Compare commits
228 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
cc7866089b | ||
|
c5fc734bb1 | ||
|
e6645c12a8 | ||
|
00c3e7c263 | ||
|
ea6b0d50f0 | ||
|
f73bf6fdeb | ||
|
039d634e62 | ||
|
0ce78b62a0 | ||
|
2bc11c6dfe | ||
|
e4f2cdede6 | ||
|
4b8719ab9c | ||
|
4bc8fbc557 | ||
|
206f91d766 | ||
|
8bece51a20 | ||
|
0ea1d81ad3 | ||
|
602f8f4b73 | ||
|
930976f67e | ||
|
e6b4c02e34 | ||
|
8f65b1390b | ||
|
c6239b2770 | ||
|
bf5db3f47b | ||
|
628872f27c | ||
|
dfea4b4779 | ||
|
afbd63646a | ||
|
39c80352b3 | ||
|
16b02fcbaa | ||
|
e197aa41fe | ||
|
2d6bba2224 | ||
|
5c6a45875c | ||
|
f5c2bd88f2 | ||
|
1c6908b6a5 | ||
|
99739064cc | ||
|
dc82ee9be6 | ||
|
7b710d4d13 | ||
|
2ecbc53983 | ||
|
c3f8b2a938 | ||
|
e7adb05c3d | ||
|
5e30c2898e | ||
|
7e83c926ae | ||
|
26f8526f70 | ||
|
b5bce230c1 | ||
|
624308bae8 | ||
|
28591f00a3 | ||
|
23f4dd5756 | ||
|
9392b93d10 | ||
|
da08621dc6 | ||
|
3ba41f78ad | ||
|
c8c1031c29 | ||
|
0b6d48bddc | ||
|
4e993f4d55 | ||
|
12206fd3ee | ||
|
3cc76d0b61 | ||
|
4a158ae6e8 | ||
|
c330e6000d | ||
|
d9e9770eb8 | ||
|
0745d90a5c | ||
|
e58be83214 | ||
|
9dbe7cfa2b | ||
|
15d93abea3 | ||
|
9ca27118c4 | ||
|
29b37b7ed0 | ||
|
d36e33e4df | ||
|
4ac07ef938 | ||
|
ee9a1ea9c7 | ||
|
df6e14c585 | ||
|
0b53b78cda | ||
|
6c396c6ec8 | ||
|
591a98bff1 | ||
|
41d072bc90 | ||
|
358e822660 | ||
|
3388a15462 | ||
|
ea5f99b0d2 | ||
|
c0387b1521 | ||
|
1eabbf5df2 | ||
|
7c336e2320 | ||
|
2044da4be9 | ||
|
a14d444960 | ||
|
5e85e5a3b9 | ||
|
99a1eeb356 | ||
|
e42625f1aa | ||
|
b26d7b08c6 | ||
|
f82de45a03 | ||
|
e8e2a9ab2c | ||
|
b2c3d2c0c3 | ||
|
d8adb4596c | ||
|
e757da19eb | ||
|
d7c772e748 | ||
|
9fbbb87fa8 | ||
|
63e7de4fad | ||
|
ce3508f8be | ||
|
2ab95463c5 | ||
|
dc91b69bf5 | ||
|
83dc99e1a8 | ||
|
335765e3ea | ||
|
d50f974c3d | ||
|
4d71238084 | ||
|
a7fa577837 | ||
|
f7e5995add | ||
|
a679ad20bb | ||
|
2ab96606aa | ||
|
0b42899347 | ||
|
053d9751c3 | ||
|
32b1c4888d | ||
|
c122589a2e | ||
|
6559154bca | ||
|
827497114d | ||
|
48fdb3138a | ||
|
cffe037269 | ||
|
d9255db8a9 | ||
|
89b249274f | ||
|
e0da70838a | ||
|
c70a93e54e | ||
|
be9da7811d | ||
|
8a4cad1195 | ||
|
e2e82dc3f3 | ||
|
caca627b18 | ||
|
7ad01f6b26 | ||
|
9448d3c111 | ||
|
b26855de90 | ||
|
725ca7bdd3 | ||
|
c904fd3932 | ||
|
f31cd0f773 | ||
|
34cc06cd9c | ||
|
5f8896eec2 | ||
|
ea342a0d0b | ||
|
1bd2968982 | ||
|
3dc15aeb68 | ||
|
668e8a6ba7 | ||
|
de2af7931f | ||
|
a64e820e80 | ||
|
eb6ba7a1a5 | ||
|
89b69a9fa1 | ||
|
dc7542de60 | ||
|
b18d872c66 | ||
|
fd6585d80c | ||
|
4b8bcac049 | ||
|
4c85fcc47e | ||
|
38566f1f60 | ||
|
89d416becd | ||
|
de7344b192 | ||
|
39ff6acf99 | ||
|
e2687865ef | ||
|
fe3159105f | ||
|
49f0bfbd71 | ||
|
24881d7cdc | ||
|
627eabd8b2 | ||
|
3242ad80c4 | ||
|
8ce6dc7607 | ||
|
0b0f78a3ed | ||
|
142b3b7be9 | ||
|
21cba5946b | ||
|
4f116fdcc4 | ||
|
6c9044b457 | ||
|
e9b85f7878 | ||
|
5e50a3a733 | ||
|
eed15cd23c | ||
|
3629796786 | ||
|
95917e22f0 | ||
|
ac33ffa34a | ||
|
65884f80f6 | ||
|
127a589b2c | ||
|
ba3b1a64e5 | ||
|
00d5e98712 | ||
|
91838194bb | ||
|
6319ca272e | ||
|
6350c95536 | ||
|
ee4049b947 | ||
|
76683371cf | ||
|
f9af6219ab | ||
|
2560f0af3d | ||
|
255bd8bab8 | ||
|
6771b831e5 | ||
|
2bca93bf12 | ||
|
c3bbd35c2c | ||
|
5d88d9ad59 | ||
|
39b25acc50 | ||
|
a58bfe79cc | ||
|
f43b7d72d4 | ||
|
be81e2a863 | ||
|
c5489daac3 | ||
|
78f2a7418b | ||
|
dd1d977fbc | ||
|
a357b49824 | ||
|
84a3b6e6fa | ||
|
0b3a8b57dd | ||
|
a39f3ed3b1 | ||
|
c07fc4341d | ||
|
05b9416cd9 | ||
|
071afbfec1 | ||
|
746bece538 | ||
|
b3b5fa9fac | ||
|
ed56816836 | ||
|
d23924347e | ||
|
15a41f1ba7 | ||
|
5c99bd759e | ||
|
968576b665 | ||
|
90243b9875 | ||
|
f86eab9a95 | ||
|
4b860732c0 | ||
|
456df124f1 | ||
|
565e02ee5c | ||
|
e4a8389cf5 | ||
|
c868ca91c2 | ||
|
eea5418734 | ||
|
70f5c45abe | ||
|
3ef5e75cba | ||
|
b8c089f3fd | ||
|
e5f70ad08c | ||
|
225e450bc9 | ||
|
e3fa804fa8 | ||
|
9390295f5b | ||
|
dfdc8025e9 | ||
|
e1f91de9ef | ||
|
203537a9ce | ||
|
0778b68ef8 | ||
|
43186b86ef | ||
|
e34e5a606b | ||
|
c32bbd9124 | ||
|
5fff688612 | ||
|
f851b0df10 | ||
|
cf9f00abf5 | ||
|
620011a19a | ||
|
54adf69db5 | ||
|
d9e0bdfb9a | ||
|
31ddefba16 | ||
|
908537ea0b | ||
|
83cfd57245 | ||
|
08f3bb0578 |
@ -1,5 +1,5 @@
|
||||
# 镜像集成
|
||||
FROM node:18
|
||||
FROM node:18-slim
|
||||
|
||||
# 设置工作区间
|
||||
WORKDIR /xiaoju-survey
|
||||
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright (C) 2023 Beijing Didi Infinity Technology and Development Co.,Ltd. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -161,7 +161,7 @@ npm run local
|
||||
|
||||
#### 1.Configure Database
|
||||
|
||||
> The project uses MongoDB: [MongoDB Guide](https://xiaojusurvey.didi.cn/docs/next/document/%E6%A6%82%E8%BF%B0/%E6%95%B0%E6%8D%AE%E5%BA%93)
|
||||
> The project uses MongoDB: [MongoDB Guide](https://xiaojusurvey.didi.cn/docs/next/document/%E6%A6%82%E8%BF%B0/%E6%95%B0%E6%8D%AE%E5%BA%93#%E5%AE%89%E8%A3%85)
|
||||
|
||||
Configure the database, check MongoDB configuration.
|
||||
|
||||
|
@ -29,7 +29,6 @@ import { SurveyHistory } from './models/surveyHistory.entity';
|
||||
import { ResponseSchema } from './models/responseSchema.entity';
|
||||
import { Counter } from './models/counter.entity';
|
||||
import { SurveyResponse } from './models/surveyResponse.entity';
|
||||
import { SurveyGroup } from './models/surveyGroup.entity';
|
||||
import { ClientEncrypt } from './models/clientEncrypt.entity';
|
||||
import { Word } from './models/word.entity';
|
||||
import { MessagePushingTask } from './models/messagePushingTask.entity';
|
||||
@ -79,7 +78,6 @@ import { Logger } from './logger';
|
||||
SurveyConf,
|
||||
SurveyHistory,
|
||||
SurveyResponse,
|
||||
SurveyGroup,
|
||||
Counter,
|
||||
ResponseSchema,
|
||||
ClientEncrypt,
|
||||
|
@ -88,17 +88,10 @@ export interface MsgContent {
|
||||
msg_9004: string;
|
||||
}
|
||||
|
||||
export interface JumpConfig {
|
||||
type: string;
|
||||
link: string;
|
||||
buttonText?: string;
|
||||
}
|
||||
|
||||
export interface SubmitConf {
|
||||
submitTitle: string;
|
||||
confirmAgain: ConfirmAgain;
|
||||
msgContent: MsgContent;
|
||||
jumpConfig?: JumpConfig;
|
||||
}
|
||||
|
||||
// 白名单类型
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { Entity, Column } from 'typeorm';
|
||||
import { BaseEntity } from './base.entity';
|
||||
|
||||
@Entity({ name: 'surveyGroup' })
|
||||
export class SurveyGroup extends BaseEntity {
|
||||
@Column()
|
||||
ownerId: string;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
}
|
@ -37,9 +37,6 @@ export class SurveyMeta extends BaseEntity {
|
||||
@Column()
|
||||
workspaceId: string;
|
||||
|
||||
@Column()
|
||||
groupId: string;
|
||||
|
||||
@Column()
|
||||
curStatus: {
|
||||
status: RECORD_STATUS;
|
||||
|
@ -275,11 +275,6 @@ describe('DataStatisticController', () => {
|
||||
again_text: '确认要提交吗?',
|
||||
},
|
||||
link: '',
|
||||
jumpConfig: {
|
||||
type: 'link',
|
||||
link: '',
|
||||
buttonText: '',
|
||||
},
|
||||
},
|
||||
logicConf: {
|
||||
showLogicConf: [],
|
||||
|
@ -71,11 +71,6 @@ export const mockSensitiveResponseSchema: ResponseSchema = {
|
||||
is_again: true,
|
||||
again_text: '确认要提交吗?',
|
||||
},
|
||||
jumpConfig: {
|
||||
type: 'link',
|
||||
link: '',
|
||||
buttonText: '',
|
||||
},
|
||||
},
|
||||
dataConf: {
|
||||
dataList: [
|
||||
@ -370,11 +365,6 @@ export const mockResponseSchema: ResponseSchema = {
|
||||
is_again: true,
|
||||
again_text: '确认要提交吗?',
|
||||
},
|
||||
jumpConfig: {
|
||||
type: 'link',
|
||||
link: '',
|
||||
buttonText: '',
|
||||
},
|
||||
},
|
||||
dataConf: {
|
||||
dataList: [
|
||||
|
@ -1,132 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { SurveyGroupController } from '../controllers/surveyGroup.controller';
|
||||
import { SurveyGroupService } from '../services/surveyGroup.service';
|
||||
import { SurveyMetaService } from '../services/surveyMeta.service';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import { Logger } from 'src/logger';
|
||||
|
||||
jest.mock('src/guards/authentication.guard');
|
||||
|
||||
describe('SurveyGroupController', () => {
|
||||
let controller: SurveyGroupController;
|
||||
let service: SurveyGroupService;
|
||||
|
||||
const mockService = {
|
||||
create: jest.fn(),
|
||||
findAll: jest.fn(),
|
||||
update: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [SurveyGroupController],
|
||||
providers: [
|
||||
{
|
||||
provide: SurveyMetaService,
|
||||
useValue: {
|
||||
countSurveyMetaByGroupId: jest.fn().mockResolvedValue(0),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: SurveyGroupService,
|
||||
useValue: mockService,
|
||||
},
|
||||
{
|
||||
provide: Logger,
|
||||
useValue: {
|
||||
error: jest.fn(),
|
||||
info: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<SurveyGroupController>(SurveyGroupController);
|
||||
service = module.get<SurveyGroupService>(SurveyGroupService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a survey group', async () => {
|
||||
const result = {
|
||||
_id: new ObjectId(),
|
||||
name: 'Test Group',
|
||||
ownerId: '123',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
}; // 确保这里返回的对象结构符合预期
|
||||
jest.spyOn(service, 'create').mockResolvedValue(result);
|
||||
|
||||
// 创建模拟的请求对象
|
||||
const req = {
|
||||
user: {
|
||||
_id: '123', // 模拟的用户ID
|
||||
},
|
||||
};
|
||||
|
||||
expect(await controller.create({ name: 'Test Group' }, req)).toEqual({
|
||||
code: 200,
|
||||
data: {
|
||||
id: result._id,
|
||||
},
|
||||
});
|
||||
expect(service.create).toHaveBeenCalledWith({
|
||||
name: 'Test Group',
|
||||
ownerId: req.user._id.toString(), // 这里用模拟的 req.user._id
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return a list of survey groups', async () => {
|
||||
const result = { total: 0, notTotal: 0, list: [], allList: [] };
|
||||
jest.spyOn(service, 'findAll').mockResolvedValue(result);
|
||||
const mockReq = { user: { _id: new ObjectId() } };
|
||||
const mockQue = { curPage: 1, pageSize: 10, name: '' };
|
||||
const userId = mockReq.user._id.toString();
|
||||
expect(await controller.findAll(mockReq, mockQue)).toEqual({
|
||||
code: 200,
|
||||
data: result,
|
||||
});
|
||||
expect(service.findAll).toHaveBeenCalledWith(userId, '', 0, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a survey group', async () => {
|
||||
const updatedFields = { name: 'xxx' };
|
||||
const updatedResult = { raw: 'xxx', generatedMaps: [] };
|
||||
const id = '1';
|
||||
jest.spyOn(service, 'update').mockResolvedValue(updatedResult);
|
||||
|
||||
expect(await controller.updateOne(id, updatedFields)).toEqual({
|
||||
code: 200,
|
||||
ret: updatedResult,
|
||||
});
|
||||
expect(service.update).toHaveBeenCalledWith(id, updatedFields);
|
||||
});
|
||||
|
||||
it('should throw error on invalid parameter', async () => {
|
||||
const id = '1';
|
||||
const invalidFields: any = {};
|
||||
await expect(controller.updateOne(id, invalidFields)).rejects.toThrow(
|
||||
HttpException,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should remove a survey group', async () => {
|
||||
const id = '1';
|
||||
jest.spyOn(service, 'remove').mockResolvedValue(undefined);
|
||||
|
||||
expect(await controller.remove(id)).toEqual({ code: 200 });
|
||||
expect(service.remove).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,102 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { SurveyGroupService } from '../services/surveyGroup.service';
|
||||
import { SurveyGroup } from 'src/models/surveyGroup.entity';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
describe('SurveyGroupService', () => {
|
||||
let service: SurveyGroupService;
|
||||
|
||||
const mockSurveyGroupRepository = {
|
||||
create: jest.fn(),
|
||||
save: jest.fn(),
|
||||
findAndCount: jest.fn(),
|
||||
find: jest.fn(),
|
||||
update: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
};
|
||||
|
||||
const mockSurveyMetaRepository = {
|
||||
updateMany: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
SurveyGroupService,
|
||||
{
|
||||
provide: getRepositoryToken(SurveyGroup),
|
||||
useValue: mockSurveyGroupRepository,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(SurveyMeta),
|
||||
useValue: mockSurveyMetaRepository,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<SurveyGroupService>(SurveyGroupService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('create', () => {
|
||||
it('should create a survey group', async () => {
|
||||
const createParams = { name: 'Test Group', ownerId: '123' };
|
||||
const mockSavedGroup = { ...createParams, id: '1' };
|
||||
|
||||
mockSurveyGroupRepository.create.mockReturnValue(mockSavedGroup);
|
||||
mockSurveyGroupRepository.save.mockResolvedValue(mockSavedGroup);
|
||||
|
||||
expect(await service.create(createParams)).toEqual(mockSavedGroup);
|
||||
expect(mockSurveyGroupRepository.create).toHaveBeenCalledWith(
|
||||
createParams,
|
||||
);
|
||||
expect(mockSurveyGroupRepository.save).toHaveBeenCalledWith(
|
||||
mockSavedGroup,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findAll', () => {
|
||||
it('should return survey groups', async () => {
|
||||
const list = [{ id: '1', name: 'Test Group', ownerId: '123' }];
|
||||
const total = list.length;
|
||||
|
||||
mockSurveyGroupRepository.findAndCount.mockResolvedValue([list, total]);
|
||||
mockSurveyGroupRepository.find.mockResolvedValue(list);
|
||||
|
||||
const result = await service.findAll('123', '', 0, 10);
|
||||
expect(result).toEqual({ total, list, allList: list });
|
||||
expect(mockSurveyGroupRepository.findAndCount).toHaveBeenCalled();
|
||||
expect(mockSurveyGroupRepository.find).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
it('should update a survey group', async () => {
|
||||
const id = '1';
|
||||
const updatedFields = { name: 'Updated Test Group' };
|
||||
|
||||
await service.update(id, updatedFields);
|
||||
expect(mockSurveyGroupRepository.update).toHaveBeenCalledWith(id, {
|
||||
...updatedFields,
|
||||
updatedAt: expect.any(Date),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should remove a survey group', async () => {
|
||||
const id = '1';
|
||||
await service.remove(id);
|
||||
expect(mockSurveyMetaRepository.updateMany).toHaveBeenCalledWith(
|
||||
{ groupId: id },
|
||||
{ $set: { groupId: null } },
|
||||
);
|
||||
expect(mockSurveyGroupRepository.delete).toHaveBeenCalledWith(id);
|
||||
});
|
||||
});
|
||||
});
|
@ -77,7 +77,6 @@ describe('SurveyMetaController', () => {
|
||||
survey: {
|
||||
title: reqBody.title,
|
||||
remark: reqBody.remark,
|
||||
groupId: null,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -86,7 +86,6 @@ describe('SurveyMetaService', () => {
|
||||
createMethod: params.createMethod,
|
||||
createFrom: params.createFrom,
|
||||
workspaceId: params.workspaceId,
|
||||
groupId: null,
|
||||
});
|
||||
expect(surveyRepository.save).toHaveBeenCalledWith(newSurvey);
|
||||
expect(result).toEqual(newSurvey);
|
||||
|
@ -78,7 +78,7 @@ export class SurveyController {
|
||||
throw new HttpException('参数错误', EXCEPTION_CODE.PARAMETER_ERROR);
|
||||
}
|
||||
|
||||
const { title, remark, createMethod, createFrom, groupId } = value;
|
||||
const { title, remark, createMethod, createFrom } = value;
|
||||
|
||||
let surveyType = '',
|
||||
workspaceId = null;
|
||||
@ -100,7 +100,6 @@ export class SurveyController {
|
||||
createMethod,
|
||||
createFrom,
|
||||
workspaceId,
|
||||
groupId,
|
||||
});
|
||||
await this.surveyConfService.createSurveyConf({
|
||||
surveyId: surveyMeta._id.toString(),
|
||||
|
@ -1,145 +0,0 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
UseGuards,
|
||||
Request,
|
||||
HttpCode,
|
||||
Query,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import moment from 'moment';
|
||||
import { Authentication } from 'src/guards/authentication.guard';
|
||||
import { SurveyMetaService } from 'src/modules/survey/services/surveyMeta.service';
|
||||
import { SurveyGroupService } from '../services/surveyGroup.service';
|
||||
|
||||
import { Logger } from 'src/logger';
|
||||
import { HttpException } from 'src/exceptions/httpException';
|
||||
import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
|
||||
|
||||
import { CreateSurveyGroupDto } from '../dto/createSurveyGroup.dto';
|
||||
import { UpdateSurveyGroupDto } from '../dto/updateSurveyGroup.dto';
|
||||
import { GetGroupListDto } from '../dto/getGroupList.dto';
|
||||
|
||||
@ApiTags('surveyGroup')
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(Authentication)
|
||||
@Controller('api/surveyGroup')
|
||||
export class SurveyGroupController {
|
||||
constructor(
|
||||
private readonly surveyMetaService: SurveyMetaService,
|
||||
private readonly SurveyGroupService: SurveyGroupService,
|
||||
private readonly logger: Logger,
|
||||
) {}
|
||||
@Post()
|
||||
@HttpCode(200)
|
||||
async create(
|
||||
@Body()
|
||||
reqBody: CreateSurveyGroupDto,
|
||||
@Request()
|
||||
req,
|
||||
) {
|
||||
const { error, value } = CreateSurveyGroupDto.validate(reqBody);
|
||||
if (error) {
|
||||
this.logger.error(`createSurveyGroup_parameter error: ${error.message}`);
|
||||
throw new HttpException('参数错误', EXCEPTION_CODE.PARAMETER_ERROR);
|
||||
}
|
||||
const userId = req.user._id.toString();
|
||||
const ret = await this.SurveyGroupService.create({
|
||||
name: value.name,
|
||||
ownerId: userId,
|
||||
});
|
||||
return {
|
||||
code: 200,
|
||||
data: {
|
||||
id: ret._id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@Get()
|
||||
@HttpCode(200)
|
||||
async findAll(@Request() req, @Query() queryInfo: GetGroupListDto) {
|
||||
const { value, error } = GetGroupListDto.validate(queryInfo);
|
||||
if (error) {
|
||||
this.logger.error(`GetGroupListDto validate failed: ${error.message}`);
|
||||
throw new HttpException(
|
||||
`参数错误: 请联系管理员`,
|
||||
EXCEPTION_CODE.PARAMETER_ERROR,
|
||||
);
|
||||
}
|
||||
const userId = req.user._id.toString();
|
||||
const curPage = Number(value.curPage);
|
||||
const pageSize = Number(value.pageSize);
|
||||
const skip = (curPage - 1) * pageSize;
|
||||
const { total, list, allList } = await this.SurveyGroupService.findAll(
|
||||
userId,
|
||||
value.name,
|
||||
skip,
|
||||
pageSize,
|
||||
);
|
||||
const groupIdList = list.map((item) => item._id.toString());
|
||||
const surveyTotalList = await Promise.all(
|
||||
groupIdList.map((item) => {
|
||||
return this.surveyMetaService.countSurveyMetaByGroupId({
|
||||
groupId: item,
|
||||
});
|
||||
}),
|
||||
);
|
||||
const surveyTotalMap = groupIdList.reduce((pre, cur, index) => {
|
||||
const total = surveyTotalList[index];
|
||||
pre[cur] = total;
|
||||
return pre;
|
||||
}, {});
|
||||
const notTotal = await this.surveyMetaService.countSurveyMetaByGroupId({
|
||||
groupId: null,
|
||||
});
|
||||
return {
|
||||
code: 200,
|
||||
data: {
|
||||
total,
|
||||
list: list.map((item) => {
|
||||
const id = item._id.toString();
|
||||
return {
|
||||
...item,
|
||||
createdAt: moment(item.createdAt).format('YYYY-MM-DD HH:mm:ss'),
|
||||
surveyTotal: surveyTotalMap[id] || 0,
|
||||
};
|
||||
}),
|
||||
allList,
|
||||
notTotal,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@Post(':id')
|
||||
@HttpCode(200)
|
||||
async updateOne(
|
||||
@Param('id') id: string,
|
||||
@Body()
|
||||
reqBody: UpdateSurveyGroupDto,
|
||||
) {
|
||||
const { error, value } = UpdateSurveyGroupDto.validate(reqBody);
|
||||
if (error) {
|
||||
this.logger.error(`createSurveyGroup_parameter error: ${error.message}`);
|
||||
throw new HttpException('参数错误', EXCEPTION_CODE.PARAMETER_ERROR);
|
||||
}
|
||||
const ret = await this.SurveyGroupService.update(id, value);
|
||||
return {
|
||||
code: 200,
|
||||
ret,
|
||||
};
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@HttpCode(200)
|
||||
async remove(@Param('id') id: string) {
|
||||
await this.SurveyGroupService.remove(id);
|
||||
return {
|
||||
code: 200,
|
||||
};
|
||||
}
|
||||
}
|
@ -48,7 +48,6 @@ export class SurveyMetaController {
|
||||
title: Joi.string().required(),
|
||||
remark: Joi.string().allow(null, '').default(''),
|
||||
surveyId: Joi.string().required(),
|
||||
groupId: Joi.string().allow(null, ''),
|
||||
}).validate(reqBody, { allowUnknown: true });
|
||||
|
||||
if (error) {
|
||||
@ -58,8 +57,6 @@ export class SurveyMetaController {
|
||||
const survey = req.surveyMeta;
|
||||
survey.title = value.title;
|
||||
survey.remark = value.remark;
|
||||
survey.groupId =
|
||||
value.groupId && value.groupId !== '' ? value.groupId : null;
|
||||
|
||||
await this.surveyMetaService.editSurveyMeta({
|
||||
survey,
|
||||
@ -89,7 +86,7 @@ export class SurveyMetaController {
|
||||
this.logger.error(error.message);
|
||||
throw new HttpException('参数有误', EXCEPTION_CODE.PARAMETER_ERROR);
|
||||
}
|
||||
const { curPage, pageSize, workspaceId, groupId } = value;
|
||||
const { curPage, pageSize, workspaceId } = value;
|
||||
let filter = {},
|
||||
order = {};
|
||||
if (value.filter) {
|
||||
@ -123,7 +120,6 @@ export class SurveyMetaController {
|
||||
filter,
|
||||
order,
|
||||
workspaceId,
|
||||
groupId,
|
||||
surveyIdList,
|
||||
});
|
||||
return {
|
||||
|
@ -20,9 +20,6 @@ export class CreateSurveyDto {
|
||||
@ApiProperty({ description: '问卷创建在哪个空间下', required: false })
|
||||
workspaceId?: string;
|
||||
|
||||
@ApiProperty({ description: '问卷创建在哪个分组下', required: false })
|
||||
groupId?: string;
|
||||
|
||||
static validate(data) {
|
||||
return Joi.object({
|
||||
title: Joi.string().required(),
|
||||
@ -39,7 +36,6 @@ export class CreateSurveyDto {
|
||||
otherwise: Joi.allow(null),
|
||||
}),
|
||||
workspaceId: Joi.string().allow(null, ''),
|
||||
groupId: Joi.string().allow(null, ''),
|
||||
}).validate(data);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import Joi from 'joi';
|
||||
|
||||
export class CreateSurveyGroupDto {
|
||||
@ApiProperty({ description: '分组名称', required: true })
|
||||
name: string;
|
||||
|
||||
static validate(data) {
|
||||
return Joi.object({
|
||||
name: Joi.string().required(),
|
||||
}).validate(data);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import Joi from 'joi';
|
||||
|
||||
export class GetGroupListDto {
|
||||
@ApiProperty({ description: '当前页码', required: true })
|
||||
curPage: number;
|
||||
|
||||
@ApiProperty({ description: '分页', required: false })
|
||||
pageSize: number;
|
||||
|
||||
@ApiProperty({ description: '空间名称', required: false })
|
||||
name?: string;
|
||||
|
||||
static validate(data: Partial<GetGroupListDto>): Joi.ValidationResult {
|
||||
return Joi.object({
|
||||
curPage: Joi.number().required(),
|
||||
pageSize: Joi.number().allow(null).default(10),
|
||||
name: Joi.string().allow(null, '').optional(),
|
||||
}).validate(data);
|
||||
}
|
||||
}
|
@ -17,9 +17,6 @@ export class GetSurveyListDto {
|
||||
@ApiProperty({ description: '空间id', required: false })
|
||||
workspaceId?: string;
|
||||
|
||||
@ApiProperty({ description: '分组id', required: false })
|
||||
groupId?: string;
|
||||
|
||||
static validate(data) {
|
||||
return Joi.object({
|
||||
curPage: Joi.number().required(),
|
||||
@ -27,7 +24,6 @@ export class GetSurveyListDto {
|
||||
filter: Joi.string().allow(null),
|
||||
order: Joi.string().allow(null),
|
||||
workspaceId: Joi.string().allow(null, ''),
|
||||
groupId: Joi.string().allow(null, ''),
|
||||
}).validate(data);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import Joi from 'joi';
|
||||
|
||||
export class UpdateSurveyGroupDto {
|
||||
@ApiProperty({ description: '分组名称', required: true })
|
||||
name: string;
|
||||
|
||||
static validate(data) {
|
||||
return Joi.object({
|
||||
name: Joi.string().required(),
|
||||
}).validate(data);
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { MongoRepository } from 'typeorm';
|
||||
|
||||
import { SurveyGroup } from 'src/models/surveyGroup.entity';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
|
||||
@Injectable()
|
||||
export class SurveyGroupService {
|
||||
constructor(
|
||||
@InjectRepository(SurveyGroup)
|
||||
private readonly SurveyGroup: MongoRepository<SurveyGroup>,
|
||||
@InjectRepository(SurveyMeta)
|
||||
private surveyMetaRepository: MongoRepository<SurveyMeta>,
|
||||
) {}
|
||||
create(params: { name: string; ownerId: string }) {
|
||||
const newGroup = this.SurveyGroup.create({
|
||||
...params,
|
||||
});
|
||||
return this.SurveyGroup.save(newGroup);
|
||||
}
|
||||
|
||||
async findAll(userId: string, name: string, skip: number, pageSize: number) {
|
||||
const [list, total] = await this.SurveyGroup.findAndCount({
|
||||
skip: skip,
|
||||
take: pageSize,
|
||||
where: name
|
||||
? { name: { $regex: name, $options: 'i' }, ownerId: userId }
|
||||
: { ownerId: userId },
|
||||
order: {
|
||||
createdAt: -1,
|
||||
},
|
||||
});
|
||||
const allList = await this.SurveyGroup.find({
|
||||
where: { ownerId: userId },
|
||||
select: ['_id', 'name'],
|
||||
});
|
||||
return {
|
||||
total,
|
||||
list,
|
||||
allList,
|
||||
};
|
||||
}
|
||||
|
||||
update(id: string, updatedFields: Partial<SurveyGroup>) {
|
||||
updatedFields.updatedAt = new Date();
|
||||
return this.SurveyGroup.update(id, updatedFields);
|
||||
}
|
||||
|
||||
async remove(id: string) {
|
||||
const query = { groupId: id };
|
||||
const update = { $set: { groupId: null } };
|
||||
await this.surveyMetaRepository.updateMany(query, update);
|
||||
return this.SurveyGroup.delete(id);
|
||||
}
|
||||
}
|
@ -47,7 +47,6 @@ export class SurveyMetaService {
|
||||
createMethod: string;
|
||||
createFrom: string;
|
||||
workspaceId?: string;
|
||||
groupId?: string;
|
||||
}) {
|
||||
const {
|
||||
title,
|
||||
@ -58,7 +57,6 @@ export class SurveyMetaService {
|
||||
createFrom,
|
||||
userId,
|
||||
workspaceId,
|
||||
groupId,
|
||||
} = params;
|
||||
const surveyPath = await this.getNewSurveyPath();
|
||||
const newSurvey = this.surveyRepository.create({
|
||||
@ -73,7 +71,6 @@ export class SurveyMetaService {
|
||||
createMethod,
|
||||
createFrom,
|
||||
workspaceId,
|
||||
groupId: groupId && groupId !== '' ? groupId : null,
|
||||
});
|
||||
|
||||
return await this.surveyRepository.save(newSurvey);
|
||||
@ -146,18 +143,10 @@ export class SurveyMetaService {
|
||||
filter: Record<string, any>;
|
||||
order: Record<string, any>;
|
||||
workspaceId?: string;
|
||||
groupId?: string;
|
||||
surveyIdList?: Array<string>;
|
||||
}): Promise<{ data: any[]; count: number }> {
|
||||
const {
|
||||
pageNum,
|
||||
pageSize,
|
||||
userId,
|
||||
username,
|
||||
workspaceId,
|
||||
groupId,
|
||||
surveyIdList,
|
||||
} = condition;
|
||||
const { pageNum, pageSize, userId, username, workspaceId, surveyIdList } =
|
||||
condition;
|
||||
const skip = (pageNum - 1) * pageSize;
|
||||
try {
|
||||
const query: Record<string, any> = Object.assign(
|
||||
@ -171,15 +160,6 @@ export class SurveyMetaService {
|
||||
if (condition.filter['curStatus.status']) {
|
||||
query['subStatus.status'] = RECORD_SUB_STATUS.DEFAULT;
|
||||
}
|
||||
if (groupId && groupId !== 'all') {
|
||||
query.groupId =
|
||||
groupId === 'nogrouped'
|
||||
? {
|
||||
$exists: true,
|
||||
$eq: null,
|
||||
}
|
||||
: groupId;
|
||||
}
|
||||
if (workspaceId) {
|
||||
query.workspaceId = workspaceId;
|
||||
} else {
|
||||
@ -248,21 +228,4 @@ export class SurveyMetaService {
|
||||
});
|
||||
return total;
|
||||
}
|
||||
async countSurveyMetaByGroupId({ groupId }) {
|
||||
const total = await this.surveyRepository.count({
|
||||
groupId,
|
||||
$or: [
|
||||
{ workspaceId: { $exists: false } },
|
||||
{ workspaceId: null },
|
||||
{ workspaceId: '' },
|
||||
],
|
||||
isDeleted: {
|
||||
$ne: true,
|
||||
},
|
||||
'curStatus.status': {
|
||||
$ne: RECORD_STATUS.REMOVED,
|
||||
},
|
||||
});
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,11 @@ import { SurveyUIController } from './controllers/surveyUI.controller';
|
||||
import { CollaboratorController } from './controllers/collaborator.controller';
|
||||
import { DownloadTaskController } from './controllers/downloadTask.controller';
|
||||
import { SessionController } from './controllers/session.controller';
|
||||
import { SurveyGroupController } from './controllers/surveyGroup.controller';
|
||||
|
||||
import { SurveyConf } from 'src/models/surveyConf.entity';
|
||||
import { SurveyHistory } from 'src/models/surveyHistory.entity';
|
||||
import { SurveyMeta } from 'src/models/surveyMeta.entity';
|
||||
import { SurveyResponse } from 'src/models/surveyResponse.entity';
|
||||
import { SurveyGroup } from 'src/models/surveyGroup.entity';
|
||||
import { Word } from 'src/models/word.entity';
|
||||
import { Collaborator } from 'src/models/collaborator.entity';
|
||||
import { DownloadTask } from 'src/models/downloadTask.entity';
|
||||
@ -40,7 +38,6 @@ import { CounterService } from '../surveyResponse/services/counter.service';
|
||||
import { FileService } from '../file/services/file.service';
|
||||
import { DownloadTaskService } from './services/downloadTask.service';
|
||||
import { SessionService } from './services/session.service';
|
||||
import { SurveyGroupService } from './services/surveyGroup.service';
|
||||
import { Session } from 'src/models/session.entity';
|
||||
|
||||
@Module({
|
||||
@ -55,7 +52,6 @@ import { Session } from 'src/models/session.entity';
|
||||
Counter,
|
||||
DownloadTask,
|
||||
Session,
|
||||
SurveyGroup,
|
||||
]),
|
||||
ConfigModule,
|
||||
SurveyResponseModule,
|
||||
@ -72,7 +68,6 @@ import { Session } from 'src/models/session.entity';
|
||||
CollaboratorController,
|
||||
DownloadTaskController,
|
||||
SessionController,
|
||||
SurveyGroupController,
|
||||
],
|
||||
providers: [
|
||||
DataStatisticService,
|
||||
@ -87,7 +82,6 @@ import { Session } from 'src/models/session.entity';
|
||||
DownloadTaskService,
|
||||
FileService,
|
||||
SessionService,
|
||||
SurveyGroupService,
|
||||
],
|
||||
})
|
||||
export class SurveyModule {}
|
||||
|
@ -39,8 +39,8 @@
|
||||
"showSpliter": true,
|
||||
"placeholder": "",
|
||||
"isRequired": true,
|
||||
"min": "",
|
||||
"max": "",
|
||||
"starMin": "",
|
||||
"starMax": "",
|
||||
"type": "radio-star",
|
||||
"title": "标题2"
|
||||
}
|
||||
|
@ -75,11 +75,6 @@ export const mockResponseSchema: ResponseSchema = {
|
||||
is_again: true,
|
||||
again_text: '确认要提交吗?',
|
||||
},
|
||||
jumpConfig: {
|
||||
type: 'link',
|
||||
link: '',
|
||||
buttonText: '',
|
||||
},
|
||||
},
|
||||
dataConf: {
|
||||
dataList: [
|
||||
|
@ -78,21 +78,3 @@ export const getCollaboratorPermissions = (surveyId: string) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const createGroup = ({ name }: any) => {
|
||||
return axios.post('surveyGroup', { name })
|
||||
}
|
||||
|
||||
export const updateGroup = ({ _id, name }: any) => {
|
||||
return axios.post(`/surveyGroup/${_id}`, { name })
|
||||
}
|
||||
|
||||
export const getGroupList = (params: any) => {
|
||||
return axios.get('/surveyGroup', {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const deleteGroup = (id: string) => {
|
||||
return axios.delete(`/surveyGroup/${id}`)
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
import axios from './base'
|
||||
|
||||
export const getSurveyList = ({ curPage, filter, order, workspaceId, groupId }) => {
|
||||
export const getSurveyList = ({ curPage, filter, order, workspaceId }) => {
|
||||
return axios.get('/survey/getList', {
|
||||
params: {
|
||||
pageSize: 10,
|
||||
curPage,
|
||||
filter,
|
||||
order,
|
||||
workspaceId,
|
||||
groupId
|
||||
workspaceId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
<el-select-v2
|
||||
v-model="value"
|
||||
filterable
|
||||
class="search-name"
|
||||
remote
|
||||
:remote-method="remoteMethod"
|
||||
clearable
|
||||
@ -59,8 +58,7 @@ const value = ref('')
|
||||
const selectOptions = ref<ListItem[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
const remoteMethod = async (q: string) => {
|
||||
const query = q.trim()
|
||||
const remoteMethod = async (query: string) => {
|
||||
if (query !== '') {
|
||||
loading.value = true
|
||||
const res: any = await getUserList(query)
|
||||
|
@ -115,9 +115,6 @@ const rules = {
|
||||
{
|
||||
trigger: 'change',
|
||||
validator: (rule: any, value: IMember[], callback: Function) => {
|
||||
if (value.length === 0) {
|
||||
callback('请添加协作者')
|
||||
}
|
||||
if (value.filter((item: IMember) => !item.role.length).length) {
|
||||
callback('请设置协作者对应权限')
|
||||
}
|
||||
@ -189,18 +186,8 @@ const handleMembersChange = (val: IMember[]) => {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss" rel="lang/scss" scoped>
|
||||
.base-form-root {
|
||||
padding: 20px;
|
||||
|
||||
:deep(.list-wrapper .el-select) {
|
||||
.el-select__placeholder {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-form-item.is-error .search-name .el-select__wrapper) {
|
||||
box-shadow: 0 0 0 1px var(--el-border-color) inset;
|
||||
}
|
||||
</style>
|
||||
|
@ -125,11 +125,6 @@ const handleCheckAll = (val: CheckboxValueType) => {
|
||||
:deep(.el-select__wrapper) {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
&:hover,
|
||||
&:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
:deep(.ishovering) {
|
||||
border: none;
|
||||
@ -139,11 +134,11 @@ const handleCheckAll = (val: CheckboxValueType) => {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
// .operation-select {
|
||||
// :deep(.el-select__placeholder) {
|
||||
// text-align: right;
|
||||
// }
|
||||
// }
|
||||
.operation-select {
|
||||
:deep(.el-select__placeholder) {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
|
@ -34,25 +34,6 @@ export const spaceListConfig = {
|
||||
}
|
||||
}
|
||||
|
||||
export const groupListConfig = {
|
||||
name: {
|
||||
title: '分组名称',
|
||||
key: 'name',
|
||||
width: 200
|
||||
},
|
||||
surveyTotal: {
|
||||
title: '问卷数',
|
||||
key: 'surveyTotal',
|
||||
width: 150,
|
||||
tip: true
|
||||
},
|
||||
createdAt: {
|
||||
title: '创建时间',
|
||||
key: 'createdAt',
|
||||
minWidth: 200
|
||||
}
|
||||
}
|
||||
|
||||
export const fieldConfig = {
|
||||
type: {
|
||||
title: '类型',
|
||||
@ -111,16 +92,6 @@ export const noSpaceSearchDataConfig = {
|
||||
desc: '可以更换条件查询试试',
|
||||
img: '/imgs/icons/list-empty.webp'
|
||||
}
|
||||
export const noGroupDataConfig = {
|
||||
title: '您还没有创建问卷分组',
|
||||
desc: '赶快点击右上角立即创建问卷分组吧!',
|
||||
img: '/imgs/icons/list-empty.webp'
|
||||
}
|
||||
export const noGroupSearchDataConfig = {
|
||||
title: '没有满足该查询条件的问卷分组哦',
|
||||
desc: '可以更换条件查询试试',
|
||||
img: '/imgs/icons/list-empty.webp'
|
||||
}
|
||||
export const noSearchDataConfig = {
|
||||
title: '没有满足该查询条件的问卷',
|
||||
desc: '可以更换条件查询试试',
|
||||
|
@ -26,19 +26,6 @@
|
||||
/>
|
||||
<p class="form-item-tip">备注仅自己可见</p>
|
||||
</el-form-item>
|
||||
<el-form-item prop="groupId" label="问卷分组" v-if="menuType === MenuType.PersonalGroup">
|
||||
<el-select
|
||||
v-model="form.groupId"
|
||||
placeholder="未分组"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in groupAllList"
|
||||
:key="item?._id"
|
||||
:label="item?.name"
|
||||
:value="item?._id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="create-btn" type="primary" @click="submit" :loading="!canSubmit">
|
||||
开始创建
|
||||
@ -50,13 +37,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, toRefs } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import 'element-plus/theme-chalk/src/message.scss'
|
||||
import { createSurvey } from '@/management/api/survey'
|
||||
import { SURVEY_TYPE_LIST } from '../types'
|
||||
import { MenuType, GroupState } from '@/management/utils/workSpace'
|
||||
import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
|
||||
interface Props {
|
||||
@ -68,8 +53,6 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
})
|
||||
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const { groupAllList, menuType, groupId, workSpaceId } = storeToRefs(workSpaceStore)
|
||||
|
||||
const ruleForm = ref<any>(null)
|
||||
|
||||
const state = reactive({
|
||||
@ -79,8 +62,7 @@ const state = reactive({
|
||||
canSubmit: true,
|
||||
form: {
|
||||
title: '问卷调研',
|
||||
remark: '问卷调研',
|
||||
groupId: groupId.value == GroupState.All || groupId.value == GroupState.Not ? '' : groupId.value
|
||||
remark: '问卷调研'
|
||||
}
|
||||
})
|
||||
const { rules, canSubmit, form } = toRefs(state)
|
||||
@ -110,8 +92,8 @@ const submit = () => {
|
||||
surveyType: selectType,
|
||||
...state.form
|
||||
}
|
||||
if (workSpaceId.value) {
|
||||
payload.workspaceId = workSpaceId.value
|
||||
if (workSpaceStore.workSpaceId) {
|
||||
payload.workspaceId = workSpaceStore.workSpaceId
|
||||
}
|
||||
const res: any = await createSurvey(payload)
|
||||
if (res?.code === 200 && res?.data?.id) {
|
||||
|
@ -14,7 +14,6 @@
|
||||
v-for="(content, contentIndex) in item.content"
|
||||
:key="`${item.key}${contentIndex}`"
|
||||
:form-config="content"
|
||||
v-show="isShowFormItem(content)"
|
||||
>
|
||||
<Component
|
||||
:is="components[content.type]"
|
||||
@ -83,14 +82,6 @@ const formFieldData = ref<Array<any>>([])
|
||||
const init = ref<boolean>(true)
|
||||
const components = shallowRef<any>(props.customComponents || {})
|
||||
|
||||
const isShowFormItem = (content: any) => {
|
||||
if (_isFunction(content.toggleShowFn)) {
|
||||
return content.toggleShowFn(props.moduleConfig)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
const handleFormChange = (data: any, formConfig: any) => {
|
||||
// 处理用户操作的设置器的值
|
||||
if (_isFunction(formConfig?.valueSetter)) {
|
||||
|
@ -11,7 +11,6 @@
|
||||
:list="item.questionList"
|
||||
:group="{ name: DND_GROUP, pull: 'clone', put: false }"
|
||||
:clone="createNewQuestion"
|
||||
@end="onDragEnd"
|
||||
item-key="path"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
@ -54,7 +53,7 @@ import { ref } from 'vue'
|
||||
|
||||
const editStore = useEditStore()
|
||||
const { newQuestionIndex } = storeToRefs(editStore)
|
||||
const { addQuestion, hasSetCurrentEditOne, createNewQuestion } = editStore
|
||||
const { addQuestion, setCurrentEditOne, createNewQuestion } = editStore
|
||||
|
||||
const activeNames = ref([0, 1])
|
||||
const previewImg = ref('')
|
||||
@ -68,11 +67,7 @@ questionLoader.init({
|
||||
const onQuestionType = ({ type }) => {
|
||||
const newQuestion = createNewQuestion({ type })
|
||||
addQuestion({ question: newQuestion, index: newQuestionIndex.value })
|
||||
hasSetCurrentEditOne(newQuestionIndex.value)
|
||||
}
|
||||
|
||||
const onDragEnd = (event) => {
|
||||
hasSetCurrentEditOne(event.newIndex)
|
||||
setCurrentEditOne(newQuestionIndex.value)
|
||||
}
|
||||
|
||||
const showPreview = ({ snapshot }, id) => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
<SetterField
|
||||
class="question-config-form"
|
||||
label-position="left"
|
||||
label-position="top"
|
||||
:form-config-list="formFields"
|
||||
:module-config="moduleConfig"
|
||||
@form-change="handleFormChange"
|
||||
@ -71,25 +71,4 @@ const handleFormChange = ({ key, value }: any) => {
|
||||
.question-config-form {
|
||||
padding: 30px 20px 50px 20px;
|
||||
}
|
||||
|
||||
:deep(.group-wrap) {
|
||||
margin-bottom: 0;
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.group-title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.el-radio {
|
||||
height: initial;
|
||||
line-height: initial;
|
||||
margin-bottom: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -5,9 +5,7 @@
|
||||
<img src="/imgs/icons/success.webp" class="success-img" />
|
||||
<div class="title-msg" v-safe-html="successText"></div>
|
||||
</div>
|
||||
<div v-if="jumpConfig.buttonText && jumpConfig.type === 'button'" class="jump-btn">
|
||||
{{ jumpConfig.buttonText }}
|
||||
</div>
|
||||
<div class="bottom-btn"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -19,7 +17,6 @@ interface Props {
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
const successText = computed(() => props.moduleConfig?.msgContent?.msg_200 || '')
|
||||
const jumpConfig = computed(() => props.moduleConfig?.jumpConfig || {})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/*成功页面跳转全屏展示浮层*/
|
||||
@ -53,18 +50,7 @@ const jumpConfig = computed(() => props.moduleConfig?.jumpConfig || {})
|
||||
font-size: 0.36rem;
|
||||
}
|
||||
}
|
||||
.jump-btn {
|
||||
background: var(--primary-color);
|
||||
width: 90%;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.25rem 0;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.25rem;
|
||||
font-weight: 500;
|
||||
margin: 0 auto;
|
||||
border: none;
|
||||
.bottom-btn {
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
|
@ -16,9 +16,7 @@
|
||||
<script setup lang="ts">
|
||||
import { watch, ref } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useEditStore } from '@/management/stores/edit'
|
||||
const editStore = useEditStore()
|
||||
const { setCurrentEditOne } = editStore
|
||||
|
||||
const routes = [
|
||||
{
|
||||
text: '内容设置',
|
||||
@ -40,7 +38,6 @@ watch(
|
||||
activeRouter,
|
||||
(val: any) => {
|
||||
// 避免编辑页刷新丢失query
|
||||
setCurrentEditOne(null)
|
||||
const query = route.query
|
||||
router.push({ name: val, query })
|
||||
},
|
||||
|
@ -103,7 +103,7 @@ export default {
|
||||
type: 'WhiteList',
|
||||
custom: true, // 自定义导入高级组件
|
||||
relyFunc: (data) => {
|
||||
return data.whitelistType == 'CUSTOM'
|
||||
return data.whitelistType === 'CUSTOM'
|
||||
}
|
||||
},
|
||||
team_list: {
|
||||
@ -112,7 +112,7 @@ export default {
|
||||
type: 'TeamMemberList',
|
||||
custom: true, // 自定义导入高级组件
|
||||
relyFunc: (data) => {
|
||||
return data.whitelistType == 'MEMBER'
|
||||
return data.whitelistType === 'MEMBER'
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
export default {
|
||||
Success: [
|
||||
{
|
||||
title: '提示文案',
|
||||
label: '提示文案',
|
||||
type: 'RichText',
|
||||
key: 'msgContent.msg_200',
|
||||
placeholder: '提交成功',
|
||||
@ -9,46 +9,6 @@ export default {
|
||||
labelStyle: {
|
||||
'font-weight': 'bold'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '交卷跳转',
|
||||
type: 'Customed',
|
||||
key: 'jumpConfig',
|
||||
content: [
|
||||
{
|
||||
key: 'jumpConfig.type',
|
||||
type: 'RadioGroup',
|
||||
value: 'link',
|
||||
options: [
|
||||
{
|
||||
label: '跳转网页',
|
||||
value: 'link'
|
||||
},
|
||||
{
|
||||
label: '跳转按钮',
|
||||
value: 'button'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'jumpConfig.buttonText',
|
||||
label: '按钮文案',
|
||||
type: 'InputSetter',
|
||||
placeholder: '请输入按钮文案',
|
||||
value: '',
|
||||
toggleShowFn: (data) => {
|
||||
return data?.jumpConfig?.type === 'button'
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'jumpConfig.link',
|
||||
label: '跳转链接',
|
||||
type: 'InputSetter',
|
||||
placeholder: '请输入网址',
|
||||
value: '',
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
OverTime: [
|
||||
|
@ -98,8 +98,6 @@
|
||||
:type="modifyType"
|
||||
:visible="showModify"
|
||||
:question-info="questionInfo"
|
||||
:group-all-list="groupAllList"
|
||||
:menu-type="menuType"
|
||||
@on-close-codify="onCloseModify"
|
||||
/>
|
||||
<CooperModify :modifyId="cooperId" :visible="cooperModify" @on-close-codify="onCooperClose" />
|
||||
@ -144,7 +142,7 @@ import {
|
||||
|
||||
const surveyListStore = useSurveyListStore()
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const { workSpaceId, groupAllList, menuType } = storeToRefs(workSpaceStore)
|
||||
const { workSpaceId } = storeToRefs(workSpaceStore)
|
||||
const router = useRouter()
|
||||
const props = defineProps({
|
||||
loading: {
|
||||
@ -365,6 +363,7 @@ const onDelete = async (row) => {
|
||||
type: 'warning'
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('取消删除')
|
||||
return
|
||||
}
|
||||
|
||||
@ -372,8 +371,6 @@ const onDelete = async (row) => {
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
ElMessage.success('删除成功')
|
||||
onRefresh()
|
||||
workSpaceStore.getGroupList()
|
||||
workSpaceStore.getSpaceList()
|
||||
} else {
|
||||
ElMessage.error(res.errmsg || '删除失败')
|
||||
}
|
||||
@ -412,8 +409,6 @@ const onCloseModify = (type) => {
|
||||
questionInfo.value = {}
|
||||
if (type === 'update') {
|
||||
onRefresh()
|
||||
workSpaceStore.getGroupList()
|
||||
workSpaceStore.getSpaceList()
|
||||
}
|
||||
}
|
||||
const onRowClick = (row) => {
|
||||
|
@ -1,245 +0,0 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<TextSearch placeholder="请输入分组名称" :value="searchVal" @search="onSearchText" />
|
||||
</div>
|
||||
<div class="list-wrap" v-if="props.total">
|
||||
<el-table
|
||||
v-if="props.total"
|
||||
ref="multipleListTable"
|
||||
class="list-table"
|
||||
:data="data"
|
||||
empty-text="暂无数据"
|
||||
row-key="_id"
|
||||
header-row-class-name="tableview-header"
|
||||
row-class-name="tableview-row"
|
||||
cell-class-name="tableview-cell"
|
||||
v-loading="loading"
|
||||
:height="550"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column column-key="space" width="20" />
|
||||
<el-table-column
|
||||
v-for="field in fieldList"
|
||||
:key="(field as any)?.key"
|
||||
:label="(field as any).title"
|
||||
:column-key="(field as any).key"
|
||||
:width="(field as any).width"
|
||||
:min-width="(field as any).width || (field as any).minWidth"
|
||||
class-name="link"
|
||||
>
|
||||
<template #default="scope">
|
||||
<template v-if="(field as any).comp">
|
||||
<component :is="(field as any).comp" type="table" :value="scope.row" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="cell-span">{{ scope.row[(field as any).key] }}</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
:width="200"
|
||||
label-class-name="operation"
|
||||
class-name="table-options"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div class="space-tool-bar">
|
||||
<ToolBar
|
||||
:data="scope.row"
|
||||
:tool-width="50"
|
||||
:tools="tools"
|
||||
@click="handleClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-else>
|
||||
<EmptyIndex :data="!searchVal ? noGroupDataConfig : noGroupSearchDataConfig" />
|
||||
</div>
|
||||
<div class="list-pagination">
|
||||
<el-pagination
|
||||
v-if="props.total"
|
||||
v-model:current-page="curPage"
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
layout="prev, pager, next"
|
||||
:total="props.total"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<GroupModify
|
||||
v-if="showGroupModify"
|
||||
type="edit"
|
||||
:visible="showGroupModify"
|
||||
@on-close-codify="onCloseModify"
|
||||
/>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import 'element-plus/theme-chalk/src/message-box.scss'
|
||||
import { get, map } from 'lodash-es'
|
||||
import {
|
||||
noGroupDataConfig,
|
||||
noGroupSearchDataConfig,
|
||||
groupListConfig
|
||||
} from '@/management/config/listConfig'
|
||||
import { MenuType } from '@/management/utils/workSpace'
|
||||
import GroupModify from './GroupModify.vue'
|
||||
import TextSearch from '@/management/pages/list/components/TextSearch.vue'
|
||||
import EmptyIndex from '@/management/components/EmptyIndex.vue'
|
||||
import ToolBar from './ToolBar.vue'
|
||||
import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
import { useSurveyListStore } from '@/management/stores/surveyList'
|
||||
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const surveyListStore = useSurveyListStore()
|
||||
|
||||
const showGroupModify = ref(false)
|
||||
const props = defineProps({
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
const fields = ['name', 'surveyTotal', 'createdAt']
|
||||
const fieldList = computed(() => {
|
||||
return map(fields, (f) => {
|
||||
return get(groupListConfig, f, null)
|
||||
})
|
||||
})
|
||||
const tools = ref([{
|
||||
key: 'open',
|
||||
label: '进入'
|
||||
}, {
|
||||
key: 'modify',
|
||||
label: '管理'
|
||||
}, {
|
||||
key: 'delete',
|
||||
label: '删除'
|
||||
}])
|
||||
|
||||
const data = computed(() => {
|
||||
return props.data
|
||||
})
|
||||
let searchVal = ref('')
|
||||
let curPage = ref(1)
|
||||
const emitRefresh = (page: number, name: string) => {
|
||||
curPage.value = page
|
||||
emit('refresh', {
|
||||
curPage: page,
|
||||
name
|
||||
})
|
||||
}
|
||||
const handleCurrentChange = async (val: number) => {
|
||||
emitRefresh(val, searchVal.value)
|
||||
}
|
||||
const onSearchText = async (value: string) => {
|
||||
searchVal.value = value
|
||||
emitRefresh(1, value)
|
||||
}
|
||||
|
||||
const handleModify = (id: string) => {
|
||||
workSpaceStore.getGroupDetail(id)
|
||||
showGroupModify.value = true
|
||||
}
|
||||
const handleDelete = (id: string) => {
|
||||
ElMessageBox.confirm(
|
||||
'删除分组后,属于该分组的问卷将会自动更换到“未分组”下,是否确认本次删除?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
await workSpaceStore.deleteGroup(id)
|
||||
await workSpaceStore.getGroupList()
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
const handleClick = (key: string, data: any) => {
|
||||
if (key === 'modify') {
|
||||
handleModify(data._id)
|
||||
} else if (key === 'delete') {
|
||||
handleDelete(data._id)
|
||||
} else if(key === 'open') {
|
||||
workSpaceStore.changeMenuType(MenuType.PersonalGroup)
|
||||
workSpaceStore.changeGroup(data._id)
|
||||
surveyListStore.getSurveyList({
|
||||
pageSize: 10,
|
||||
curPage: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onCloseModify = () => {
|
||||
showGroupModify.value = false
|
||||
workSpaceStore.getGroupList()
|
||||
}
|
||||
|
||||
defineExpose({ onCloseModify })
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.list-pagination {
|
||||
margin-top: 20px;
|
||||
:deep(.el-pagination) {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
.list-wrap {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
|
||||
.search {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.list-table {
|
||||
:deep(.el-table__header) {
|
||||
.tableview-header .el-table__cell {
|
||||
.cell {
|
||||
height: 24px;
|
||||
color: #4a4c5b;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.tableview-row) {
|
||||
.tableview-cell {
|
||||
height: 42px;
|
||||
|
||||
&.link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cell .cell-span {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="base-dialog-root"
|
||||
:model-value="visible"
|
||||
width="40%"
|
||||
:title="formTitle"
|
||||
@close="onClose"
|
||||
>
|
||||
<el-form
|
||||
class="base-form-root"
|
||||
ref="ruleForm"
|
||||
:model="formModel"
|
||||
:rules="rules"
|
||||
label-position="top"
|
||||
size="large"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input v-model="formModel.name" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="onClose">取消</el-button>
|
||||
<el-button type="primary" class="save-btn" @click="onConfirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, shallowRef, onMounted } from 'vue'
|
||||
import { pick as _pick } from 'lodash-es'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import 'element-plus/theme-chalk/src/message.scss'
|
||||
|
||||
import { QOP_MAP } from '@/management/utils/constant'
|
||||
import { type IGroup } from '@/management/utils/workSpace'
|
||||
import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const emit = defineEmits(['on-close-codify'])
|
||||
const props = defineProps({
|
||||
type: String,
|
||||
width: String,
|
||||
visible: Boolean
|
||||
})
|
||||
const ruleForm = shallowRef<any>(null)
|
||||
|
||||
const formTitle = computed(() => {
|
||||
return props.type === QOP_MAP.ADD ? '创建分组' : '管理分组'
|
||||
})
|
||||
const formModel = ref<Required<IGroup>>({
|
||||
_id: '',
|
||||
name: ''
|
||||
})
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入分组名称', trigger: 'blur' }]
|
||||
}
|
||||
const groupDetail = computed(() => {
|
||||
return workSpaceStore.groupDetail
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.type === QOP_MAP.EDIT) {
|
||||
formModel.value = _pick(groupDetail.value as any, ['_id', 'name'])
|
||||
}
|
||||
})
|
||||
const onClose = () => {
|
||||
formModel.value = {
|
||||
_id: '',
|
||||
name: ''
|
||||
}
|
||||
// 清空空间详情
|
||||
workSpaceStore.setGroupDetail(null)
|
||||
emit('on-close-codify')
|
||||
}
|
||||
|
||||
const onConfirm = async () => {
|
||||
ruleForm.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (props.type === QOP_MAP.ADD) {
|
||||
try {
|
||||
await handleAdd()
|
||||
emit('on-close-codify')
|
||||
} catch (err) {
|
||||
ElMessage.error('createGroup status err' + err)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await handleUpdate()
|
||||
emit('on-close-codify')
|
||||
} catch (err) {
|
||||
ElMessage.error('createGroup status err' + err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleUpdate = async () => {
|
||||
await workSpaceStore.updateGroup(formModel.value)
|
||||
}
|
||||
const handleAdd = async () => {
|
||||
await workSpaceStore.addGroup({ name: formModel.value.name })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="lang/scss" scoped>
|
||||
.base-form-root {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
|
@ -21,19 +21,6 @@
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="current.remark" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="groupId" label="问卷分组" v-if="menuType === MenuType.PersonalGroup">
|
||||
<el-select
|
||||
v-model="current.groupId"
|
||||
placeholder="未分组"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in groupAllList"
|
||||
:key="item._id"
|
||||
:label="item.name"
|
||||
:value="item._id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@ -48,6 +35,7 @@
|
||||
|
||||
<script>
|
||||
import { pick as _pick } from 'lodash-es'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import 'element-plus/theme-chalk/src/message.scss'
|
||||
|
||||
@ -55,22 +43,17 @@ import { CODE_MAP } from '@/management/api/base'
|
||||
import { updateSurvey, createSurvey } from '@/management/api/survey'
|
||||
import { QOP_MAP } from '@/management/utils/constant'
|
||||
|
||||
import { MenuType } from '@/management/utils/workSpace'
|
||||
|
||||
export default {
|
||||
name: 'ModifyDialog',
|
||||
props: {
|
||||
type: String,
|
||||
questionInfo: Object,
|
||||
width: String,
|
||||
visible: Boolean,
|
||||
groupAllList: Array,
|
||||
menuType: String,
|
||||
visible: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
QOP_MAP,
|
||||
MenuType,
|
||||
loadingInstance: null,
|
||||
rules: {
|
||||
title: [{ required: true, message: '请输入问卷标题', trigger: 'blur' }]
|
||||
@ -89,8 +72,7 @@ export default {
|
||||
methods: {
|
||||
getCurrent(val) {
|
||||
return {
|
||||
..._pick(val, ['title', 'remark']),
|
||||
groupId: val.groupId === null ? '' : val.groupId
|
||||
..._pick(val, ['title', 'remark'])
|
||||
}
|
||||
},
|
||||
onClose() {
|
||||
|
@ -1,16 +1,14 @@
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="active"
|
||||
:default-active="SpaceType.Personal"
|
||||
class="el-menu-vertical"
|
||||
ref="menuRef"
|
||||
@select="handleMenu"
|
||||
@open="handleMenu"
|
||||
@close="handleMenu"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<template v-for="(menu, index) in props.menus" :key="menu.id">
|
||||
<template v-for="(menu, index) in menus" :key="menu.id">
|
||||
<el-menu-item
|
||||
:class="[index === 0 ? 'bottom' : '', index > 2 ? 'sub-item' : 'main-item', active == menu.id ? 'check-item' : '' ]"
|
||||
:index="menu.id.toString()"
|
||||
:class="[index === 0 ? 'bottom' : '', index > 2 ? 'sub-item' : 'main-item']"
|
||||
:index="menu.id"
|
||||
v-if="!menu.children?.length"
|
||||
>
|
||||
<template #title>
|
||||
@ -20,65 +18,46 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
<el-sub-menu v-else :index="menu.id.toString()" :class="[ active == menu.id ? 'check-item' : '' ]">
|
||||
<el-menu-item-group v-else>
|
||||
<template #title>
|
||||
<div class="title-content sub-title main-item">
|
||||
<el-menu-item :index="menu.id" class="sub-title main-item">
|
||||
<div class="title-content">
|
||||
<i :class="['iconfont', menu.icon]"></i>
|
||||
<span>{{ menu.name }}</span>
|
||||
</div>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
<el-menu-item v-for="item in menu.children" :key="item.id" :index="item.id.toString()" :class="[ active == item.id ? 'check-item' : '' ]">
|
||||
<div class="title-box">
|
||||
<p class="title-text">{{ item.name }}</p>
|
||||
<p class="title-total">{{ item.total }}</p>
|
||||
</div>
|
||||
<el-menu-item v-for="item in menu.children" :key="item.id" :index="item.id">
|
||||
<p>
|
||||
{{ item.name }}
|
||||
</p>
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-menu-item-group>
|
||||
</template>
|
||||
</el-menu>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { type MenuItem } from '@/management/utils/workSpace'
|
||||
import { MenuType } from '@/management/utils/workSpace'
|
||||
import { SpaceType } from '@/management/utils/workSpace'
|
||||
|
||||
const menuRef = ref()
|
||||
const props = withDefaults(
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
menus: Array<MenuItem>,
|
||||
activeValue: string
|
||||
menus: Array<MenuItem>
|
||||
}>(),
|
||||
{
|
||||
menus: () => [],
|
||||
activeValue: MenuType.PersonalGroup
|
||||
menus: () => []
|
||||
}
|
||||
)
|
||||
|
||||
const active = computed({
|
||||
get: () => {
|
||||
return props.activeValue
|
||||
},
|
||||
set: () => {}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['select'])
|
||||
const handleMenu = (id: string) => {
|
||||
active.value = id
|
||||
const handleSelect = (id: string) => {
|
||||
emit('select', id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-sub-menu {
|
||||
:deep(.el-sub-menu__icon-arrow) {
|
||||
transform: rotate(-90deg) !important;
|
||||
}
|
||||
|
||||
&.is-opened {
|
||||
> :deep(.el-sub-menu__title .el-sub-menu__icon-arrow) {
|
||||
transform: rotate(0deg) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-menu-vertical {
|
||||
border: none;
|
||||
width: 200px;
|
||||
@ -115,6 +94,10 @@ const handleMenu = (id: string) => {
|
||||
&.sub-item {
|
||||
margin: 0;
|
||||
}
|
||||
&.is-active {
|
||||
// background-color: #F2F4F7;
|
||||
background: #fef6e6 100% !important;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #f2f4f7;
|
||||
}
|
||||
@ -123,27 +106,6 @@ const handleMenu = (id: string) => {
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.title-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
width: 80%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.title-total {
|
||||
font-size: 14px;
|
||||
color: #92949D;
|
||||
text-align: right;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
}
|
||||
:deep(.el-menu-item-group) {
|
||||
> ul {
|
||||
@ -166,7 +128,4 @@ const handleMenu = (id: string) => {
|
||||
margin-right: 10px;
|
||||
color: #faa600 !important;
|
||||
}
|
||||
.check-item {
|
||||
background: #fef6e6 100% !important
|
||||
}
|
||||
</style>
|
||||
|
@ -2,75 +2,71 @@
|
||||
<div class="search">
|
||||
<TextSearch placeholder="请输入空间名称" :value="searchVal" @search="onSearchText" />
|
||||
</div>
|
||||
<template v-if="total > 0">
|
||||
<div class="list-wrap">
|
||||
<el-table
|
||||
ref="multipleListTable"
|
||||
class="list-table"
|
||||
:data="data"
|
||||
empty-text="暂无数据"
|
||||
row-key="_id"
|
||||
header-row-class-name="tableview-header"
|
||||
row-class-name="tableview-row"
|
||||
cell-class-name="tableview-cell"
|
||||
v-loading="loading"
|
||||
:height="550"
|
||||
style="width: 100%"
|
||||
<div class="list-wrap" v-if="props.total > 0">
|
||||
<el-table
|
||||
ref="multipleListTable"
|
||||
class="list-table"
|
||||
:data="data"
|
||||
empty-text="暂无数据"
|
||||
row-key="_id"
|
||||
header-row-class-name="tableview-header"
|
||||
row-class-name="tableview-row"
|
||||
cell-class-name="tableview-cell"
|
||||
v-loading="loading"
|
||||
:height="550"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column column-key="space" width="20" />
|
||||
<el-table-column
|
||||
v-for="field in fieldList"
|
||||
:key="(field as any)?.key"
|
||||
:label="(field as any).title"
|
||||
:column-key="(field as any).key"
|
||||
:width="(field as any).width"
|
||||
:min-width="(field as any).width || (field as any).minWidth"
|
||||
class-name="link"
|
||||
>
|
||||
<el-table-column column-key="space" width="20" />
|
||||
<el-table-column
|
||||
v-for="field in fieldList"
|
||||
:key="(field as any)?.key"
|
||||
:label="(field as any).title"
|
||||
:column-key="(field as any).key"
|
||||
:width="(field as any).width"
|
||||
:min-width="(field as any).width || (field as any).minWidth"
|
||||
class-name="link"
|
||||
>
|
||||
<template #default="scope">
|
||||
<template v-if="(field as any).comp">
|
||||
<component :is="(field as any).comp" type="table" :value="scope.row" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="cell-span">{{ scope.row[(field as any).key] }}</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<template v-if="(field as any).comp">
|
||||
<component :is="(field as any).comp" type="table" :value="scope.row" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
:width="200"
|
||||
label-class-name="operation"
|
||||
class-name="table-options"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div class="space-tool-bar">
|
||||
<ToolBar
|
||||
:data="scope.row"
|
||||
:tool-width="50"
|
||||
:tools="getTools(scope.row)"
|
||||
@click="handleClick"
|
||||
/>
|
||||
</div>
|
||||
<template v-else>
|
||||
<span class="cell-span">{{ scope.row[(field as any).key] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="list-pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="curPage"
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
layout="prev, pager, next"
|
||||
:total="props.total"
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
:width="200"
|
||||
label-class-name="operation"
|
||||
class-name="table-options"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #default="scope">
|
||||
<div class="space-tool-bar">
|
||||
<ToolBar
|
||||
:data="scope.row"
|
||||
:tool-width="50"
|
||||
:tools="getTools(scope.row)"
|
||||
@click="handleClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-else>
|
||||
<EmptyIndex :data="!searchVal ? noSpaceDataConfig : noSpaceSearchDataConfig" />
|
||||
</div>
|
||||
|
||||
<div class="list-pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="curPage"
|
||||
background
|
||||
@current-change="handleCurrentChange"
|
||||
layout="prev, pager, next"
|
||||
:total="props.total"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<SpaceModify
|
||||
v-if="showSpaceModify"
|
||||
:type="modifyType"
|
||||
|
@ -55,7 +55,7 @@ import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
import MemberSelect from '@/management/components/CooperModify/MemberSelect.vue'
|
||||
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const emit = defineEmits(['on-close-codify', 'onFocus', 'change', 'blur', 'updateData'])
|
||||
const emit = defineEmits(['on-close-codify', 'onFocus', 'change', 'blur'])
|
||||
const props = defineProps({
|
||||
type: String,
|
||||
width: String,
|
||||
@ -128,7 +128,6 @@ const onConfirm = async () => {
|
||||
} else {
|
||||
try {
|
||||
await handleUpdate()
|
||||
emit('updateData', formModel.value)
|
||||
emit('on-close-codify', 'update')
|
||||
} catch (err) {
|
||||
ElMessage.error('createSpace status err' + err)
|
||||
|
@ -2,32 +2,23 @@
|
||||
<div class="question-list-root">
|
||||
<TopNav></TopNav>
|
||||
<div class="content-wrap">
|
||||
<SliderBar :menus="spaceMenus" :activeValue="activeValue" @select="handleSpaceSelect" />
|
||||
<SliderBar :menus="spaceMenus" @select="handleSpaceSelect" />
|
||||
<div class="list-content">
|
||||
<div class="top">
|
||||
<h2>
|
||||
{{ tableTitle }}
|
||||
{{ spaceType === SpaceType.Group ? '团队空间' : currentTeamSpace?.name || '问卷列表' }}
|
||||
</h2>
|
||||
<div class="operation">
|
||||
<el-button
|
||||
class="btn create-btn"
|
||||
type="default"
|
||||
@click="onSpaceCreate"
|
||||
v-if="menuType === MenuType.SpaceGroup && !workSpaceId"
|
||||
v-if="spaceType == SpaceType.Group"
|
||||
>
|
||||
<i class="iconfont icon-chuangjian"></i>
|
||||
<span>创建团队空间</span>
|
||||
</el-button>
|
||||
<el-button
|
||||
class="btn create-btn"
|
||||
type="default"
|
||||
@click="onGroupCreate"
|
||||
v-if="menuType === MenuType.PersonalGroup && !groupId"
|
||||
>
|
||||
<i class="iconfont icon-chuangjian"></i>
|
||||
<span>创建分组</span>
|
||||
</el-button>
|
||||
<el-button type="default" class="btn" @click="onSetGroup" v-if="workSpaceId && menuType === MenuType.SpaceGroup">
|
||||
<el-button type="default" class="btn" @click="onSetGroup" v-if="workSpaceId">
|
||||
<i class="iconfont icon-shujuliebiao"></i>
|
||||
<span>团队管理</span>
|
||||
</el-button>
|
||||
@ -35,7 +26,7 @@
|
||||
class="btn create-btn"
|
||||
type="default"
|
||||
@click="onCreate"
|
||||
v-if="workSpaceId || groupId"
|
||||
v-if="spaceType !== SpaceType.Group"
|
||||
>
|
||||
<i class="iconfont icon-chuangjian"></i>
|
||||
<span>创建问卷</span>
|
||||
@ -47,7 +38,7 @@
|
||||
:data="surveyList"
|
||||
:total="surveyTotal"
|
||||
@refresh="fetchSurveyList"
|
||||
v-if="workSpaceId || groupId"
|
||||
v-if="spaceType !== SpaceType.Group"
|
||||
></BaseList>
|
||||
<SpaceList
|
||||
ref="spaceListRef"
|
||||
@ -55,30 +46,15 @@
|
||||
:loading="spaceLoading"
|
||||
:data="workSpaceList"
|
||||
:total="workSpaceListTotal"
|
||||
v-if="menuType === MenuType.SpaceGroup && !workSpaceId"
|
||||
v-if="spaceType === SpaceType.Group"
|
||||
></SpaceList>
|
||||
<GroupList
|
||||
ref="groupListRef"
|
||||
@refresh="fetchGroupList"
|
||||
:loading="groupLoading"
|
||||
:data="groupList"
|
||||
:total="groupListTotal"
|
||||
v-if="menuType === MenuType.PersonalGroup && !groupId"
|
||||
></GroupList>
|
||||
</div>
|
||||
</div>
|
||||
<SpaceModify
|
||||
v-if="showSpaceModify"
|
||||
:type="modifyType"
|
||||
:visible="showSpaceModify"
|
||||
@on-close-codify="onCloseSpaceModify"
|
||||
@update-data="onCloseModifyInTeamWork"
|
||||
/>
|
||||
<GroupModify
|
||||
v-if="showGroupModify"
|
||||
type="add"
|
||||
:visible="showGroupModify"
|
||||
@on-close-codify="onCloseGroupModify"
|
||||
@on-close-codify="onCloseModify"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -89,54 +65,25 @@ import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
import BaseList from './components/BaseList.vue'
|
||||
import SpaceList from './components/SpaceList.vue'
|
||||
import GroupList from './components/GroupList.vue'
|
||||
import SliderBar from './components/SliderBar.vue'
|
||||
import SpaceModify from './components/SpaceModify.vue'
|
||||
import GroupModify from './components/GroupModify.vue'
|
||||
import TopNav from '@/management/components/TopNav.vue'
|
||||
import { MenuType } from '@/management/utils/workSpace'
|
||||
|
||||
import { SpaceType } from '@/management/utils/workSpace'
|
||||
import { useWorkSpaceStore } from '@/management/stores/workSpace'
|
||||
import { useSurveyListStore } from '@/management/stores/surveyList'
|
||||
import { type IWorkspace } from '@/management/utils/workSpace'
|
||||
|
||||
const workSpaceStore = useWorkSpaceStore()
|
||||
const surveyListStore = useSurveyListStore()
|
||||
|
||||
const { surveyList, surveyTotal } = storeToRefs(surveyListStore)
|
||||
const { spaceMenus, workSpaceId, groupId, menuType, workSpaceList, workSpaceListTotal, groupList, groupListTotal } =
|
||||
const { spaceMenus, workSpaceId, spaceType, workSpaceList, workSpaceListTotal } =
|
||||
storeToRefs(workSpaceStore)
|
||||
const router = useRouter()
|
||||
|
||||
const tableTitle = computed(() => {
|
||||
if(menuType.value === MenuType.PersonalGroup && !groupId.value) {
|
||||
return '我的空间'
|
||||
} else if (menuType.value === MenuType.SpaceGroup && !workSpaceId.value) {
|
||||
return '团队空间'
|
||||
} else {
|
||||
return currentTeamSpace.value?.name || '问卷列表';
|
||||
}
|
||||
})
|
||||
|
||||
const activeValue = computed(() => {
|
||||
if(workSpaceId.value !== '') {
|
||||
return workSpaceId.value
|
||||
} else if(groupId.value !== '') {
|
||||
return groupId.value
|
||||
} else if(menuType.value === MenuType.PersonalGroup) {
|
||||
return MenuType.PersonalGroup
|
||||
} else if(menuType.value === MenuType.SpaceGroup) {
|
||||
return MenuType.SpaceGroup
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const spaceListRef = ref<any>(null)
|
||||
const spaceLoading = ref(false)
|
||||
const groupLoading = ref(false)
|
||||
|
||||
const fetchSpaceList = async (params?: any) => {
|
||||
spaceLoading.value = true
|
||||
@ -145,39 +92,24 @@ const fetchSpaceList = async (params?: any) => {
|
||||
spaceLoading.value = false
|
||||
}
|
||||
|
||||
const fetchGroupList = async (params?: any) => {
|
||||
groupLoading.value = true
|
||||
workSpaceStore.changeWorkSpace('')
|
||||
workSpaceStore.getGroupList(params)
|
||||
groupLoading.value = false
|
||||
}
|
||||
|
||||
const handleSpaceSelect = (id: MenuType | string) => {
|
||||
if (groupId.value === id || workSpaceId.value === id) {
|
||||
const handleSpaceSelect = (id: SpaceType | string) => {
|
||||
if (id === spaceType.value || id === workSpaceId.value) {
|
||||
return void 0
|
||||
}
|
||||
let parentMenu = undefined
|
||||
|
||||
switch (id) {
|
||||
case MenuType.PersonalGroup:
|
||||
workSpaceStore.changeMenuType(MenuType.PersonalGroup)
|
||||
case SpaceType.Personal:
|
||||
workSpaceStore.changeSpaceType(SpaceType.Personal)
|
||||
workSpaceStore.changeWorkSpace('')
|
||||
fetchGroupList()
|
||||
break
|
||||
case MenuType.SpaceGroup:
|
||||
workSpaceStore.changeMenuType(MenuType.SpaceGroup)
|
||||
case SpaceType.Group:
|
||||
workSpaceStore.changeSpaceType(SpaceType.Group)
|
||||
workSpaceStore.changeWorkSpace('')
|
||||
fetchSpaceList()
|
||||
break
|
||||
default:
|
||||
parentMenu = spaceMenus.value.find((parent: any) => parent.children.find((children: any) => children.id.toString() === id))
|
||||
if(parentMenu != undefined) {
|
||||
workSpaceStore.changeMenuType(parentMenu.id)
|
||||
if(parentMenu.id === MenuType.PersonalGroup) {
|
||||
workSpaceStore.changeGroup(id)
|
||||
} else if (parentMenu.id === MenuType.SpaceGroup) {
|
||||
workSpaceStore.changeWorkSpace(id)
|
||||
}
|
||||
}
|
||||
workSpaceStore.changeSpaceType(SpaceType.Teamwork)
|
||||
workSpaceStore.changeWorkSpace(id)
|
||||
break
|
||||
}
|
||||
fetchSurveyList()
|
||||
@ -199,7 +131,6 @@ const fetchSurveyList = async (params?: any) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchGroupList()
|
||||
fetchSpaceList()
|
||||
fetchSurveyList()
|
||||
})
|
||||
@ -218,24 +149,7 @@ const onSetGroup = async () => {
|
||||
showSpaceModify.value = true
|
||||
}
|
||||
|
||||
const onCloseModifyInTeamWork = (data: IWorkspace) => {
|
||||
if (activeValue.value === MenuType.SpaceGroup) {
|
||||
const currentData = workSpaceList.value.find((item) => item._id === data._id)
|
||||
if (currentData) {
|
||||
currentData.name = data.name
|
||||
currentData.memberTotal = data.members.length
|
||||
currentData.description = data.description
|
||||
}
|
||||
const currentMenus: any = spaceMenus.value?.[1]?.children?.find(
|
||||
(item: { id: string; name: string }) => item.id === data._id
|
||||
)
|
||||
if (currentMenus) {
|
||||
currentMenus.name = data.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onCloseSpaceModify = (type: string) => {
|
||||
const onCloseModify = (type: string) => {
|
||||
showSpaceModify.value = false
|
||||
if (type === 'update' && spaceListRef.value) {
|
||||
fetchSpaceList()
|
||||
@ -246,20 +160,6 @@ const onSpaceCreate = () => {
|
||||
modifyType.value = 'add'
|
||||
showSpaceModify.value = true
|
||||
}
|
||||
|
||||
// 分组
|
||||
|
||||
const showGroupModify = ref<boolean>(false)
|
||||
|
||||
const onCloseGroupModify = () => {
|
||||
showGroupModify.value = false
|
||||
fetchGroupList()
|
||||
}
|
||||
|
||||
const onGroupCreate = () => {
|
||||
showGroupModify.value = true
|
||||
}
|
||||
|
||||
const onCreate = () => {
|
||||
router.push('/create')
|
||||
}
|
||||
|
@ -166,16 +166,10 @@ export const useEditStore = defineStore('edit', () => {
|
||||
if (!questCount) {
|
||||
return startIndex
|
||||
}
|
||||
return endIndex - 1
|
||||
return endIndex
|
||||
}
|
||||
})
|
||||
|
||||
const hasSetCurrentEditOne = (value: number) => {
|
||||
if(!currentEditOne.value) {
|
||||
setCurrentEditOne(value)
|
||||
}
|
||||
}
|
||||
|
||||
// 题目操作:增删改
|
||||
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion } = useQuestionData({
|
||||
questionDataList,
|
||||
@ -200,7 +194,6 @@ export const useEditStore = defineStore('edit', () => {
|
||||
currentEditMeta,
|
||||
newQuestionIndex,
|
||||
setCurrentEditOne,
|
||||
hasSetCurrentEditOne,
|
||||
changeCurrentEditStatus,
|
||||
|
||||
pageEditOne,
|
||||
|
@ -6,7 +6,7 @@ import 'element-plus/theme-chalk/src/message.scss'
|
||||
|
||||
import { CODE_MAP } from '@/management/api/base'
|
||||
import { getSurveyList as getSurveyListReq } from '@/management/api/survey'
|
||||
import { GroupState } from '@/management/utils/workSpace'
|
||||
|
||||
import { useWorkSpaceStore } from './workSpace'
|
||||
|
||||
import {
|
||||
@ -150,8 +150,7 @@ export const useSurveyListStore = defineStore('surveyList', () => {
|
||||
pageSize: payload?.pageSize || 10, // 默认一页10条
|
||||
filter: filterString,
|
||||
order: orderString,
|
||||
workspaceId: workSpaceStore.workSpaceId,
|
||||
groupId: workSpaceStore.groupId === GroupState.All ? '' : workSpaceStore.groupId
|
||||
workspaceId: workSpaceStore.workSpaceId
|
||||
}
|
||||
|
||||
const res: any = await getSurveyListReq(params)
|
||||
|
@ -10,16 +10,11 @@ import {
|
||||
updateSpace as updateSpaceReq,
|
||||
deleteSpace as deleteSpaceReq,
|
||||
getSpaceList as getSpaceListReq,
|
||||
getSpaceDetail as getSpaceDetailReq,
|
||||
createGroup,
|
||||
getGroupList as getGroupListReq,
|
||||
updateGroup as updateGroupReq,
|
||||
deleteGroup as deleteGroupReq
|
||||
getSpaceDetail as getSpaceDetailReq
|
||||
} from '@/management/api/space'
|
||||
|
||||
import { GroupState, MenuType } from '@/management/utils/workSpace'
|
||||
import { type SpaceDetail, type SpaceItem, type IWorkspace, type IGroup, type GroupItem, } from '@/management/utils/workSpace'
|
||||
|
||||
import { SpaceType } from '@/management/utils/workSpace'
|
||||
import { type SpaceDetail, type SpaceItem, type IWorkspace } from '@/management/utils/workSpace'
|
||||
|
||||
import { useSurveyListStore } from './surveyList'
|
||||
|
||||
@ -29,18 +24,16 @@ export const useWorkSpaceStore = defineStore('workSpace', () => {
|
||||
{
|
||||
icon: 'icon-wodekongjian',
|
||||
name: '我的空间',
|
||||
id: MenuType.PersonalGroup,
|
||||
children: []
|
||||
id: SpaceType.Personal
|
||||
},
|
||||
{
|
||||
icon: 'icon-tuanduikongjian',
|
||||
name: '团队空间',
|
||||
id: MenuType.SpaceGroup,
|
||||
id: SpaceType.Group,
|
||||
children: []
|
||||
}
|
||||
])
|
||||
const menuType = ref(MenuType.PersonalGroup)
|
||||
const groupId = ref('')
|
||||
const spaceType = ref(SpaceType.Personal)
|
||||
const workSpaceId = ref('')
|
||||
const spaceDetail = ref<SpaceDetail | null>(null)
|
||||
const workSpaceList = ref<SpaceItem[]>([])
|
||||
@ -57,8 +50,7 @@ export const useWorkSpaceStore = defineStore('workSpace', () => {
|
||||
const workSpace = list.map((item: SpaceDetail) => {
|
||||
return {
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
total: item.surveyTotal
|
||||
name: item.name
|
||||
}
|
||||
})
|
||||
workSpaceList.value = list
|
||||
@ -86,19 +78,12 @@ export const useWorkSpaceStore = defineStore('workSpace', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function changeMenuType(id: MenuType) {
|
||||
menuType.value = id
|
||||
function changeSpaceType(id: SpaceType) {
|
||||
spaceType.value = id
|
||||
}
|
||||
|
||||
function changeWorkSpace(id: string) {
|
||||
workSpaceId.value = id
|
||||
groupId.value = ''
|
||||
surveyListStore.resetSearch()
|
||||
}
|
||||
|
||||
function changeGroup(id: string) {
|
||||
groupId.value = id
|
||||
workSpaceId.value = ''
|
||||
surveyListStore.resetSearch()
|
||||
}
|
||||
|
||||
@ -142,129 +127,20 @@ export const useWorkSpaceStore = defineStore('workSpace', () => {
|
||||
spaceDetail.value = data
|
||||
}
|
||||
|
||||
// 分组
|
||||
const groupList = ref<GroupItem[]>([])
|
||||
const groupAllList = ref<IGroup[]>([])
|
||||
const groupListTotal = ref(0)
|
||||
const groupDetail = ref<GroupItem | null>(null)
|
||||
async function addGroup(params: IGroup) {
|
||||
const { name } = params
|
||||
const res: any = await createGroup({ name })
|
||||
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
ElMessage.success('添加成功')
|
||||
} else {
|
||||
ElMessage.error('createGroup code err' + res.errmsg)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateGroup(params: Required<IGroup>) {
|
||||
const { _id, name } = params
|
||||
const res: any = await updateGroupReq({ _id, name })
|
||||
|
||||
if (res?.code === CODE_MAP.SUCCESS) {
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
ElMessage.error(res?.errmsg)
|
||||
}
|
||||
}
|
||||
|
||||
async function getGroupList(params = { curPage: 1 }) {
|
||||
try {
|
||||
const res: any = await getGroupListReq(params)
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
const { list, allList, total, notTotal } = res.data
|
||||
let allTotal = notTotal
|
||||
const group = list.map((item: GroupItem) => {
|
||||
allTotal += item.surveyTotal
|
||||
return {
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
total: item.surveyTotal,
|
||||
}
|
||||
})
|
||||
group.unshift({
|
||||
id: GroupState.All,
|
||||
name: '全部' ,
|
||||
total: allTotal
|
||||
}, {
|
||||
id: GroupState.Not,
|
||||
name: '未分组' ,
|
||||
total: notTotal
|
||||
})
|
||||
allList.unshift({
|
||||
_id: '',
|
||||
name: '未分组'
|
||||
})
|
||||
groupList.value = list
|
||||
groupListTotal.value = total
|
||||
spaceMenus.value[0].children = group
|
||||
groupAllList.value = allList
|
||||
} else {
|
||||
ElMessage.error('getGroupList' + res.errmsg)
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.error('getGroupList' + err)
|
||||
}
|
||||
}
|
||||
|
||||
function getGroupDetail(id: string) {
|
||||
try {
|
||||
const data = groupList.value.find((item: GroupItem) => item._id === id)
|
||||
if(data != undefined) {
|
||||
groupDetail.value = data
|
||||
} else {
|
||||
ElMessage.error('groupDetail 未找到分组')
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.error('groupDetail' + err)
|
||||
}
|
||||
}
|
||||
|
||||
function setGroupDetail(data: null | GroupItem) {
|
||||
groupDetail.value = data
|
||||
}
|
||||
|
||||
async function deleteGroup(id: string) {
|
||||
try {
|
||||
const res: any = await deleteGroupReq(id)
|
||||
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
ElMessage.success('删除成功')
|
||||
} else {
|
||||
ElMessage.error(res.errmsg)
|
||||
}
|
||||
} catch (err: any) {
|
||||
ElMessage.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
menuType,
|
||||
spaceMenus,
|
||||
groupId,
|
||||
spaceType,
|
||||
workSpaceId,
|
||||
spaceDetail,
|
||||
workSpaceList,
|
||||
workSpaceListTotal,
|
||||
getSpaceList,
|
||||
getSpaceDetail,
|
||||
changeMenuType,
|
||||
changeSpaceType,
|
||||
changeWorkSpace,
|
||||
changeGroup,
|
||||
addSpace,
|
||||
deleteSpace,
|
||||
updateSpace,
|
||||
setSpaceDetail,
|
||||
groupList,
|
||||
groupAllList,
|
||||
groupListTotal,
|
||||
groupDetail,
|
||||
addGroup,
|
||||
updateGroup,
|
||||
getGroupList,
|
||||
getGroupDetail,
|
||||
setGroupDetail,
|
||||
deleteGroup
|
||||
setSpaceDetail
|
||||
}
|
||||
})
|
||||
|
@ -7,15 +7,9 @@ export interface MenuItem {
|
||||
id: string
|
||||
name: string
|
||||
icon?: string
|
||||
total?: Number
|
||||
children?: MenuItem[]
|
||||
}
|
||||
|
||||
export type IGroup = {
|
||||
_id?: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type IWorkspace = {
|
||||
_id?: string
|
||||
name: string
|
||||
@ -35,7 +29,6 @@ export interface SpaceDetail {
|
||||
name: string
|
||||
currentUserId?: string
|
||||
description: string
|
||||
surveyTotal: number
|
||||
members: IMember[]
|
||||
}
|
||||
|
||||
@ -56,30 +49,16 @@ export interface ICollaborator {
|
||||
permissions: Array<number>
|
||||
}
|
||||
|
||||
export type GroupItem = {
|
||||
_id: string,
|
||||
name: string,
|
||||
createdAt: string
|
||||
updatedAt?: string
|
||||
ownerId: string
|
||||
surveyTotal: number
|
||||
export enum SpaceType {
|
||||
Personal = 'personal',
|
||||
Group = 'group',
|
||||
Teamwork = 'teamwork'
|
||||
}
|
||||
|
||||
export enum MenuType {
|
||||
PersonalGroup = 'personalGroup',
|
||||
SpaceGroup = 'spaceGroup',
|
||||
}
|
||||
|
||||
export enum UserRole {
|
||||
Admin = 'admin',
|
||||
Member = 'user'
|
||||
}
|
||||
|
||||
export enum GroupState {
|
||||
All = 'all',
|
||||
Not = 'nogrouped'
|
||||
}
|
||||
|
||||
// 定义角色标签映射对象
|
||||
export const roleLabels: Record<UserRole, string> = {
|
||||
[UserRole.Admin]: '管理员',
|
||||
|
147
web/src/render/components/VerifyWhiteDialog.vue
Normal file
147
web/src/render/components/VerifyWhiteDialog.vue
Normal file
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="whiteVisible"
|
||||
title="验证"
|
||||
:show-close="false"
|
||||
class="verify-white-wrap"
|
||||
width="315"
|
||||
:close-on-press-escape="false"
|
||||
:close-on-click-modal="false"
|
||||
align-center
|
||||
>
|
||||
<template #header>
|
||||
<div class="verify-white-head">
|
||||
<div class="verify-white-title">验证</div>
|
||||
<div v-if="whitelistTip" class="verify-white-tips">{{ whitelistTip }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="verify-white-body">
|
||||
<el-input
|
||||
v-if="isPwd"
|
||||
v-model="state.password"
|
||||
class="wd255 mb16"
|
||||
placeholder="请输入6位字符串类型访问密码"
|
||||
/>
|
||||
<el-input
|
||||
v-if="isValue"
|
||||
v-model="state.value"
|
||||
class="wd255 mb16"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
<div class="submit-btn" @click="handleSubmit">验证并开始答题</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, computed, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import 'element-plus/theme-chalk/src/message.scss'
|
||||
|
||||
import { validate } from '../api/survey'
|
||||
import { useSurveyStore } from '../stores/survey'
|
||||
|
||||
const whiteVisible = ref(false)
|
||||
|
||||
const surveyStore = useSurveyStore()
|
||||
const state = reactive({
|
||||
password: '',
|
||||
value: '',
|
||||
is_submit: false
|
||||
})
|
||||
|
||||
const baseConf = computed(() => store.state.baseConf || {})
|
||||
const isPwd = computed(() => baseConf.value.passwordSwitch)
|
||||
const whitelistType = computed(() => baseConf.value.whitelistType)
|
||||
const memberType = computed(() => baseConf.value.memberType)
|
||||
const whitelistTip = computed(() => baseConf.value.whitelistTip)
|
||||
const surveyPath = computed(() => store.state?.surveyPath || '')
|
||||
|
||||
const isValue = computed(() => {
|
||||
if (!whitelistType.value) return false
|
||||
return whitelistType.value != 'ALL'
|
||||
})
|
||||
|
||||
const placeholder = computed(() => {
|
||||
if (whitelistType.value == 'MEMBER') {
|
||||
return '请输入用户名'
|
||||
}
|
||||
if (memberType.value == 'MOBILE') {
|
||||
return '请输入手机号'
|
||||
}
|
||||
if (memberType.value == 'EMAIL') {
|
||||
return '请输入邮箱'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (state.is_submit) return
|
||||
const params = {
|
||||
surveyPath: surveyPath.value
|
||||
}
|
||||
if (isValue.value) {
|
||||
params.whitelist = state.value
|
||||
}
|
||||
if (isPwd.value) {
|
||||
params.password = state.password
|
||||
}
|
||||
const res = await validate(params)
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res.errmsg || '验证失败')
|
||||
return
|
||||
}
|
||||
whiteVisible.value = false
|
||||
surveyStore.setWhiteData(params)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => baseConf.value,
|
||||
() => {
|
||||
if (whiteVisible.value) return
|
||||
if (isValue.value || isPwd.value) {
|
||||
whiteVisible.value = true
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.verify-white-wrap {
|
||||
.verify-white-body {
|
||||
padding: 0 14px;
|
||||
}
|
||||
.verify-white-head {
|
||||
padding: 0 14px;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.mb16 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.verify-white-tips {
|
||||
text-align: center;
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #92949d;
|
||||
}
|
||||
.verify-white-title {
|
||||
font-size: 16px;
|
||||
color: #292a36;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.submit-btn {
|
||||
background: #faa600;
|
||||
border-radius: 2px;
|
||||
width: 255px;
|
||||
height: 32px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -16,17 +16,13 @@
|
||||
>
|
||||
重新填写
|
||||
</router-link>
|
||||
|
||||
<a v-if="showJumpButton" :href="jumpConfig.link" class="jump-btn">
|
||||
{{ jumpConfig.buttonText }}
|
||||
</a>
|
||||
</div>
|
||||
<LogoIcon :logo-conf="logoConf" :readonly="true" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watchEffect } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useSurveyStore } from '../stores/survey'
|
||||
// @ts-ignore
|
||||
import communalLoader from '@materials/communals/communalLoader.js'
|
||||
@ -41,20 +37,6 @@ const successMsg = computed(() => {
|
||||
const msgContent = (surveyStore?.submitConf as any)?.msgContent || {}
|
||||
return msgContent?.msg_200 || '提交成功'
|
||||
})
|
||||
|
||||
const jumpConfig = computed(() => {
|
||||
return (surveyStore?.submitConf as any)?.jumpConfig || {}
|
||||
})
|
||||
|
||||
const showJumpButton = ref(false)
|
||||
|
||||
watchEffect(() => {
|
||||
const { jumpConfig } = (surveyStore?.submitConf || {}) as any
|
||||
if (jumpConfig?.type === 'link' && jumpConfig?.link) {
|
||||
window.location.href = jumpConfig.link
|
||||
}
|
||||
showJumpButton.value = jumpConfig?.type === 'button' && jumpConfig?.buttonText
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/render/styles/variable.scss';
|
||||
@ -105,20 +87,5 @@ watchEffect(() => {
|
||||
text-decoration: underline;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.jump-btn {
|
||||
background: var(--primary-color);
|
||||
width: 90%;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.2rem 0;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.3rem;
|
||||
font-weight: 500;
|
||||
margin: 0.5rem auto 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user