feat: 修改traceid生成规则,修改readme、图片和windows兼容

This commit is contained in:
sudoooooo 2024-02-06 21:01:58 +08:00
parent e3fa804fa8
commit 225e450bc9
39 changed files with 552 additions and 487 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
node_modules node_modules
dist dist
package-lock.json
# local env files # local env files
.env.local .env.local

View File

@ -1,16 +1,5 @@
# 镜像集成 # 镜像集成
FROM ubuntu:latest FROM node:16
# 安装依赖
RUN apt-get -y update
RUN apt-get -y install wget gcc
# 安装node环境
ENV NODE_VERSION v18.17.1
RUN mkdir -p /node/$NODE_VERSION
RUN wget https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-linux-x64.tar.gz
RUN tar xzf node-$NODE_VERSION-linux-x64.tar.gz -C /node/
ENV PATH /node/node-$NODE_VERSION-linux-x64/bin:$PATH
# 设置工作区间 # 设置工作区间
WORKDIR /xiaoju-survey WORKDIR /xiaoju-survey

View File

@ -1,8 +1,9 @@
XIAOJU_SURVEY_MONGO_DB_NAME=xiaojuSurvey XIAOJU_SURVEY_MONGO_DB_NAME=xiaojuSurvey
XIAOJU_SURVEY_MONGO_URL=mongodb://localhost:27017 XIAOJU_SURVEY_MONGO_URL=mongodb://localhost:27017
XIAOJU_SURVEY_RESPONSE_AES_ENCRYPT_SECRET_KEY=dataAesEncryptSecretKey
XIAOJU_SURVEY_MONGO_AUTH_SOURCE= XIAOJU_SURVEY_MONGO_AUTH_SOURCE=
XIAOJU_SURVEY_RESPONSE_AES_ENCRYPT_SECRET_KEY=dataAesEncryptSecretKey
XIAOJU_SURVEY_HTTP_DATA_ENCRYPT_TYPE=rsa XIAOJU_SURVEY_HTTP_DATA_ENCRYPT_TYPE=rsa
XIAOJU_SURVEY_JWT_SECRET=xiaojuSurveyJwtSecret XIAOJU_SURVEY_JWT_SECRET=xiaojuSurveyJwtSecret

View File

@ -1,73 +0,0 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

View File

@ -1,15 +1,14 @@
{ {
"name": "server-new", "name": "server",
"version": "0.0.1", "version": "0.0.1",
"description": "", "description": "",
"author": "", "author": "",
"private": true,
"license": "UNLICENSED",
"scripts": { "scripts": {
"build": "nest build", "build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"local": "ts-node ./scripts/run-local.ts", "local": "ts-node ./scripts/run-local.ts",
"start": "nest start", "start": "nest start",
"dev": "npm run start:dev",
"start:dev": "NODE_ENV=development nest start --watch", "start:dev": "NODE_ENV=development nest start --watch",
"start:debug": "NODE_ENV=development nest start --debug --watch", "start:debug": "NODE_ENV=development nest start --debug --watch",
"start:prod": "NODE_ENV=production node dist/main", "start:prod": "NODE_ENV=production node dist/main",

View File

@ -1,4 +1,4 @@
#main{ #main {
width: 100wh; width: 100wh;
height: 100vh; height: 100vh;
display: flex; display: flex;
@ -6,7 +6,8 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.title{
.title {
font-size: 20px; font-size: 20px;
color: #4A4C5B; color: #4A4C5B;
} }

View File

@ -2,8 +2,8 @@ import { MiddlewareConsumer, Module } from '@nestjs/common';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { ResponseSecurityPlugin } from './plugins/responseSecurityPlugin'; import { ResponseSecurityPlugin } from './securityPlugin/responseSecurityPlugin';
import { SurveyUtilPlugin } from './plugins/surveyUtilPlugin'; import { SurveyUtilPlugin } from './securityPlugin/surveyUtilPlugin';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigModule, ConfigService } from '@nestjs/config';
@ -29,9 +29,9 @@ import { ClientEncrypt } from './models/clientEncrypt.entity';
import { Word } from './models/word.entity'; import { Word } from './models/word.entity';
import { LoggerProvider } from './logger/logger.provider'; import { LoggerProvider } from './logger/logger.provider';
import { PluginManagerProvider } from './plugins/pluginManager.provider'; import { PluginManagerProvider } from './securityPlugin/pluginManager.provider';
import { LogRequestMiddleware } from './middlewares/logRequest.middleware'; import { LogRequestMiddleware } from './middlewares/logRequest.middleware';
import { XiaojuSurveyPluginManager } from './plugins/pluginManager'; import { XiaojuSurveyPluginManager } from './securityPlugin/pluginManager';
import { Logger } from './logger'; import { Logger } from './logger';
@Module({ @Module({

View File

@ -16,7 +16,7 @@ export class Authtication implements CanActivate {
const token = request.headers.authorization?.split(' ')[1]; const token = request.headers.authorization?.split(' ')[1];
if (!token) { if (!token) {
throw new AuthtificationException('登录'); throw new AuthtificationException('登录');
} }
let decoded; let decoded;

View File

@ -1,15 +1,27 @@
import { customAlphabet } from 'nanoid'; let count = 999;
const traceIdAlphabet = 'abcdef0123456789';
let count = 0;
const getCountStr = () => { const getCountStr = () => {
count++; count++;
return count.toString().padStart(8, '0'); if (count > 9000) {
count = 1000;
}
return count.toString();
}; };
const getRandom = customAlphabet(traceIdAlphabet, 10); export const genTraceId = ({ ip }) => {
// ip转16位 + 当前时间戳(毫秒级)+自增序列1000开始自增到9000+ 当前进程id的后5位
ip = ip.replace('::ffff:', '');
let ipArr;
if (ip.indexOf(':') > 0) {
ipArr = ip.split(':').map((segment) => {
// 将IPv6每个段转为16位并补0到长度为4
return parseInt(segment, 16).toString(16).padStart(4, '0');
});
} else {
ipArr = ip
.split('.')
.map((item) => parseInt(item).toString(16).padStart(2, '0'));
}
export const genTraceId = (): string => { return `${ipArr.join('')}${Date.now().toString()}${getCountStr()}${process.pid.toString().slice(-5)}`;
return getRandom() + Math.round(Date.now() / 1000).toString() + getCountStr();
}; };

View File

@ -2,7 +2,10 @@ import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
async function bootstrap() { async function bootstrap() {
const PORT = process.env.PORT || 3000;
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
await app.listen(3000); await app.listen(PORT);
console.log(`server is running at: http://127.0.0.1:${PORT}`);
} }
bootstrap(); bootstrap();

View File

@ -12,7 +12,7 @@ export class LogRequestMiddleware implements NestMiddleware {
const { method, originalUrl, ip } = req; const { method, originalUrl, ip } = req;
const userAgent = req.get('user-agent') || ''; const userAgent = req.get('user-agent') || '';
const startTime = Date.now(); const startTime = Date.now();
const traceId = genTraceId(); const traceId = genTraceId({ ip });
this.logger.setTraceId(traceId); this.logger.setTraceId(traceId);
const query = JSON.stringify(req.query); const query = JSON.stringify(req.query);
const body = JSON.stringify(req.body); const body = JSON.stringify(req.body);

View File

@ -8,31 +8,13 @@ import {
} from 'typeorm'; } from 'typeorm';
import { ObjectId } from 'mongodb'; import { ObjectId } from 'mongodb';
import { RECORD_STATUS } from '../enums'; import { RECORD_STATUS } from '../enums';
import pluginManager from '../plugins/pluginManager'; import pluginManager from '../securityPlugin/pluginManager';
@Entity({ name: 'surveySubmit' }) @Entity({ name: 'surveySubmit' })
export class SurveyResponse { export class SurveyResponse {
@ObjectIdColumn() @ObjectIdColumn()
_id: ObjectId; _id: ObjectId;
@Column()
curStatus: {
status: RECORD_STATUS;
date: number;
};
@Column()
statusList: Array<{
status: RECORD_STATUS;
date: number;
}>;
@Column()
createDate: number;
@Column()
updateDate: number;
@Column() @Column()
pageId: string; pageId: string;
@ -54,6 +36,24 @@ export class SurveyResponse {
@Column('jsonb') @Column('jsonb')
optionTextAndId: Record<string, any>; optionTextAndId: Record<string, any>;
@Column()
curStatus: {
status: RECORD_STATUS;
date: number;
};
@Column()
statusList: Array<{
status: RECORD_STATUS;
date: number;
}>;
@Column()
createDate: number;
@Column()
updateDate: number;
@BeforeInsert() @BeforeInsert()
initDefaultInfo() { initDefaultInfo() {
const now = Date.now(); const now = Date.now();

View File

@ -61,7 +61,7 @@ describe('SurveyController', () => {
}); });
describe('createSurvey', () => { describe('createSurvey', () => {
it('should create a survey and return the survey ID', async () => { it('should create a survey and return the survey id', async () => {
const surveyInfo = { const surveyInfo = {
surveyType: 'normal', surveyType: 'normal',
remark: '问卷调研', remark: '问卷调研',

View File

@ -13,7 +13,7 @@ import { ResponseSchemaService } from '../../surveyResponse/services/responseSch
import * as Joi from 'joi'; import * as Joi from 'joi';
import { Authtication } from 'src/guards/authtication'; import { Authtication } from 'src/guards/authtication';
import { XiaojuSurveyPluginManager } from 'src/plugins/pluginManager'; import { XiaojuSurveyPluginManager } from 'src/securityPlugin/pluginManager';
@Controller('/api/survey/dataStatistic') @Controller('/api/survey/dataStatistic')
export class DataStatisticController { export class DataStatisticController {

View File

@ -8,7 +8,7 @@ import { NoSurveyPermissionException } from 'src/exceptions/noSurveyPermissionEx
import { HttpException } from 'src/exceptions/httpException'; import { HttpException } from 'src/exceptions/httpException';
import { SurveyNotFoundException } from 'src/exceptions/surveyNotFoundException'; import { SurveyNotFoundException } from 'src/exceptions/surveyNotFoundException';
import { EXCEPTION_CODE } from 'src/enums/exceptionCode'; import { EXCEPTION_CODE } from 'src/enums/exceptionCode';
import { XiaojuSurveyPluginManager } from 'src/plugins/pluginManager'; import { XiaojuSurveyPluginManager } from 'src/securityPlugin/pluginManager';
@Injectable() @Injectable()
export class SurveyMetaService { export class SurveyMetaService {

View File

@ -23,7 +23,7 @@ import { SurveyHistoryService } from './services/surveyHistory.service';
import { SurveyMetaService } from './services/surveyMeta.service'; import { SurveyMetaService } from './services/surveyMeta.service';
import { ContentSecurityService } from './services/contentSecurity.service'; import { ContentSecurityService } from './services/contentSecurity.service';
import { PluginManagerProvider } from 'src/plugins/pluginManager.provider'; import { PluginManagerProvider } from 'src/securityPlugin/pluginManager.provider';
@Module({ @Module({
imports: [ imports: [

View File

@ -17,7 +17,8 @@ export class XiaojuSurveyPluginManager {
async triggerHook(hookName: AllowHooks, data?: any) { async triggerHook(hookName: AllowHooks, data?: any) {
for (const plugin of this.plugins) { for (const plugin of this.plugins) {
if (plugin[hookName]) { if (plugin[hookName]) {
data = await plugin[hookName](data); await plugin[hookName](data);
break;
} }
} }
return data; return data;

View File

@ -26,7 +26,7 @@
import { getSurveyHistory } from '@/management/api/survey'; import { getSurveyHistory } from '@/management/api/survey';
import moment from 'moment'; import moment from 'moment';
// //
import 'moment/locale/zh-cn' import 'moment/locale/zh-cn';
// //
moment.locale('zh-cn'); moment.locale('zh-cn');

View File

@ -1,11 +1,21 @@
<template> <template>
<div class="content"> <div class="content">
<template v-for="btnItem in btnList"> <template v-for="btnItem in btnList">
<router-link class="navbar-btn" :key="btnItem.key" :to="{ name: btnItem.router }" tag="div" replace> <router-link
class="navbar-btn"
:key="btnItem.key"
:to="{ name: btnItem.router }"
tag="div"
replace
>
<i class="iconfont" :class="[btnItem.icon]"></i> <i class="iconfont" :class="[btnItem.icon]"></i>
<span>{{ btnItem.text }}</span> <span>{{ btnItem.text }}</span>
</router-link> </router-link>
<i v-if="btnItem.next" :key="btnItem.key + '-next'" class="iconfont icon-jiantou next"></i> <i
v-if="btnItem.next"
:key="btnItem.key + '-next'"
class="iconfont icon-jiantou next"
></i>
</template> </template>
</div> </div>
</template> </template>

View File

@ -2,4 +2,4 @@
export const QOP_MAP = { export const QOP_MAP = {
COPY: 'copy', COPY: 'copy',
EDIT: 'edit', EDIT: 'edit',
}; };

View File

@ -1,15 +1,18 @@
@import './default.scss'; @import './default.scss';
.isPc .choice-wrapper { .isPc .choice-wrapper {
.choice-box .choice-item { .choice-box .choice-item {
&:hover { &:hover {
background-color: $primary-color-light; background-color: $primary-color-light;
transition: background-color 0.3s ease-in-out; transition: background-color 0.3s ease-in-out;
} }
&:not(:hover) { &:not(:hover) {
background-color: transparent; background-color: transparent;
transition: background-color 0.3s ease-in-out; transition: background-color 0.3s ease-in-out;
} }
} }
.nest-box .choice-outer .choice-item .item-title { .nest-box .choice-outer .choice-item .item-title {
display: none !important; display: none !important;
} }
@ -17,9 +20,11 @@
.choice-wrapper { .choice-wrapper {
font-size: 0; font-size: 0;
.choice-box { .choice-box {
padding: 0 .2rem!important; padding: 0 .2rem !important;
box-sizing: border-box; box-sizing: border-box;
// margin-bottom: -0.22rem; // margin-bottom: -0.22rem;
.choice-item { .choice-item {
position: relative; position: relative;
@ -30,9 +35,10 @@
vertical-align: top; vertical-align: top;
// height: .88rem; // height: .88rem;
line-height: 0.4rem; line-height: 0.4rem;
padding: 0.22rem 0 0.22rem 0.05rem!important; padding: 0.22rem 0 0.22rem 0.05rem !important;
margin-bottom: 0.08rem; margin-bottom: 0.08rem;
cursor: pointer; cursor: pointer;
.item-input { .item-input {
position: relative; position: relative;
vertical-align: top; vertical-align: top;
@ -43,31 +49,37 @@
border-radius: 2px; border-radius: 2px;
background-color: #fff; background-color: #fff;
cursor: pointer; cursor: pointer;
&[type='radio']{
&[type='radio'] {
border-radius: 100%; border-radius: 100%;
} }
&[type='radio']::before{
&[type='radio']::before {
border-radius: 50%; border-radius: 50%;
} }
&.print { &.print {
border-radius: 0; border-radius: 0;
} }
&.print:after { &.print:after {
display: none; display: none;
} }
&:disabled { &:disabled {
border-color: $border-color !important; border-color: $border-color !important;
&::after { &::after {
background: #eee; background: #eee;
} }
& + label {
&+label {
color: #ccc !important; color: #ccc !important;
} }
} }
} }
.item-title { .item-title {
flex: 1; flex: 1;
vertical-align: top; vertical-align: top;
@ -76,10 +88,12 @@
overflow: hidden; overflow: hidden;
word-wrap: break-word; word-wrap: break-word;
cursor: pointer; cursor: pointer;
.label-img-wrapper { .label-img-wrapper {
width: 80%; width: 80%;
text-align: center; text-align: center;
} }
.label-img { .label-img {
display: inline-block !important; display: inline-block !important;
width: 2rem; width: 2rem;
@ -87,6 +101,7 @@
margin-top: 0.25rem; margin-top: 0.25rem;
} }
} }
.center-text { .center-text {
span { span {
display: inline-block; display: inline-block;
@ -94,10 +109,12 @@
text-align: center; text-align: center;
} }
} }
&.is-checked { &.is-checked {
.item-title { .item-title {
color: $primary-color; color: $primary-color;
} }
.qicon.qicon-gouxuan { .qicon.qicon-gouxuan {
display: inline-block; display: inline-block;
font-size: 0.32rem; font-size: 0.32rem;
@ -105,16 +122,19 @@
border-color: $primary-color; border-color: $primary-color;
background-color: $primary-color; background-color: $primary-color;
color: #fff; color: #fff;
border:none border: none
} }
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
} }
&:not(.is-checked) { &:not(.is-checked) {
background-color: transparent; background-color: transparent;
.item-title { .item-title {
color: $font-color; color: $font-color;
} }
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
} }
@ -123,6 +143,7 @@
margin-bottom: 0; margin-bottom: 0;
} }
} }
.option-wrapper { .option-wrapper {
display: flex; display: flex;
// justify-content: center; // justify-content: center;
@ -130,9 +151,11 @@
.vertical { .vertical {
width: 100%; width: 100%;
.item-title .label-img { .item-title .label-img {
width: 75%; width: 75%;
} }
// &.choice-item.last2child { // &.choice-item.last2child {
// margin-bottom: .08rem; // margin-bottom: .08rem;
// } // }
@ -161,97 +184,114 @@
.input-wrapper { .input-wrapper {
font-size: 0; font-size: 0;
.input-box { .input-box {
outline: none; outline: none;
font-size: 0.56rem; font-size: 0.56rem;
padding: 0.4rem; padding: 0.4rem;
border-radius: .08rem; border-radius: .08rem;
background-color: #fff; background-color: #fff;
vertical-align: top; vertical-align: top;
border: 1px solid $border-color; border: 1px solid $border-color;
width: 200%; width: 200%;
height: 1.61rem; height: 1.61rem;
transform: scale(0.5,0.5); transform: scale(0.5, 0.5);
transform-origin: left top; transform-origin: left top;
box-sizing: border-box; box-sizing: border-box;
margin-bottom: -.81rem; margin-bottom: -.81rem;
overflow: hidden; overflow: hidden;
// overflow: hidden; // overflow: hidden;
color: $font-color; color: $font-color;
z-index: 10; z-index: 10;
// &:focus, &.is-focused {
// border: 1px solid $primary-color; // &:focus, &.is-focused {
// } // border: 1px solid $primary-color;
&:not([readonly="readonly"]):hover{ // }
border: 1px solid $primary-color; &:not([readonly="readonly"]):hover {
} border: 1px solid $primary-color;
&.print { }
border: none;
border-bottom: 1px solid $border-color; &.print {
border-radius: 0; border: none;
} border-bottom: 1px solid $border-color;
&::-webkit-input-placeholder { /* WebKit browsers */ border-radius: 0;
font-size: .56rem; }
font-weight: 300;
color: $placeholder-color; &::-webkit-input-placeholder {
} /* WebKit browsers */
&:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ font-size: .56rem;
font-size: .56rem; font-weight: 300;
font-weight: 300; color: $placeholder-color;
color: $placeholder-color; }
}
&::-moz-placeholder { /* Mozilla Firefox 19+ */ &:-moz-placeholder {
font-size: .56rem; /* Mozilla Firefox 4 to 18 */
font-weight: 300; font-size: .56rem;
color: $placeholder-color; font-weight: 300;
} color: $placeholder-color;
&:-ms-input-placeholder { /* Internet Explorer 10+ */ }
font-size: .56rem;
font-weight: 300; &::-moz-placeholder {
color: $placeholder-color; /* Mozilla Firefox 19+ */
} font-size: .56rem;
font-weight: 300;
color: $placeholder-color;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ */
font-size: .56rem;
font-weight: 300;
color: $placeholder-color;
}
} }
.text-number-tip { .text-number-tip {
font-size: .24rem; font-size: .24rem;
color: $font-color; color: $font-color;
float: right; float: right;
margin-right: .1rem; margin-right: .1rem;
margin-top: .1rem; margin-top: .1rem;
} }
input::-webkit-outer-spin-button, input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button { input::-webkit-inner-spin-button {
-webkit-appearance: none !important; -webkit-appearance: none !important;
margin: 0; margin: 0;
} }
input[type="number"] { input[type="number"] {
-moz-appearance: textfield; -moz-appearance: textfield;
} }
} }
.nest-box { .nest-box {
justify-content: space-around; justify-content: space-around;
padding-left: 0 !important; padding-left: 0 !important;
.choice-outer { .choice-outer {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
.choice-item { .choice-item {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
margin-bottom: 0; margin-bottom: 0;
padding-left: 0 !important; padding-left: 0 !important;
.item-input { .item-input {
margin-right: 0; margin-right: 0;
border-radius: 2px; border-radius: 2px;
&.ql-checked-input + .item-title {
&.ql-checked-input+.item-title {
visibility: visible; visibility: visible;
height: auto; height: auto;
opacity: 1; opacity: 1;
} }
} }
.item-title { .item-title {
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
@ -262,6 +302,7 @@
width: 100%; width: 100%;
color: $font-color; color: $font-color;
position: absolute; position: absolute;
.item-title-text { .item-title-text {
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
@ -273,10 +314,12 @@
} }
} }
} }
// &.choice-box { // &.choice-box {
// padding: 0; // padding: 0;
// } // }
} }
// input[type="radio"]{ // input[type="radio"]{
// cursor: pointer; // cursor: pointer;
// // position: relative; // // position: relative;

View File

@ -21,24 +21,24 @@ $font-size: 0.28rem;
$tip-size: 0.22rem; $tip-size: 0.22rem;
.el-radio__input.is-checked+.el-radio__label { .el-radio__input.is-checked+.el-radio__label {
color: $font-color !important; color: $font-color !important;
} }
.el-switch.is-checked .el-switch__core { .el-switch.is-checked .el-switch__core {
border-color: $primary-color !important; border-color: $primary-color !important;
background-color: $primary-color !important; background-color: $primary-color !important;
} }
.el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-checked .el-checkbox__inner,
.question-edit-wrapper .el-checkbox__input.is-indeterminate .el-checkbox__inner { .question-edit-wrapper .el-checkbox__input.is-indeterminate .el-checkbox__inner {
background-color: $primary-color !important; background-color: $primary-color !important;
border-color: $primary-color !important; border-color: $primary-color !important;
} }
.el-checkbox__input.is-focus .el-checkbox__inner { .el-checkbox__input.is-focus .el-checkbox__inner {
border-color: $primary-color !important; border-color: $primary-color !important;
} }
.el-checkbox__input.is-checked+.el-checkbox__label { .el-checkbox__input.is-checked+.el-checkbox__label {
color: $font-color !important; color: $font-color !important;
} }

View File

@ -1,13 +1,17 @@
@import './default.scss'; @import './default.scss';
.question-wrapper { .question-wrapper {
position: relative; position: relative;
&.gap{
&.gap {
padding: 0.2rem 0 0.8rem; padding: 0.2rem 0 0.8rem;
} }
.component-wrapper { .component-wrapper {
padding: 0 0.4rem; padding: 0 0.4rem;
} }
.noPadding{
.noPadding {
padding: 0; padding: 0;
} }
@ -27,49 +31,60 @@
&.question-type-section { &.question-type-section {
padding-bottom: 0; padding-bottom: 0;
.module-title { .module-title {
padding-bottom: 0; padding-bottom: 0;
} }
} }
&.horizon { &.horizon {
display: flex; display: flex;
.module-title .m-title { .module-title .m-title {
width: 1.2rem; width: 1.2rem;
margin-right: 8px; margin-right: 8px;
text-align: justify; text-align: justify;
position: relative; position: relative;
&::before { &::before {
content: ':'; content: ':';
display: block; display: block;
position: absolute; position: absolute;
right: -5px; right: -5px;
} }
&::after { &::after {
content: ''; content: '';
display: inline-block; display: inline-block;
width: 100%; width: 100%;
} }
} }
.component-wrapper { .component-wrapper {
flex: 1; flex: 1;
} }
&.hasError { &.hasError {
margin-bottom: 0.4rem; margin-bottom: 0.4rem;
} }
.module-err-tip { .module-err-tip {
position: absolute; position: absolute;
padding: 0; padding: 0;
margin-top: -5px; margin-top: -5px;
left: 0; left: 0;
.tip-text { .tip-text {
padding-top: 0; padding-top: 0;
} }
} }
} }
&.hasError { &.hasError {
.item-border { .item-border {
border-color: $error-color; border-color: $error-color;
} }
/*由于错误提示可能多行因此有错误时取消margin让错误提示撑开边距*/ /*由于错误提示可能多行因此有错误时取消margin让错误提示撑开边距*/
margin-bottom: 0; margin-bottom: 0;
} }
@ -77,6 +92,7 @@
&.special .module-err-tip { &.special .module-err-tip {
padding: 0.12rem 0.75rem 0; padding: 0.12rem 0.75rem 0;
} }
&.spliter { &.spliter {
border-bottom: 0.12rem solid $spliter-color; border-bottom: 0.12rem solid $spliter-color;
} }
@ -84,6 +100,7 @@
&:last-child { &:last-child {
border-bottom: 0; border-bottom: 0;
} }
.sort-tip { .sort-tip {
font-size: 0.26rem; font-size: 0.26rem;
line-height: 0.26rem; line-height: 0.26rem;
@ -99,6 +116,7 @@
.isPc .question-form-item { .isPc .question-form-item {
border-bottom: none; border-bottom: none;
.sort-tip { .sort-tip {
padding-left: 0; padding-left: 0;
margin-bottom: 0.24rem; margin-bottom: 0.24rem;

View File

@ -1,167 +1,193 @@
@import './default.scss'; @import './default.scss';
.isPc .group-wrapper.group-radio .module-err-tip {
position: relative; .isPc .group-wrapper.group-radio .module-err-tip {
} position: relative;
.isPc .group-wrapper.group-radio .question-form-item { }
margin-bottom: 0;
} .isPc .group-wrapper.group-radio .question-form-item {
margin-bottom: 0;
.isPc .group-wrapper.group-radio { }
.matrix-select-more {
margin-left: 0; .isPc .group-wrapper.group-radio {
.module-err-tip {
left: 0;
}
}
}
.group-wrapper {
width: 100%;
// overflow: hidden;
&::-webkit-scrollbar {
display: block;
height: 10px;
background-color: #F2F4F7;
}
&::-webkit-scrollbar-thumb {
border-radius: 5px;
background: #E3E4E8;
}
&::-webkit-scrollbar-track {
height: 16px;
background: #F2F4F7;
}
.form-item-wrapper {
padding: 0 0 .2rem 0;
box-sizing: border-box;
}
.question-form-item {
padding: .16rem 0 .4rem;
border-bottom: none;
.module-title {
padding: 0 0 .24rem 0.2rem;
font-size: .28rem;
font-weight: 400;
}
.component-wrapper {
padding: 0;
.star-wrapper {
padding: 0 .35rem;
}
.nps-wrapper {
padding: 0;
}
}
&:last-child {
padding-bottom: 0;
}
&.hasError .module-err-tip.show {
padding: 0;
}
}
.box {
display: flex;
}
.group-title.main {
background: #F2F4F7;
padding: 0 ;
min-height: .4rem;
line-height: .4rem;
box-sizing: border-box;
display: flex;
span {
display: inline-block;
box-sizing: border-box;
vertical-align: top;
font-size: .28rem;
color: $title-color;
text-align: center;
line-height: 0.4rem;
// font-weight: 500;
width: 100%;
word-break: break-word;
border-left: 1px dotted rgba(200, 201, 205, 1);
height: auto;
}
& > span:first-child {
border: none;
}
.group-title-text span {
border: none;
}
&>span{
padding: .2rem .1rem;
}
}
&.group-radio {
.module-title {
// color: $font-color;
line-height: .36rem;
}
.question-form-item {
padding: .4rem 0 .4rem 0;
}
.checkbox-wrapper, .radio-wrapper {
.radio-box.nest-box .radio-outer .radio-item {
padding: .22rem 0;
}
}
.module-err-tip {
margin-top: .25rem;
}
}
}
.horizontal {
.group-title {
padding-left: 25%;
}
.question-form-item {
width: 100%;
font-size: 0;
overflow: hidden;
border-bottom: 1px solid #eee;
margin-bottom: .2rem;
padding-top: .2rem;
.module-title {
float: left;
width: 27%;
vertical-align: top;
font-size: .26rem !important;
}
.checkbox-wrapper, .radio-wrapper {
display: inline-block;
width: 70%;
vertical-align: top;
border-bottom: none;
}
}
}
.select-more-label {
display: block;
margin-top: .2rem;
// margin-bottom: -.2rem;
height: .3rem;
line-height: .3rem;
width: 100%;
color: #666;
font-size: .26rem;
}
.matrix-select-more { .matrix-select-more {
max-width: 10rem; margin-left: 0;
.question-form-item {
padding-top: 0px; .module-err-tip {
.m-select-more { left: 0;
margin-top: .3rem; }
margin-bottom: .5rem; }
width: 100% !important; }
.group-wrapper {
width: 100%;
// overflow: hidden;
&::-webkit-scrollbar {
display: block;
height: 10px;
background-color: #F2F4F7;
}
&::-webkit-scrollbar-thumb {
border-radius: 5px;
background: #E3E4E8;
}
&::-webkit-scrollbar-track {
height: 16px;
background: #F2F4F7;
}
.form-item-wrapper {
padding: 0 0 .2rem 0;
box-sizing: border-box;
}
.question-form-item {
padding: .16rem 0 .4rem;
border-bottom: none;
.module-title {
padding: 0 0 .24rem 0.2rem;
font-size: .28rem;
font-weight: 400;
}
.component-wrapper {
padding: 0;
.star-wrapper {
padding: 0 .35rem;
}
.nps-wrapper {
padding: 0;
} }
} }
}
&:last-child {
padding-bottom: 0;
}
&.hasError .module-err-tip.show {
padding: 0;
}
}
.box {
display: flex;
}
.group-title.main {
background: #F2F4F7;
padding: 0;
min-height: .4rem;
line-height: .4rem;
box-sizing: border-box;
display: flex;
span {
display: inline-block;
box-sizing: border-box;
vertical-align: top;
font-size: .28rem;
color: $title-color;
text-align: center;
line-height: 0.4rem;
// font-weight: 500;
width: 100%;
word-break: break-word;
border-left: 1px dotted rgba(200, 201, 205, 1);
height: auto;
}
&>span:first-child {
border: none;
}
.group-title-text span {
border: none;
}
&>span {
padding: .2rem .1rem;
}
}
&.group-radio {
.module-title {
// color: $font-color;
line-height: .36rem;
}
.question-form-item {
padding: .4rem 0 .4rem 0;
}
.checkbox-wrapper,
.radio-wrapper {
.radio-box.nest-box .radio-outer .radio-item {
padding: .22rem 0;
}
}
.module-err-tip {
margin-top: .25rem;
}
}
}
.horizontal {
.group-title {
padding-left: 25%;
}
.question-form-item {
width: 100%;
font-size: 0;
overflow: hidden;
border-bottom: 1px solid #eee;
margin-bottom: .2rem;
padding-top: .2rem;
.module-title {
float: left;
width: 27%;
vertical-align: top;
font-size: .26rem !important;
}
.checkbox-wrapper,
.radio-wrapper {
display: inline-block;
width: 70%;
vertical-align: top;
border-bottom: none;
}
}
}
.select-more-label {
display: block;
margin-top: .2rem;
// margin-bottom: -.2rem;
height: .3rem;
line-height: .3rem;
width: 100%;
color: #666;
font-size: .26rem;
}
.matrix-select-more {
max-width: 10rem;
.question-form-item {
padding-top: 0px;
.m-select-more {
margin-top: .3rem;
margin-bottom: .5rem;
width: 100% !important;
}
}
}

View File

@ -1,8 +1,9 @@
@font-face { @font-face {
font-family: "qicon"; /* Project id 4263885 */ font-family: "qicon";
/* Project id 4263885 */
src: url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.woff2?t=1697079806138') format('woff2'), src: url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.woff2?t=1697079806138') format('woff2'),
url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.woff?t=1697079806138') format('woff'), url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.woff?t=1697079806138') format('woff'),
url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.ttf?t=1697079806138') format('truetype'); url('//at.alicdn.com/t/c/font_4263885_u91txz1d68.ttf?t=1697079806138') format('truetype');
} }
.qicon { .qicon {
@ -35,4 +36,4 @@
.qicon-xingxing:before { .qicon-xingxing:before {
content: "\a6ca"; content: "\a6ca";
} }

View File

@ -1,6 +1,8 @@
@import './default.scss'; @import './default.scss';
.input-wrapper { .input-wrapper {
font-size: 0; font-size: 0;
.input-box { .input-box {
outline: none; outline: none;
font-size: 0.56rem; font-size: 0.56rem;
@ -13,7 +15,7 @@
width: 200%; width: 200%;
height: 1.61rem; height: 1.61rem;
transform: scale(0.5,0.5); transform: scale(0.5, 0.5);
transform-origin: left top; transform-origin: left top;
box-sizing: border-box; box-sizing: border-box;
margin-bottom: -.81rem; margin-bottom: -.81rem;
@ -21,41 +23,53 @@
// overflow: hidden; // overflow: hidden;
color: $font-color; color: $font-color;
z-index: 10; z-index: 10;
&.is-focused:focus { &.is-focused:focus {
border: 1px solid $primary-color; border: 1px solid $primary-color;
height: 3.5rem; height: 3.5rem;
margin-bottom: -1.75rem; margin-bottom: -1.75rem;
overflow-y: scroll; overflow-y: scroll;
} }
&:not([readonly="readonly"]):hover{
&:not([readonly="readonly"]):hover {
border: 1px solid $primary-color; border: 1px solid $primary-color;
} }
&.print { &.print {
border: none; border: none;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
border-radius: 0; border-radius: 0;
} }
&::-webkit-input-placeholder { /* WebKit browsers */
&::-webkit-input-placeholder {
/* WebKit browsers */
font-size: .56rem; font-size: .56rem;
font-weight: 300; font-weight: 300;
color: $placeholder-color; color: $placeholder-color;
} }
&:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
font-size: .56rem; font-size: .56rem;
font-weight: 300; font-weight: 300;
color: $placeholder-color; color: $placeholder-color;
} }
&::-moz-placeholder { /* Mozilla Firefox 19+ */
&::-moz-placeholder {
/* Mozilla Firefox 19+ */
font-size: .56rem; font-size: .56rem;
font-weight: 300; font-weight: 300;
color: $placeholder-color; color: $placeholder-color;
} }
&:-ms-input-placeholder { /* Internet Explorer 10+ */
&:-ms-input-placeholder {
/* Internet Explorer 10+ */
font-size: .56rem; font-size: .56rem;
font-weight: 300; font-weight: 300;
color: $placeholder-color; color: $placeholder-color;
} }
} }
.text-number-tip { .text-number-tip {
font-size: .24rem; font-size: .24rem;
color: $font-color; color: $font-color;
@ -73,7 +87,8 @@
input[type="number"] { input[type="number"] {
-moz-appearance: textfield; -moz-appearance: textfield;
} }
textarea{
textarea {
resize: none; resize: none;
} }
} }

View File

@ -1,4 +1,5 @@
@import './default.scss'; @import './default.scss';
.question { .question {
position: relative; position: relative;
padding: 0.2rem 0 0.3rem; padding: 0.2rem 0 0.3rem;
@ -6,5 +7,4 @@
&-block { &-block {
padding: 0 0.4rem; padding: 0 0.4rem;
} }
} }

View File

@ -1,96 +1,110 @@
@import './default.scss'; @import './default.scss';
.question-form-item { .question-form-item {
position: relative; position: relative;
padding: 0.2rem 0 0.8rem; padding: 0.2rem 0 0.8rem;
.component-wrapper {
padding: 0 0.4rem;
}
.noPadding {
padding: 0;
}
&.no-padding {
.component-wrapper { .component-wrapper {
padding: 0 0.4rem;
}
.noPadding{
padding: 0; padding: 0;
} }
}
&.no-padding {
.component-wrapper { &.no-out-padding {
padding: 0; padding: 0 0 0.2rem;
} }
}
.clear {
&.no-out-padding { clear: both;
padding: 0 0 0.2rem; }
}
&.question-type-section {
.clear { padding-bottom: 0;
clear: both;
} .module-title {
&.question-type-section {
padding-bottom: 0; padding-bottom: 0;
.module-title {
padding-bottom: 0;
}
}
&.horizon {
display: flex;
.module-title .m-title {
width: 1.2rem;
margin-right: 8px;
text-align: justify;
position: relative;
&::before {
content: ':';
display: block;
position: absolute;
right: -5px;
}
&::after {
content: '';
display: inline-block;
width: 100%;
}
}
.component-wrapper {
flex: 1;
}
&.hasError {
margin-bottom: 0.4rem;
}
.module-err-tip {
position: absolute;
padding: 0;
margin-top: -5px;
left: 0;
.tip-text {
padding-top: 0;
}
}
}
&.hasError {
.item-border {
border-color: $error-color;
}
/*由于错误提示可能多行因此有错误时取消margin让错误提示撑开边距*/
margin-bottom: 0;
}
&.special .module-err-tip {
padding: 0.12rem 0.75rem 0;
}
&.spliter {
border-bottom: 0.12rem solid $spliter-color;
}
&:last-child {
border-bottom: 0;
}
.sort-tip {
font-size: 0.26rem;
line-height: 0.26rem;
opacity: 0.5;
margin-top: -0.24rem;
margin-bottom: 0.4rem;
padding-left: 0.4rem;
color: #92949d;
} }
} }
&.horizon {
display: flex;
.module-title .m-title {
width: 1.2rem;
margin-right: 8px;
text-align: justify;
position: relative;
&::before {
content: ':';
display: block;
position: absolute;
right: -5px;
}
&::after {
content: '';
display: inline-block;
width: 100%;
}
}
.component-wrapper {
flex: 1;
}
&.hasError {
margin-bottom: 0.4rem;
}
.module-err-tip {
position: absolute;
padding: 0;
margin-top: -5px;
left: 0;
.tip-text {
padding-top: 0;
}
}
}
&.hasError {
.item-border {
border-color: $error-color;
}
/*由于错误提示可能多行因此有错误时取消margin让错误提示撑开边距*/
margin-bottom: 0;
}
&.special .module-err-tip {
padding: 0.12rem 0.75rem 0;
}
&.spliter {
border-bottom: 0.12rem solid $spliter-color;
}
&:last-child {
border-bottom: 0;
}
.sort-tip {
font-size: 0.26rem;
line-height: 0.26rem;
opacity: 0.5;
margin-top: -0.24rem;
margin-bottom: 0.4rem;
padding-left: 0.4rem;
color: #92949d;
}
}

View File

@ -178,7 +178,7 @@ export default {
for (const i in addOne) { for (const i in addOne) {
if (i === 'others') { if (i === 'others') {
addOne[i] = others; addOne[i] = others;
if(others) addOne.othersKey = `${field}_${addOne.hash}`; if (others) addOne.othersKey = `${field}_${addOne.hash}`;
} else if (i === 'mustOthers') { } else if (i === 'mustOthers') {
addOne[i] = false; addOne[i] = false;
} else if (i === 'text') { } else if (i === 'text') {

View File

@ -1,8 +1,7 @@
<script> <script>
import OptionConfig from '@/materials/questions/components/AdvancedConfig/OptionConfig.vue'; import OptionConfig from '@/materials/questions/components/AdvancedConfig/OptionConfig.vue';
import RateConfig from '../AdvancedConfig/RateConfig.vue'; import RateConfig from '../AdvancedConfig/RateConfig.vue';
import { defineComponent, ref, inject, computed } from 'vue'; import { defineComponent, ref, inject } from 'vue';
import store from '@/management/store';
import ExtraIcon from '@/materials/questions/components/ExtraIcon.vue'; import ExtraIcon from '@/materials/questions/components/ExtraIcon.vue';
export default defineComponent({ export default defineComponent({
@ -11,7 +10,7 @@ export default defineComponent({
props: { props: {
optionList: { optionList: {
type: Array, type: Array,
default: [], default: () => [],
}, },
showOthers: { showOthers: {
type: Boolean, type: Boolean,
@ -29,9 +28,6 @@ export default defineComponent({
setup(props, { emit }) { setup(props, { emit }) {
const moduleConfig = inject('moduleConfig'); const moduleConfig = inject('moduleConfig');
const optionConfigVisible = ref(false); const optionConfigVisible = ref(false);
const currentEditKey = computed(() => {
return store.getters['edit/currentEditKey'];
});
const addOther = () => { const addOther = () => {
emit('addOther'); emit('addOther');
@ -131,18 +127,21 @@ export default defineComponent({
line-height: 24px; line-height: 24px;
font-size: 12px; font-size: 12px;
color: $primary-color; color: $primary-color;
.add-option { .add-option {
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
cursor: pointer; cursor: pointer;
font-size: 12px; font-size: 12px;
} }
.option-advanced-config { .option-advanced-config {
color: #0f8a82; color: #0f8a82;
float: right; float: right;
cursor: pointer; cursor: pointer;
font-size: 12px; font-size: 12px;
} }
.primary-color { .primary-color {
color: $primary-color; color: $primary-color;
} }
@ -155,6 +154,7 @@ export default defineComponent({
letter-spacing: 0; letter-spacing: 0;
text-align: left; text-align: left;
} }
.pop-tip { .pop-tip {
font-family: PingFangSC-Regular; font-family: PingFangSC-Regular;
font-size: 12px; font-size: 12px;
@ -162,6 +162,7 @@ export default defineComponent({
letter-spacing: 0.65px; letter-spacing: 0.65px;
text-align: left; text-align: left;
} }
.pop-input { .pop-input {
margin-top: 6px; margin-top: 6px;
margin-bottom: 16px; margin-bottom: 16px;

View File

@ -26,13 +26,13 @@ function useOptionBase(options) {
if (typeof text !== 'string') { if (typeof text !== 'string') {
text = '选项'; text = '选项';
} }
const getHash = new GetHash(); const getHash = new GetHash();
addOne.hash = getHash.getHash(); addOne.hash = getHash.getHash();
for (const i in addOne) { for (const i in addOne) {
if (i === 'others') { if (i === 'others') {
addOne[i] = others; addOne[i] = others;
if(others) addOne.othersKey = `${field}_${addOne.hash}`; if (others) addOne.othersKey = `${field}_${addOne.hash}`;
} else if (i === 'mustOthers') { } else if (i === 'mustOthers') {
addOne[i] = false; addOne[i] = false;
} else if (i === 'text') { } else if (i === 'text') {

View File

@ -71,11 +71,14 @@ export default {
return max(this.moduleConfig); return max(this.moduleConfig);
} }
return Number(max); return Number(max);
} else if (min !== undefined && Array.isArray(this.moduleConfig?.options)) { } else if (
min !== undefined &&
Array.isArray(this.moduleConfig?.options)
) {
// inputNumber checkbox, vote, matrix-checkbox, // inputNumber checkbox, vote, matrix-checkbox,
return this.moduleConfig.options.length; return this.moduleConfig.options.length;
} else { } else {
return Infinity return Infinity;
} }
}, },
}, },

View File

@ -23,7 +23,7 @@
// elementformatmomentformatD // elementformatmomentformatD
import moment from 'moment'; import moment from 'moment';
// //
import 'moment/locale/zh-cn' import 'moment/locale/zh-cn';
// //
moment.locale('zh-cn'); moment.locale('zh-cn');
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'; import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant';

View File

@ -15,7 +15,7 @@
<script> <script>
import moment from 'moment'; import moment from 'moment';
// //
import 'moment/locale/zh-cn' import 'moment/locale/zh-cn';
// //
moment.locale('zh-cn'); moment.locale('zh-cn');
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'; import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant';