feat: 添加分页组件和配置
- 新增 PageConfig 组件用于分页设置 - 新增 Paging 组件用于显示分页信息 - 添加自定义样式和布局
This commit is contained in:
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
||||
/src/fonts
|
||||
/public
|
||||
|
||||
50
.eslintrc.cjs
Normal file
50
.eslintrc.cjs
Normal file
@@ -0,0 +1,50 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
plugins: ['vue'],
|
||||
extends: ['plugin:vue/vue3-essential'],
|
||||
parserOptions: {
|
||||
parser: '@babel/eslint-parser'
|
||||
},
|
||||
rules: {
|
||||
'global-require': 0,
|
||||
'import/prefer-default-export': 0,
|
||||
'no-console': 0,
|
||||
'vue/no-deprecated-slot-attribute': 0,
|
||||
'no-plusplus': 0,
|
||||
'no-param-reassign': 0,
|
||||
'vue/no-use-v-if-with-v-for': 0,
|
||||
'max-len': [
|
||||
'error',
|
||||
{
|
||||
code: 120,
|
||||
tabWidth: 2,
|
||||
ignoreStrings: true,
|
||||
ignoreUrls: true,
|
||||
ignoreRegExpLiterals: true,
|
||||
ignoreTemplateLiterals: true
|
||||
}
|
||||
],
|
||||
'import/extensions': 0,
|
||||
eqeqeq: 0,
|
||||
'vue/no-deprecated-slot-scope-attribute': 0,
|
||||
'no-underscore-dangle': 0,
|
||||
'consistent-return': 0,
|
||||
'linebreak-style': [0, 'error', 'windows'],
|
||||
'vue/no-parsing-error': 0,
|
||||
'vue/multi-word-component-names': 0,
|
||||
'vue/custom-event-name-casing': 0,
|
||||
'vue/no-ref-as-operand': 0,
|
||||
'operator-linebreak': ['error', 'before', { overrides: { '=': 'none' } }]
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
|
||||
env: {
|
||||
mocha: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
8
.prettierrc.json
Normal file
8
.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": true,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
4
auto-imports.d.ts
vendored
4
auto-imports.d.ts
vendored
@@ -5,6 +5,4 @@
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
declare global {
|
||||
|
||||
}
|
||||
declare global {}
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -17,7 +17,8 @@
|
||||
"uuid": "^11.1.0",
|
||||
"vant": "^4.9.17",
|
||||
"vue": "^3.4.29",
|
||||
"vue-router": "^4.3.3"
|
||||
"vue-router": "^4.3.3",
|
||||
"vuex": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
@@ -10510,6 +10511,17 @@
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vuex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz",
|
||||
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-virtual-modules": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
"uuid": "^11.1.0",
|
||||
"vant": "^4.9.17",
|
||||
"vue": "^3.4.29",
|
||||
"vue-router": "^4.3.3"
|
||||
"vue-router": "^4.3.3",
|
||||
"vuex": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
|
||||
@@ -41,12 +41,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
* {
|
||||
/* box-sizing: border-box; */
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
|
||||
/* font-weight: normal; */
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -74,4 +73,8 @@ body {
|
||||
text-rendering: optimizelegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
& div {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@import './base.css';
|
||||
@import '../font/iconfont.css';
|
||||
@import '../fonts/iconfont.css';
|
||||
|
||||
|
||||
a,
|
||||
.green {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { RouterView } from 'vue-router';
|
||||
<style scoped lang="scss">
|
||||
|
||||
.common-layout {
|
||||
height: calc(100vh);
|
||||
min-height: calc(100vh);
|
||||
background-color: #E9EEF3;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
44
src/style/box.scss
Normal file
44
src/style/box.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-start,
|
||||
.flex.flex-start {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.flex-end,
|
||||
.flex.flex-end {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.flex-auto {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.flex-none {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.full-size {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
36
src/style/config/common.scss
Normal file
36
src/style/config/common.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
.quiz-config-content {
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.text {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-none {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.w138 {
|
||||
width: 138px;
|
||||
}
|
||||
|
||||
.w125 {
|
||||
width: 125px;
|
||||
}
|
||||
|
||||
.w56 {
|
||||
width: 56px;
|
||||
}
|
||||
155
src/style/customize/button.scss
Normal file
155
src/style/customize/button.scss
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* 自定义按钮样式,为 a-button 添加 custom-button 类,并传入相应的 type,size,disabled
|
||||
* 默认尺寸按钮:size="default" 大尺寸按钮:size="large"
|
||||
* 置灰状态按钮:disabled
|
||||
* 无边框按钮: type="text" class="custom-button"
|
||||
* 灰色边框按钮: type="default" class="custom-button"
|
||||
* 蓝色边框按钮: type="default" class="custom-button btn-outline"
|
||||
* 蓝色背景按钮: type="primary" class="custom-button"
|
||||
*/
|
||||
.custom-modal .ant-modal-footer .ant-btn,
|
||||
.custom-button,
|
||||
.ant-btn.custom-button {
|
||||
padding-right: 20px;
|
||||
padding-left: 20px;
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0;
|
||||
word-spacing: 0;
|
||||
|
||||
//font-family: PingFangSC-Regular, PingFang SC, sans-serif;
|
||||
cursor: pointer;
|
||||
|
||||
&.ant-btn-default {
|
||||
&:not([disabled]) {
|
||||
border-color: #d9d9d9;
|
||||
color: #262626;
|
||||
|
||||
svg path {
|
||||
fill: #262626;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $yili-default-color;
|
||||
color: $yili-default-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-default-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
border-color: #d9d9d9;
|
||||
background-color: #fff;
|
||||
color: #bfbfbf;
|
||||
|
||||
svg path {
|
||||
fill: #bfbfbf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-outline {
|
||||
&:not([disabled]) {
|
||||
border-color: $yili-btn-check-color;
|
||||
color: $yili-default-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-default-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $yili-btn-check-color;
|
||||
color: $yili-btn-check-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-btn-check-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
border-color: $yili-disabled-color;
|
||||
background-color: #fff;
|
||||
color: $yili-disabled-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-disabled-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-btn-primary {
|
||||
&:not([disabled]) {
|
||||
border-color: $yili-default-color;
|
||||
background-color: $yili-default-color;
|
||||
|
||||
svg path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $yili-btn-check-color;
|
||||
background-color: $yili-btn-check-color;
|
||||
|
||||
svg path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
border-color: $yili-disabled-color;
|
||||
background-color: $yili-disabled-color;
|
||||
color: #fff;
|
||||
|
||||
svg path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-btn-text {
|
||||
&:not([disabled]) {
|
||||
color: $yili-default-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-default-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #fff;
|
||||
color: $yili-btn-check-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-btn-check-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
color: $yili-disabled-color;
|
||||
|
||||
svg path {
|
||||
fill: $yili-disabled-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-btn-link {
|
||||
color: $yili-default-color;
|
||||
}
|
||||
|
||||
&.ant-btn-lg {
|
||||
height: 42px;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:not(.ant-btn-lg) ::v-deep {
|
||||
> .anticon + span,
|
||||
> span + .anticon {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
src/style/customize/checkbox.scss
Normal file
96
src/style/customize/checkbox.scss
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* 自定义 checkbox 样式,为 a-checkbox 添加类
|
||||
* 小尺寸:custom-checkbox
|
||||
* 大尺寸:custom-checkbox-large
|
||||
*
|
||||
* 自定义 checkbox-group 样式,为 a-checkbox-group 添加类
|
||||
* 小尺寸:custom-checkbox-group
|
||||
* 大尺寸:custom-checkbox-group-large
|
||||
*/
|
||||
.custom-checkbox-group .ant-checkbox-wrapper,
|
||||
.custom-checkbox {
|
||||
.ant-checkbox,
|
||||
.ant-checkbox-input,
|
||||
.ant-checkbox-inner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-checkbox + span {
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
&.ant-checkbox-wrapper-disabled {
|
||||
.ant-checkbox-checked.ant-checkbox-disabled {
|
||||
.ant-checkbox-inner {
|
||||
background-color: #d9d9d9;
|
||||
|
||||
&::after {
|
||||
border-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-checkbox-checked {
|
||||
&::after {
|
||||
border-color: $yili-default-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-checkbox-inner {
|
||||
border-color: $yili-default-color;
|
||||
background-color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-checkbox-group-large .ant-checkbox-wrapper,
|
||||
.custom-checkbox-large {
|
||||
.ant-checkbox,
|
||||
.ant-checkbox-input,
|
||||
.ant-checkbox-inner {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.ant-checkbox + span {
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
&.ant-checkbox-wrapper-disabled {
|
||||
.ant-checkbox-checked.ant-checkbox-disabled {
|
||||
.ant-checkbox-inner {
|
||||
background-color: #d9d9d9;
|
||||
|
||||
&::after {
|
||||
border-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-checkbox-checked {
|
||||
&::after {
|
||||
border-color: $yili-default-color;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.ant-checkbox-inner {
|
||||
border-color: $yili-default-color;
|
||||
background-color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-checkbox-inner {
|
||||
&::after {
|
||||
top: 47%;
|
||||
left: 26%;
|
||||
width: 6.5px;
|
||||
height: 10.1px;
|
||||
border-width: 3px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/style/customize/date-picker.scss
Normal file
17
src/style/customize/date-picker.scss
Normal file
@@ -0,0 +1,17 @@
|
||||
.custom-date-picker.ant-calendar-picker {
|
||||
.ant-calendar-picker-input {
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
|
||||
&[disabled] {
|
||||
color: #8c8c8c;
|
||||
|
||||
&::placeholder {
|
||||
color: #bfbfbf;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/style/customize/form.scss
Normal file
33
src/style/customize/form.scss
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 自定义 form 表单样式,为 a-form 添加类 custom-form
|
||||
* 自定义 form-item 样式,为 a-form-item 添加 custom-form 类
|
||||
*/
|
||||
.custom-form {
|
||||
&.ant-form-vertical .ant-form-item-label {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-form .ant-form-item,
|
||||
.custom-form-item.ant-form-item {
|
||||
.ant-form-item-label {
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.ant-form-item-no-colon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
&.ant-form-item-has-error {
|
||||
.ant-input,
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-input:hover,
|
||||
.ant-input-affix-wrapper:hover {
|
||||
border-color: #ff374f;
|
||||
}
|
||||
|
||||
.ant-form-item-explain.ant-form-item-explain-error {
|
||||
color: #ff374f;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/style/customize/index.scss
Normal file
11
src/style/customize/index.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
@import './button';
|
||||
@import './input';
|
||||
@import './form';
|
||||
@import './select';
|
||||
@import './checkbox';
|
||||
@import './radio';
|
||||
@import './switch';
|
||||
@import './modal';
|
||||
@import './date-picker';
|
||||
@import './rate';
|
||||
@import './tinymce';
|
||||
198
src/style/customize/input.scss
Normal file
198
src/style/customize/input.scss
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* 自定义 input 样式,为 a-input 添加 custom-input 类
|
||||
*/
|
||||
.custom-form .ant-form-item .ant-input,
|
||||
.custom-form-item.ant-form-item .ant-input,
|
||||
.custom-form .ant-form-item .ant-input-affix-wrapper,
|
||||
.custom-form-item.ant-form-item .ant-input-affix-wrapper,
|
||||
.custom-form .ant-form-item .ant-input-group-wrapper,
|
||||
.custom-form-item.ant-form-item .ant-input-group-wrapper,
|
||||
.custom-input {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
font-family: PingFangSC-Regular, 'PingFang SC', sans-serif;
|
||||
|
||||
&:not(.ant-input-group-wrapper) {
|
||||
padding-right: 12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
&.ant-input-affix-wrapper .ant-input {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
border-radius: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* <=1024的设备 */
|
||||
@media (max-width: 1024px) {
|
||||
&.ant-input-affix-wrapper .ant-input {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
border-radius: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* <=600的设备 */
|
||||
@media (max-width: 600px) {
|
||||
&.ant-input-affix-wrapper .ant-input {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
border-radius: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用输入框
|
||||
*/
|
||||
&.ant-input.ant-input-disabled,
|
||||
.ant-input.ant-input-disabled {
|
||||
&[disabled] {
|
||||
color: #8c8c8c;
|
||||
font-size: 16px;
|
||||
|
||||
&::placeholder {
|
||||
color: #bfbfbf;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 最简输入框
|
||||
*/
|
||||
&.ant-input {
|
||||
border-color: #dfe0e3;
|
||||
border-radius: 4px;
|
||||
color: #262626;
|
||||
|
||||
&:focus {
|
||||
border-color: $yili-default-color;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 带清除按钮
|
||||
*/
|
||||
&.ant-input-affix-wrapper {
|
||||
border-color: #dfe0e3;
|
||||
border-radius: 4px;
|
||||
color: #262626;
|
||||
|
||||
&.ant-input-affix-wrapper-focused {
|
||||
border-color: $yili-default-color;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 带有 addon-before addon-after 的 input
|
||||
*/
|
||||
&.ant-input-group-wrapper {
|
||||
.ant-input-group-addon {
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.ant-input + .ant-input-group-addon,
|
||||
.ant-input-affix-wrapper + .ant-input-group-addon {
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.ant-input,
|
||||
.ant-input-affix-wrapper {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
*:last-child {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 input-number 样式,为 a-input-number 添加 custom-input-number 类
|
||||
*/
|
||||
.custom-form .ant-form-item .ant-input-number,
|
||||
.custom-form-item.ant-form-item .ant-input-number,
|
||||
.custom-input-number.ant-input-number {
|
||||
border-color: #dfe0e3;
|
||||
border-radius: 4px;
|
||||
color: #262626;
|
||||
|
||||
&.ant-input-number-focused {
|
||||
border-color: $yili-default-color;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ant-input-number-handler-wrap {
|
||||
width: 18px;
|
||||
height: 22px;
|
||||
border: none;
|
||||
opacity: 1;
|
||||
transform: translate(-6px, 4px);
|
||||
}
|
||||
|
||||
.ant-input-number-handler,
|
||||
.ant-input-number-handler-up,
|
||||
.ant-input-number-handler-down {
|
||||
position: relative;
|
||||
height: 50% !important;
|
||||
border-color: transparent;
|
||||
|
||||
.anticon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
width: 6px;
|
||||
height: 5px;
|
||||
margin: 0;
|
||||
background-position: center center;
|
||||
background-size: 6px 5px;
|
||||
background-repeat: no-repeat;
|
||||
transform: translate(0);
|
||||
}
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-number-handler-up {
|
||||
.ant-input-number-handler-up-inner {
|
||||
top: unset;
|
||||
bottom: 1px;
|
||||
background-image: url('~@/assets/img/customize/num_up.png');
|
||||
|
||||
&:hover {
|
||||
background-image: url('~@/assets/img/customize/num_up_hover.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-number-handler-down {
|
||||
.ant-input-number-handler-down-inner {
|
||||
top: 1px;
|
||||
bottom: unset;
|
||||
background-image: url('~@/assets/img/customize/num_down.png');
|
||||
|
||||
&:hover {
|
||||
background-image: url('~@/assets/img/customize/num_down_hover.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-form .ant-form-item textarea.ant-input,
|
||||
.custom-form-item.ant-form-item textarea.ant-input,
|
||||
textarea.custom-textarea.ant-input {
|
||||
&[no-resize] {
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
124
src/style/customize/modal.scss
Normal file
124
src/style/customize/modal.scss
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* 自定义 modal 样式,为 a-modal 添加 wrapClassName 属性值 custom-modal
|
||||
* 通知图标:添加 wrapClassName 属性值 custom-modal-title-notice
|
||||
* 下载图标:添加 wrapClassName 属性值 custom-modal-title-download
|
||||
*/
|
||||
.custom-modal {
|
||||
//font-family: PingFangSC-Semibold, PingFang SC, sans-serif;
|
||||
|
||||
&.custom-modal-title-notice,
|
||||
&.custom-modal-title-confirm-notice,
|
||||
&.custom-modal-title-download {
|
||||
.ant-modal-header,
|
||||
.ant-modal-confirm-title {
|
||||
&::before {
|
||||
content: '';
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
background-position: center center;
|
||||
background-size: 24px 24px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal-confirm-title::before {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&.custom-modal-title-download .ant-modal-header::before {
|
||||
background-image: url('~@/assets/img/customize/title_download.png');
|
||||
}
|
||||
|
||||
&.custom-modal-title-notice .ant-modal-header::before,
|
||||
&.custom-modal-title-notice .ant-modal-confirm-title::before,
|
||||
&.custom-modal-title-confirm-notice .ant-modal-confirm-title::before {
|
||||
background-image: url('~@/assets/img/customize/title_notice.png');
|
||||
}
|
||||
|
||||
&.custom-modal-title-notice .ant-modal-confirm-title,
|
||||
&.custom-modal-title-confirm-notice .ant-modal-confirm-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
&.hide-ant-icon .ant-modal-confirm-body span.anticon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-content {
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.2);
|
||||
|
||||
.ant-btn {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&.custom-modal-title-notice .ant-modal-confirm-body {
|
||||
span.anticon.anticon-info-circle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal-confirm-content {
|
||||
padding-left: 38px;
|
||||
}
|
||||
|
||||
span + span + .ant-modal-confirm-content {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.ant-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 32px 32px 0;
|
||||
border-bottom: none;
|
||||
color: #262626;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ant-modal-footer {
|
||||
padding: 0 32px 24px;
|
||||
border-top: none;
|
||||
|
||||
.ant-btn {
|
||||
margin-left: 12px;
|
||||
padding-right: 14px;
|
||||
letter-spacing: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal-body {
|
||||
overflow-y: auto;
|
||||
max-height: 60vh;
|
||||
padding-right: 32px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
&.custom-modal-height-70vh .ant-modal-body {
|
||||
max-height: 70vh;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全屏 modal 样式,为 a-modal 添加 wrapClassName 属性值 fullscreen-modal
|
||||
*/
|
||||
.fullscreen-modal {
|
||||
overflow: hidden !important;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
.ant-modal-body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
91
src/style/customize/radio.scss
Normal file
91
src/style/customize/radio.scss
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 自定义 radio 样式,为 a-checkbox 添加类
|
||||
* 小尺寸:custom-radio
|
||||
* 大尺寸:custom-radio-large
|
||||
*
|
||||
* 自定义 radio-group 样式,为 a-radio-group 添加类
|
||||
* 小尺寸:custom-radio-group
|
||||
* 大尺寸:custom-radio-group-large
|
||||
*/
|
||||
.custom-radio-group .ant-radio-wrapper,
|
||||
.custom-radio {
|
||||
.ant-radio,
|
||||
.ant-radio-input,
|
||||
.ant-radio-inner {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.ant-radio + span {
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
&.ant-radio-wrapper-disabled {
|
||||
.ant-radio-checked.ant-radio-disabled {
|
||||
.ant-radio-inner {
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-radio-checked {
|
||||
.ant-radio-inner {
|
||||
border-color: $yili-btn-border-color;
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
border-color: $yili-default-color;
|
||||
background-color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-radio-group-large .ant-radio-wrapper,
|
||||
.custom-radio-large {
|
||||
.ant-radio,
|
||||
.ant-radio-input,
|
||||
.ant-radio-inner {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.ant-radio + span {
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
&.ant-radio-wrapper-disabled {
|
||||
.ant-radio-checked.ant-radio-disabled {
|
||||
.ant-radio-inner {
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-radio-checked {
|
||||
.ant-radio-inner {
|
||||
border-color: $yili-btn-border-color;
|
||||
background-color: #fff;
|
||||
|
||||
&::after {
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-color: $yili-default-color;
|
||||
border-radius: 14px;
|
||||
background-color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/style/customize/rate.scss
Normal file
35
src/style/customize/rate.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
.custom-rate.ant-rate {
|
||||
text-align: left;
|
||||
|
||||
.ant-rate-star {
|
||||
.ant-rate-star-first,
|
||||
.ant-rate-star-second {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 21px;
|
||||
}
|
||||
|
||||
.icon.iconfont {
|
||||
font-size: 23px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-rate-mob.ant-rate {
|
||||
.ant-rate-star {
|
||||
.ant-rate-star-first,
|
||||
.ant-rate-star-second {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.icon.iconfont {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
100
src/style/customize/select.scss
Normal file
100
src/style/customize/select.scss
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 自定义 select 样式,为 a-select 添加 custom-select 类
|
||||
*/
|
||||
.custom-form .ant-form-item .ant-select,
|
||||
.custom-form-item.ant-form-item .ant-select,
|
||||
.custom-select {
|
||||
border-radius: 4px;
|
||||
|
||||
&.ant-select .ant-select-selector {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
&.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) .ant-select-selector {
|
||||
border-color: $yili-default-color;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&.ant-select:not(.ant-select-customize-input) .ant-select-selector {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-select-arrow .ant-select-suffix {
|
||||
&::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 10px;
|
||||
background-image: url('~@/assets/img/customize/arrow_down_black.png');
|
||||
background-position: center center;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-select-disabled {
|
||||
.ant-select-selection-placeholder {
|
||||
color: #bfbfbf;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.ant-select-arrow .ant-select-suffix {
|
||||
&::after {
|
||||
background-image: url('~@/assets/img/customize/arrow_down_gray.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 多选
|
||||
*/
|
||||
.ant-select-selection-overflow-item .ant-select-selection-item {
|
||||
border-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
|
||||
.ant-select-selection-item-content {
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.ant-select-selection-item-remove {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.anticon-close {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 12px;
|
||||
background-color: #bfbfbf;
|
||||
line-height: normal;
|
||||
|
||||
svg {
|
||||
font-size: 7px;
|
||||
|
||||
path {
|
||||
fill: #f0f0f0;
|
||||
stroke: #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #8c8c8c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/style/customize/switch.scss
Normal file
30
src/style/customize/switch.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 自定义 switch 样式,为 a-switch 添加 custom-switch 类
|
||||
*/
|
||||
.custom-form .ant-form-item .ant-switch,
|
||||
.custom-form-item.ant-form-item .ant-switch,
|
||||
.custom-switch.ant-switch {
|
||||
width: 38px;
|
||||
min-width: 38px;
|
||||
height: 20px;
|
||||
background-color: #bfbfbf;
|
||||
line-height: 18px;
|
||||
opacity: 1;
|
||||
|
||||
&.ant-switch-checked {
|
||||
background-color: $yili-default-color;
|
||||
|
||||
&.ant-switch-disabled {
|
||||
background-color: #d5ebc3;
|
||||
}
|
||||
}
|
||||
|
||||
&.ant-switch-disabled {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
82
src/style/customize/tinymce.scss
Normal file
82
src/style/customize/tinymce.scss
Normal file
@@ -0,0 +1,82 @@
|
||||
.tox .tox-edit-area__iframe {
|
||||
background: #f5f5f5 !important;
|
||||
}
|
||||
|
||||
.tox .tox-edit-area {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.tox-silver-sink .tox-pop__dialog {
|
||||
border: none !important;
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--top::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--top::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--left::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--left::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--right::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--right::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--bottom::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox .tox-pop.tox-pop--bottom::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tox.tox-tbtn:focus {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:hover {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:hover svg {
|
||||
fill: $yili-default-color !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:active {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:active svg {
|
||||
fill: $yili-default-color !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn--enabled,
|
||||
.tox .tox-tbtn--enabled:hover {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn--enabled svg,
|
||||
.tox .tox-tbtn--enabled:hover svg {
|
||||
fill: $yili-default-color !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:focus:not(.tox-tbtn--disabled) {
|
||||
color: #222f3e !important;
|
||||
}
|
||||
|
||||
.tox .tox-tbtn:focus:not(.tox-tbtn--disabled) svg {
|
||||
fill: $yili-default-color !important;
|
||||
}
|
||||
54
src/style/font.scss
Normal file
54
src/style/font.scss
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
.fs-8 {
|
||||
font-size: 8px !important;
|
||||
}
|
||||
|
||||
.fs-10 {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
.fs-12 {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.fs-14 {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.fs-16 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
|
||||
.fw-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fw-bolder {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.fw-400 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.fw-500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fw-600 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fw-700 {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.fw-800 {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.fw-900 {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
44
src/style/scroller.scss
Normal file
44
src/style/scroller.scss
Normal file
@@ -0,0 +1,44 @@
|
||||
.scroller-x {
|
||||
overflow-x: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d8d8d8;
|
||||
}
|
||||
}
|
||||
|
||||
.scroller-y {
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d8d8d8;
|
||||
}
|
||||
}
|
||||
|
||||
.scroller-xy {
|
||||
overflow: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background-color: #d8d8d8;
|
||||
}
|
||||
}
|
||||
23
src/style/utils.scss
Normal file
23
src/style/utils.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
|
||||
覆盖全局样式
|
||||
|
||||
*/
|
||||
@import './box';
|
||||
|
||||
.ant-select-item-option-selected {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.ant-select-selector {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-select-dropdown.ant-select-dropdown-placement-bottomLeft {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ant-table-column-sorter {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
5
src/style/whole/whole.scss
Normal file
5
src/style/whole/whole.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
$yili-default-color: #70b936;
|
||||
$yili-disabled-color: rgba(112, 185, 54, 0.3);
|
||||
$yili-btn-check-color: #8ec75a;
|
||||
$yili-btn-border-color: #74dd1d;
|
||||
$yili-bkg-color: rgba(112, 185, 54, 0.11);
|
||||
@@ -10,11 +10,22 @@
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<choose-question
|
||||
:element="element" :index="index" :chooseQuestionId="chooseQuestionId"
|
||||
:element="element"
|
||||
:index="index"
|
||||
:chooseQuestionId="chooseQuestionId"
|
||||
@get-choose-question-id="getChooseQuestionId"
|
||||
>
|
||||
<base-select v-if="element.question_type === 1" :element="element"></base-select>
|
||||
</choose-question>
|
||||
<!-- {{ element.question_type }}-->
|
||||
<!-- {{questionInfo.survey.pages.length}}-->
|
||||
<paging
|
||||
v-if="!element.question_type && questionInfo.survey.pages.length > 1"
|
||||
:info="element"
|
||||
:index="index"
|
||||
:active="pageIsActive(activeIndex, questionInfo.questions, element.page)"
|
||||
@click.stop=""
|
||||
/>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
@@ -37,9 +48,58 @@ const BaseSelect = defineAsyncComponent(() => {
|
||||
const ChooseQuestion = defineAsyncComponent(() => {
|
||||
return import('./components/ChooseQuestion.vue');
|
||||
});
|
||||
const questionInfo = ref({ questions: [] });
|
||||
const chooseQuestionId = ref('');
|
||||
const Paging = defineAsyncComponent(() => {
|
||||
return import('./components/Questions/paging/Paging.vue');
|
||||
});
|
||||
|
||||
const chooseQuestionId = ref('');
|
||||
const questionInfo = ref(storeToRefs(counterStore).questionsInfo);
|
||||
/**
|
||||
* 工具函数
|
||||
*/
|
||||
function util() {
|
||||
/** 通过id找到数组中对应的下标 */
|
||||
const getIndexById = (arr, id) => arr.findIndex((i) => i.id === id);
|
||||
/** 通过分页找到数组中对应的下标 */
|
||||
const getIndexByPage = (arr, page) => arr.findIndex((i) => i.page === page);
|
||||
const quesIsActive = (activeIndex, questionList, eleId) => {
|
||||
return activeIndex === getIndexById(questionList, eleId);
|
||||
};
|
||||
const pageIsActive = (activeIndex, questionList, elePage) => {
|
||||
return activeIndex === getIndexByPage(questionList, elePage);
|
||||
};
|
||||
const quesIsDisabled = (questionIndex, disabledQuestionIndex) => {
|
||||
return (disabledQuestionIndex || []).includes(questionIndex);
|
||||
};
|
||||
const pagingDisabled = (index, question, disabledQuestionIndex) => {
|
||||
if (disabledQuestionIndex.includes(question?.[index - 1]?.questionIndex)) {
|
||||
return true;
|
||||
}
|
||||
for (let i = 1; i < question.length - 1; i++) {
|
||||
if (question?.[index + i]?.page) {
|
||||
continue;
|
||||
}
|
||||
if (disabledQuestionIndex.includes(question?.[index + i]?.questionIndex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/** 工具函数,复制store中的数据,避免直接更改store */
|
||||
const copyStoreContent = (store) => {
|
||||
return JSON.parse(JSON.stringify(store.state.common));
|
||||
};
|
||||
return {
|
||||
getIndexById,
|
||||
getIndexByPage,
|
||||
quesIsActive,
|
||||
pageIsActive,
|
||||
quesIsDisabled,
|
||||
pagingDisabled,
|
||||
copyStoreContent
|
||||
};
|
||||
}
|
||||
const { pageIsActive } = util();
|
||||
// 获取选中的题目的ID
|
||||
const getChooseQuestionId = (questionItem) => {
|
||||
chooseQuestionId.value = questionItem.id;
|
||||
@@ -47,8 +107,5 @@ const getChooseQuestionId = (questionItem) => {
|
||||
onMounted(() => {
|
||||
questionInfo.value = store.questionsInfo.value;
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<template>
|
||||
<div class="choose-question-container">
|
||||
<div :class="chooseQuestionId===element.id ? 'choose-question-active':''" @click="chooseItem">
|
||||
<div
|
||||
class="choose-question-context"
|
||||
:class="chooseQuestionId === element.id ? 'choose-question-active' : ''"
|
||||
@click="chooseItem"
|
||||
>
|
||||
<slot></slot>
|
||||
<!-- 题目操作-->
|
||||
<div v-if="chooseQuestionId===element.id" class="choose-question-active-container">
|
||||
<div v-for="item in questionAction" :key="item.key" class="" :class="item.class?item.class:''" @click="itemAction(item)">
|
||||
<div v-if="chooseQuestionId === element.id" class="choose-question-active-container">
|
||||
<div
|
||||
v-for="item in questionAction"
|
||||
:key="item.key"
|
||||
class=""
|
||||
:class="item.class ? item.class : ''"
|
||||
@click="itemAction(item)"
|
||||
>
|
||||
<i class="icon iconfont choose-question-active-container-icon" v-html="item.icon"></i>
|
||||
<div class="choose-question-active-container-name">
|
||||
{{ item.name }}
|
||||
@@ -79,24 +89,28 @@ const chooseItem = () => {
|
||||
|
||||
const itemAction = (item) => {
|
||||
switch (item.key) {
|
||||
case 'edit':
|
||||
break;
|
||||
case 'copy':
|
||||
break;
|
||||
case 'moveUp':
|
||||
break;
|
||||
case 'moveDown':
|
||||
break;
|
||||
case 'delete':
|
||||
break;
|
||||
case 'edit':
|
||||
break;
|
||||
case 'copy':
|
||||
break;
|
||||
case 'moveUp':
|
||||
break;
|
||||
case 'moveDown':
|
||||
break;
|
||||
case 'delete':
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.choose-question-container {
|
||||
padding: 5px;
|
||||
|
||||
& .choose-question-context {
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
& .choose-question-active {
|
||||
outline: 1px dashed #409eff;
|
||||
}
|
||||
@@ -118,5 +132,4 @@ const itemAction = (item) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
<van-field
|
||||
v-model="element.stem"
|
||||
:label="element.stem"
|
||||
:required="element.config.is_required=== 1"
|
||||
:required="element.config.is_required === 1"
|
||||
label-align="top"
|
||||
>
|
||||
<template #label>
|
||||
<div v-html="element.stem"></div>
|
||||
</template>
|
||||
<template #input>
|
||||
<van-checkbox-group>
|
||||
<template v-for="item in element.options">
|
||||
@@ -40,6 +43,4 @@ const props = defineProps({
|
||||
});
|
||||
const element = ref(props.element);
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
195
src/views/Design/components/Questions/paging/PageConfig.vue
Normal file
195
src/views/Design/components/Questions/paging/PageConfig.vue
Normal file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div>
|
||||
<ConfigTitle title="分页设置" :quiz-index="quizIndex" />
|
||||
|
||||
<ConfigBaseItem class="line-item">
|
||||
<div class="title">
|
||||
<span>最短时间</span>
|
||||
<a-tooltip :mouseEnterDelay="0.2" :overlayStyle="{ width: '248px' }">
|
||||
<template #title>
|
||||
<div style="padding: 0 4px; font-size: 12px">
|
||||
设置最短时间后用户即使填写内容,未到规定时间也不可以点击进入下一页。
|
||||
</div>
|
||||
</template>
|
||||
<i class="iconfont use-min-icon"></i>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="row">
|
||||
<a-switch
|
||||
:checked="!!+copyConfig.is_short_time"
|
||||
class="custom-switch"
|
||||
@change="switchChanged('is_short_time', $event)"
|
||||
/>
|
||||
</div>
|
||||
</ConfigBaseItem>
|
||||
|
||||
<template v-if="copyConfig.is_short_time">
|
||||
<ConfigBaseItem class="line-item">
|
||||
<div class="title">本页至少显示</div>
|
||||
<div class="row">
|
||||
<a-input-number
|
||||
ref="shortTimeRef"
|
||||
v-model:value="copyConfig.short_time"
|
||||
:formatter="shortTimeFormatter"
|
||||
:parser="(val) => (val === '不限' ? 0 : val || 0)"
|
||||
:min="0"
|
||||
placeholder="不限"
|
||||
class="custom-input-number display-count"
|
||||
@focus="inputSelectAll(shortTimeRef)"
|
||||
@blur="numberChange('short_time', copyConfig.short_time)"
|
||||
/>
|
||||
<span>S</span>
|
||||
</div>
|
||||
</ConfigBaseItem>
|
||||
|
||||
<ConfigBaseItem class="line-item">
|
||||
<div class="title">显示计时器</div>
|
||||
<div class="row">
|
||||
<a-switch
|
||||
:checked="!!+copyConfig.is_show"
|
||||
class="custom-switch"
|
||||
@change="switchChanged('is_show', $event)"
|
||||
/>
|
||||
</div>
|
||||
</ConfigBaseItem>
|
||||
|
||||
<ConfigBaseItem class="line-item">
|
||||
<div class="title">批量应用</div>
|
||||
</ConfigBaseItem>
|
||||
|
||||
<a-radio-group
|
||||
v-model:value="copyConfig.use_type"
|
||||
@change="radioChange('use_type', copyConfig.use_type)"
|
||||
>
|
||||
<ConfigBaseItem v-for="item in useTypes" :key="item.id" class="line-item">
|
||||
<div class="title">
|
||||
<a-radio :value="item.id">{{ item.name }}</a-radio>
|
||||
</div>
|
||||
</ConfigBaseItem>
|
||||
</a-radio-group>
|
||||
|
||||
<ConfigBaseItem v-if="[2].includes(copyConfig.use_type)" class="line-item">
|
||||
<span>第</span>
|
||||
<a-select
|
||||
v-model:value="copyConfig.pages"
|
||||
:get-pupup-container="(el) => el.parentNode"
|
||||
mode="multiple"
|
||||
placeholder="请选择页码"
|
||||
class="custom-select select-page"
|
||||
@blur="selectChanged('pages', copyConfig.pages)"
|
||||
>
|
||||
<a-select-option v-for="(item, index) in pages" :key="index + 1" :value="index + 1">
|
||||
{{ index + 1 }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<span>页</span>
|
||||
</ConfigBaseItem>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, defineEmits, defineProps, reactive, ref } from 'vue';
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
import ConfigTitle from '../../components/config/ConfigTitle.vue';
|
||||
import ConfigBaseItem from '../../components/config/ConfigBaseItem.vue';
|
||||
|
||||
const store = useStore();
|
||||
const emits = defineEmits(['update']);
|
||||
const props = defineProps({
|
||||
config: { type: Object, default: Object.create(null) }
|
||||
});
|
||||
|
||||
const copyConfig = computed(() => {
|
||||
return reactive({
|
||||
is_short_time: 0,
|
||||
short_time: 0,
|
||||
is_show: 0,
|
||||
use_type: 0,
|
||||
pages: [],
|
||||
...JSON.parse(JSON.stringify(props.config || {}))
|
||||
});
|
||||
});
|
||||
|
||||
const quizIndex = computed(() => `第${copyConfig.value.page}页`);
|
||||
const pages = computed(() => store.state.common.questionInfo.survey?.pages || []);
|
||||
|
||||
const useTypes = ref([
|
||||
{ id: 0, name: '应用到当前页' },
|
||||
{ id: 1, name: '应用到所有页' },
|
||||
{ id: 2, name: '应用到指定页' }
|
||||
]);
|
||||
|
||||
const shortTimeRef = ref(null);
|
||||
|
||||
function inputSelectAll(elRef) {
|
||||
const inputEl = elRef?.$el?.querySelector('input');
|
||||
if (inputEl.select) {
|
||||
inputEl.select();
|
||||
}
|
||||
}
|
||||
|
||||
function shortTimeFormatter(val) {
|
||||
const num = `${val}`.replace(/[^0-9]/g, '');
|
||||
return !+num ? '不限' : num;
|
||||
}
|
||||
|
||||
function switchChanged(field, value) {
|
||||
update({ [field]: +value });
|
||||
}
|
||||
|
||||
function numberChange(field, value) {
|
||||
update({ [field]: +value });
|
||||
}
|
||||
|
||||
function radioChange(field, value) {
|
||||
const info = { [field]: +value };
|
||||
if (field === 'use_type' && +value !== 2) {
|
||||
info.pages = [];
|
||||
}
|
||||
update(info);
|
||||
}
|
||||
|
||||
function selectChanged(field, value) {
|
||||
update({ [field]: value });
|
||||
}
|
||||
|
||||
function update(values) {
|
||||
emits('update', {
|
||||
...(copyConfig.value || {}),
|
||||
...(values || {})
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.line-item {
|
||||
height: 48px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none !important;
|
||||
|
||||
.title,
|
||||
.row {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.use-min-icon {
|
||||
margin-left: 8px;
|
||||
color: #bfbfbf;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.display-count {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.select-page {
|
||||
flex: 1 1 1px;
|
||||
margin-right: 4px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
125
src/views/Design/components/Questions/paging/Paging.vue
Normal file
125
src/views/Design/components/Questions/paging/Paging.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="page" :class="{ active: active }">
|
||||
<div class="page-text">
|
||||
<div class="page-text-line"></div>
|
||||
<span class="page-text-content">
|
||||
第 {{ info.page }}/{{ info.total }} 页:{{ info.first_title }}-{{ info.last_title }}
|
||||
</span>
|
||||
<div class="page-text-line"></div>
|
||||
<div v-if="!isOneQuestionPerPage" class="page-icon">
|
||||
<i
|
||||
class="iconfont active-icon"
|
||||
:style="{ marginRight: isLastPage ? '0' : '16px' }"
|
||||
@click="activePage"
|
||||
></i
|
||||
>
|
||||
<template v-if="!isLastPage">
|
||||
<i class="iconfont moverQues" style="margin-right: 16px"></i>
|
||||
<i class="iconfont" @click="deleteHandle"></i>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
// Props 定义
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
// 使用 Pinia Store
|
||||
const counterStore = useCounterStore();
|
||||
const { questionsInfo } = storeToRefs(counterStore);
|
||||
|
||||
// 计算属性
|
||||
const isOneQuestionPerPage = computed(() => {
|
||||
return !!questionsInfo.value?.survey?.is_one_page_one_question;
|
||||
});
|
||||
|
||||
const isLastPage = computed(() => {
|
||||
return props.index === (questionsInfo.value?.questions?.length - 1 || -1);
|
||||
});
|
||||
|
||||
// 自定义事件
|
||||
const emit = defineEmits(['activePage', 'removePage']);
|
||||
|
||||
function activePage() {
|
||||
emit('activePage');
|
||||
}
|
||||
|
||||
function deleteHandle() {
|
||||
emit('removePage');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/style/whole/whole';
|
||||
|
||||
.page {
|
||||
&.active {
|
||||
color: $yili-default-color;
|
||||
|
||||
.page-text-line {
|
||||
border-color: $yili-default-color;
|
||||
}
|
||||
|
||||
.active-icon {
|
||||
color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
|
||||
.page-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.page-text-line {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
border: 1px dashed #bfbfbf;
|
||||
}
|
||||
|
||||
.page-text-content {
|
||||
margin: 0 3px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.page-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 18px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: #dadada;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $yili-default-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user