feat: css 处理 增加font 增加 选择题目
This commit is contained in:
8
components.d.ts
vendored
8
components.d.ts
vendored
@@ -13,5 +13,13 @@ declare module 'vue' {
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanCell: typeof import('vant/es')['Cell']
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||
VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
|
||||
VanDivider: typeof import('vant/es')['Divider']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
}
|
||||
}
|
||||
|
||||
5
env.d.ts
vendored
5
env.d.ts
vendored
@@ -1 +1,6 @@
|
||||
/// <reference types="vite/client" />
|
||||
declare module '*.vue' {
|
||||
import {DefineComponent} from 'vue';
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
|
||||
40
package-lock.json
generated
40
package-lock.json
generated
@@ -13,6 +13,8 @@
|
||||
"lodash": "^4.17.21",
|
||||
"pinia": "^2.1.7",
|
||||
"sass": "^1.77.8",
|
||||
"sortablejs": "^1.15.6",
|
||||
"uuid": "^11.1.0",
|
||||
"vant": "^4.9.17",
|
||||
"vue": "^3.4.29",
|
||||
"vue-router": "^4.3.3"
|
||||
@@ -21,6 +23,7 @@
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/node": "^20.14.5",
|
||||
"@types/postcss-pxtorem": "^6.1.0",
|
||||
"@vant/auto-import-resolver": "^1.3.0",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
@@ -30,8 +33,8 @@
|
||||
"npm-run-all2": "^6.2.0",
|
||||
"postcss-pxtorem": "^6.1.0",
|
||||
"typescript": "~5.4.0",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.3",
|
||||
"unplugin-auto-import": "^0.18.6",
|
||||
"unplugin-vue-components": "^0.27.5",
|
||||
"vite": "^5.3.1",
|
||||
"vue-tsc": "^2.0.21"
|
||||
}
|
||||
@@ -1889,6 +1892,12 @@
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@vant/auto-import-resolver": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/auto-import-resolver/-/auto-import-resolver-1.3.0.tgz",
|
||||
"integrity": "sha512-lJyWtCyFizR4bHZvMiNMF3w+WTFTUWAvka1eqTnPK9ticUcKTCOx6qEmHcm8JPb3g1t3GaD2W3MnHkBp/nHamw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vant/popperjs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
|
||||
@@ -4401,18 +4410,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@yl/yili-fe-lint-config/node_modules/typescript": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz",
|
||||
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
"inBundle": true
|
||||
},
|
||||
"node_modules/@yl/yili-fe-lint-config/node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
@@ -9195,6 +9196,11 @@
|
||||
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/sortablejs": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmmirror.com/sortablejs/-/sortablejs-1.15.6.tgz",
|
||||
"integrity": "sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A=="
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"license": "BSD-3-Clause",
|
||||
@@ -10292,6 +10298,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vant": {
|
||||
"version": "4.9.17",
|
||||
"resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.17.tgz",
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
"lodash": "^4.17.21",
|
||||
"pinia": "^2.1.7",
|
||||
"sass": "^1.77.8",
|
||||
"sortablejs": "^1.15.6",
|
||||
"uuid": "^11.1.0",
|
||||
"vant": "^4.9.17",
|
||||
"vue": "^3.4.29",
|
||||
"vue-router": "^4.3.3"
|
||||
@@ -26,6 +28,7 @@
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/node": "^20.14.5",
|
||||
"@types/postcss-pxtorem": "^6.1.0",
|
||||
"@vant/auto-import-resolver": "^1.3.0",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.0",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
@@ -35,8 +38,8 @@
|
||||
"npm-run-all2": "^6.2.0",
|
||||
"postcss-pxtorem": "^6.1.0",
|
||||
"typescript": "~5.4.0",
|
||||
"unplugin-auto-import": "^0.18.2",
|
||||
"unplugin-vue-components": "^0.27.3",
|
||||
"unplugin-auto-import": "^0.18.6",
|
||||
"unplugin-vue-components": "^0.27.5",
|
||||
"vite": "^5.3.1",
|
||||
"vue-tsc": "^2.0.21"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import './base.css';
|
||||
@import '../font/iconfont.css';
|
||||
|
||||
a,
|
||||
.green {
|
||||
@@ -13,3 +14,19 @@ a,
|
||||
background-color: hsla(160deg, 100%, 37%, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
541
src/fonts/demo.css
Normal file
541
src/fonts/demo.css
Normal file
@@ -0,0 +1,541 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: 'iconfont logo';
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-style: normal;
|
||||
font-size: 160px;
|
||||
font-family: 'iconfont logo';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
color: #666;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
margin-bottom: -1px;
|
||||
border-bottom: 2px solid transparent;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 30px 100px;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
overflow: hidden;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
line-height: 1;
|
||||
text-align: left;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
color: #333;
|
||||
font-size: 160px;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
overflow: auto;
|
||||
margin: 10px 0;
|
||||
padding: 20px;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
overflow: hidden;
|
||||
width: 100% !important;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
list-style: none !important;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
font-size: 42px;
|
||||
line-height: 100px;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
margin-bottom: 24px;
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
clear: both;
|
||||
margin: 1.6em 0 0.6em;
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
clear: both;
|
||||
height: 1px;
|
||||
margin: 16px 0;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown > p,
|
||||
.markdown > blockquote,
|
||||
.markdown > .highlight,
|
||||
.markdown > ol,
|
||||
.markdown > ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul > li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown > ul li,
|
||||
.markdown blockquote ul > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown > ul li p,
|
||||
.markdown > ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol > li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown > ol li,
|
||||
.markdown blockquote ol > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
border-radius: 3px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table {
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
empty-cells: show;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.markdown > table th,
|
||||
.markdown > table td {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #e9e9e9;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
margin: 1em 0;
|
||||
padding-left: 0.8em;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
color: #999;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
margin-left: 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown > p > br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background-color: #eaffea;
|
||||
color: #55a532;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background-color: #ffecec;
|
||||
color: #bd2c00;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: none;
|
||||
color: black;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
text-shadow: 0 1px white;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*='language-']::-moz-selection,
|
||||
pre[class*='language-'] ::-moz-selection,
|
||||
code[class*='language-']::-moz-selection,
|
||||
code[class*='language-'] ::-moz-selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
pre[class*='language-']::selection,
|
||||
pre[class*='language-'] ::selection,
|
||||
code[class*='language-']::selection,
|
||||
code[class*='language-'] ::selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
overflow: auto;
|
||||
margin: .5em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
background: hsla(0deg, 0%, 100%, .5);
|
||||
color: #9a6e3a;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
29
src/fonts/iconfont.css
Normal file
29
src/fonts/iconfont.css
Normal file
@@ -0,0 +1,29 @@
|
||||
@font-face {
|
||||
font-family: iconfont; /* Project id */
|
||||
src: url('iconfont.ttf?t=1740720237938') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-style: normal;
|
||||
font-size: 16px;
|
||||
font-family: iconfont !important;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-edit2::before {
|
||||
content: '\e630';
|
||||
}
|
||||
|
||||
.icon-copy::before {
|
||||
content: '\e632';
|
||||
}
|
||||
|
||||
.icon-delete::before {
|
||||
content: '\e63f';
|
||||
}
|
||||
|
||||
.icon-sort::before {
|
||||
content: '\e6a0';
|
||||
}
|
||||
|
||||
18
src/fonts/iconfont.js
Normal file
18
src/fonts/iconfont.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const e = 'someValue';
|
||||
const a = 'anotherValue';
|
||||
const i = 'yetAnotherValue';
|
||||
const n = 'andAnotherValue';
|
||||
const o = 'oneMoreValue';
|
||||
const t = 'lastOne';
|
||||
|
||||
function someFunction() {
|
||||
const r = document.createElement('style');
|
||||
r.type = 'text/css';
|
||||
document.head.appendChild(r);
|
||||
if (r.styleSheet) {
|
||||
r.styleSheet.cssText = e + a + i + n + o + t;
|
||||
} else {
|
||||
r.appendChild(document.createTextNode(e + a + i + n + o + t));
|
||||
}
|
||||
}
|
||||
someFunction();
|
||||
37
src/fonts/iconfont.json
Normal file
37
src/fonts/iconfont.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "1160114",
|
||||
"name": "edit-2",
|
||||
"font_class": "edit2",
|
||||
"unicode": "e630",
|
||||
"unicode_decimal": 58928
|
||||
},
|
||||
{
|
||||
"icon_id": "1160116",
|
||||
"name": "copy",
|
||||
"font_class": "copy",
|
||||
"unicode": "e632",
|
||||
"unicode_decimal": 58930
|
||||
},
|
||||
{
|
||||
"icon_id": "1160129",
|
||||
"name": "delete",
|
||||
"font_class": "delete",
|
||||
"unicode": "e63f",
|
||||
"unicode_decimal": 58943
|
||||
},
|
||||
{
|
||||
"icon_id": "1160227",
|
||||
"name": "sort",
|
||||
"font_class": "sort",
|
||||
"unicode": "e6a0",
|
||||
"unicode_decimal": 59040
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
src/fonts/iconfont.ttf
Normal file
BIN
src/fonts/iconfont.ttf
Normal file
Binary file not shown.
@@ -1,39 +1,20 @@
|
||||
<template>
|
||||
<div class="common-layout">
|
||||
<el-container>
|
||||
<el-header>
|
||||
<nav>
|
||||
<RouterLink to="/">Home</RouterLink>
|
||||
<RouterLink to="/about">About</RouterLink>
|
||||
</nav>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<RouterView />
|
||||
</el-main>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterLink, RouterView } from 'vue-router';
|
||||
import { RouterView } from 'vue-router';
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.el-header, .el-footer {
|
||||
background-color: #B3C0D1;
|
||||
color: #333;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
height: calc(100vh - 60px);
|
||||
.common-layout {
|
||||
height: calc(100vh);
|
||||
background-color: #E9EEF3;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
body > .el-container {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,19 +1,10 @@
|
||||
import './assets/main.css';
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
|
||||
import 'amfe-flexible';
|
||||
import Vant from 'vant'
|
||||
|
||||
import { createApp } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
const app = createApp(App);
|
||||
app.use(Vant);
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component);
|
||||
}
|
||||
app.use(createPinia());
|
||||
app.use(router);
|
||||
|
||||
app.mount('#app');
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import HomeView from '../views/HomeView.vue';
|
||||
|
||||
// import HomeView from '../views/HomeView.vue';
|
||||
import Design from '@/views/Design/Index.vue';
|
||||
import QuestionEdit from '@/views/Design/QuestionEdit.vue';
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
// {
|
||||
// path: '/',
|
||||
// name: 'home',
|
||||
// component: HomeView
|
||||
// },
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
path: '/design',
|
||||
name: 'design',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/AboutView.vue')
|
||||
component: Design
|
||||
},
|
||||
{
|
||||
path: '/design/edit',
|
||||
name: 'questionEdit',
|
||||
component: QuestionEdit
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
38
src/stores/constance/constance.common.js
Normal file
38
src/stores/constance/constance.common.js
Normal file
@@ -0,0 +1,38 @@
|
||||
export const A_COMMON_GET_QUESTIONINFO = 'A_COMMON_GET_QUESTIONINFO';
|
||||
export const A_COMMON_SET_QUESTIONINFO = 'A_COMMON_SET_QUESTIONINFO';
|
||||
|
||||
export const A_COMMON_GET_QUESSAVEPARAM = 'A_COMMON_GET_QUESSAVEPARAM';
|
||||
export const A_COMMON_SET_QUESSAVEPARAM = 'A_COMMON_SET_QUESSAVEPARAM';
|
||||
|
||||
export const A_COMMON_GET_ACTIVEQUESTION = 'A_COMMON_GET_ACTIVEQUESTION';
|
||||
export const A_COMMON_SET_ACTIVEQUESTION = 'A_COMMON_SET_ACTIVEQUESTION';
|
||||
|
||||
export const A_COMMON_SET_BANK_LIST = 'A_COMMON_SET_BANK_LIST';
|
||||
export const A_COMMON_GET_BANK_LIST = 'A_COMMON_GET_BANK_LIST';
|
||||
|
||||
export const A_COMMON_GET_WEBSOCKET = 'A_COMMON_GET_WEBSOCKET';
|
||||
export const A_COMMON_SET_WEBSOCKET = 'A_COMMON_SET_WEBSOCKET';
|
||||
|
||||
export const A_COMMON_GET_TOKEN = 'A_COMMON_GET_TOKEN';
|
||||
export const A_COMMON_CLEAR_TOKEN = 'A_COMMON_CLEAR_TOKEN';
|
||||
export const M_COMMON_SET_TOKEN = 'M_COMMON_SET_TOKEN';
|
||||
|
||||
export const M_COMMON_GET_USERINFO = 'M_COMMON_GET_USERINFO';
|
||||
export const M_COMMON_SET_USERINFO = 'M_COMMON_SET_USERINFO';
|
||||
|
||||
export const M_COMMON_SET_SURVEY_INFO = 'M_COMMON_SET_SURVEY_INFO';
|
||||
export const M_COMMON_SET_SURVEY_STATUS = 'M_COMMON_SET_SURVEY_STATUS';
|
||||
export const M_COMMON_SET_SURVEY_SCENEID = 'M_COMMON_SET_SURVEY_SCENEID';
|
||||
export const M_COMMON_SET_SURVEY_SCENEPARENTID = 'M_COMMON_SET_SURVEY_SCENEPARENTID';
|
||||
export const M_COMMON_SET_SURVEY_NAME = 'M_COMMON_SET_SURVEY_NAME';
|
||||
|
||||
export const M_COMMON_SET_TOKEN_UNAUTHORIZED = 'M_COMMON_SET_TOKEN_UNAUTHORIZED';
|
||||
|
||||
export const GET_FILE_TYPE = 'GET_FILE_TYPE';
|
||||
export const M_COMMON_SET_THEME_INFO = 'M_COMMON_SET_THEME_INFO';
|
||||
export const HEADER_IMG_INFO = 'HEADER_IMG_INFO';
|
||||
export const DELETET_HEME_INFO_HEADIMGURL = 'DELETET_HEME_INFO_HEADIMGURL';
|
||||
|
||||
export const GUIDE_SELECT_NEED = 'GUIDE_SELECT_NEED';
|
||||
export const GUIDE_OTHER_NEED = 'GUIDE_OTHER_NEED';
|
||||
export const ANSWER_SESSION_ID = 'ANSWER_SESSION_ID';
|
||||
@@ -1,12 +1,21 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
// src/stores/counter.ts
|
||||
import { defineStore, storeToRefs } from 'pinia';
|
||||
import { useCommonStore } from './modules/common';
|
||||
|
||||
// 类型安全的实现方式
|
||||
const modulesFiles = import.meta.glob('./modules/**/*.ts', { eager: true });
|
||||
const modules = Object.entries(modulesFiles).reduce(
|
||||
(acc: { [key: string]: any }, [path, module]) => {
|
||||
const moduleName = path.replace(/^\.\/modules\/(.*)\.\w+$/, '$1');
|
||||
acc[moduleName] = (module as any).default;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
export const useCounterStore = defineStore('counter', () => {
|
||||
const count = ref(0);
|
||||
const doubleCount = computed(() => count.value * 2);
|
||||
function increment() {
|
||||
count.value += 1;
|
||||
}
|
||||
|
||||
return { count, doubleCount, increment };
|
||||
// 引入 common 模块
|
||||
const commonStore = useCommonStore();
|
||||
const { questionsInfo } = storeToRefs(commonStore);
|
||||
// 返回需要暴露的内容
|
||||
return { commonStore, questionsInfo, modules };
|
||||
});
|
||||
|
||||
80
src/stores/modules/common.ts
Normal file
80
src/stores/modules/common.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// src/stores/modules/common.ts
|
||||
import { defineStore } from 'pinia';
|
||||
// 假设 uid 是一个生成唯一 ID 的函数
|
||||
// 如果没有现成的 uid 函数,可以引入一个 UUID 库
|
||||
// 或者使用其他 UUID 库
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export const useCommonStore = defineStore('common', {
|
||||
state: () => ({
|
||||
questionsInfo: {
|
||||
// 初始化为 null 或者空对象 {}
|
||||
questions: [
|
||||
{
|
||||
id: '8819cf74-70dc-4b7d-9153-857230e50dd3',
|
||||
question_type: 1,
|
||||
question_index: 1,
|
||||
stem: '请选择您的年龄',
|
||||
title: '',
|
||||
options: [
|
||||
[
|
||||
{
|
||||
id: '451adf64-07da-49ae-9b43-1bff91045dd8',
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '<p>18岁以下</p>',
|
||||
option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' },
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
},
|
||||
{ id: '9168a75d-a007-42b6-b746-b220d1c05c7a', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>18-25岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 2, parent_id: 0, type: 0, cascade: [], config: [] }, { id: 'a4458a57-9cdf-483d-aa1e-23d190f349b8', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>26-35岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 3, parent_id: 0, type: 0, cascade: [], config: [] }, { id: 'b15f6faf-cdc8-4d3b-8b91-feec6c191014', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>36-45岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 4, parent_id: 0, type: 0, cascade: [], config: [] }, { id: '45ddfb00-275c-4a70-a9ca-1f136cf33db4', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>46-55岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 5, parent_id: 0, type: 0, cascade: [], config: [] }, { id: '4fdf3d35-a204-42f2-8d33-705a4a6f63d4', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>56岁以上</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 6, parent_id: 0, type: 0, cascade: [], config: [] }]],
|
||||
last_option_index: 6,
|
||||
config:
|
||||
{
|
||||
is_required: 1,
|
||||
quick_type: 10,
|
||||
is_show: ['is_required', 'select_random', 'each_number'],
|
||||
each_number: 1,
|
||||
select_random: 0
|
||||
},
|
||||
associate: [],
|
||||
question_code: '',
|
||||
logic_config:
|
||||
{ order: 0, type: 0, expect: '', stay_time: '' }
|
||||
},
|
||||
{
|
||||
id: '8819cf74-70dc-4b7d-9153-857230e50d34', question_type: 1, question_index: 1, stem: '请选择您的年龄', title: '', options: [[{ id: '451adf64-07da-49ae-9b43-1bff91045dd8', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>18岁以下</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 1, parent_id: 0, type: 0, cascade: [], config: [] }, { id: '9168a75d-a007-42b6-b746-b220d1c05c7a', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>18-25岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 2, parent_id: 0, type: 0, cascade: [], config: [] }, { id: 'a4458a57-9cdf-483d-aa1e-23d190f349b8', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>26-35岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 3, parent_id: 0, type: 0, cascade: [], config: [] }, { id: 'b15f6faf-cdc8-4d3b-8b91-feec6c191014', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>36-45岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 4, parent_id: 0, type: 0, cascade: [], config: [] }, { id: '45ddfb00-275c-4a70-a9ca-1f136cf33db4', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>46-55岁</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 5, parent_id: 0, type: 0, cascade: [], config: [] }, { id: '4fdf3d35-a204-42f2-8d33-705a4a6f63d4', is_fixed: 0, is_other: 0, is_remove_other: 0, option: '<p>56岁以上</p>', option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' }, option_index: 6, parent_id: 0, type: 0, cascade: [], config: [] }]], last_option_index: 6, config: { is_required: 1, quick_type: 10, is_show: ['is_required', 'select_random', 'each_number'], each_number: 1, select_random: 0 }, associate: [], question_code: '', logic_config: { order: 0, type: 0, expect: '', stay_time: '' }
|
||||
}]
|
||||
}
|
||||
}),
|
||||
actions: {
|
||||
async fetchQuestionInfo(questionInfo) {
|
||||
try {
|
||||
if (!questionInfo) return;
|
||||
|
||||
const info = JSON.parse(questionInfo);
|
||||
if (info?.questions?.length) {
|
||||
info.questions.forEach((page) => {
|
||||
// 使用 UUID 生成唯一 ID
|
||||
if (page?.page) {
|
||||
page.pageId = page.pageId || uuidv4();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.setQuestionInfo(info);
|
||||
} catch (error) {
|
||||
//未来扩展
|
||||
}
|
||||
},
|
||||
setQuestionInfo(questionInfo) {
|
||||
this.questionsInfo = questionInfo;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
getQuestionsInfo: (state) => state.questionsInfo
|
||||
}
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<main>
|
||||
<div>About</div>
|
||||
<div>count: {{ count }}</div>
|
||||
<div>doubleCount: {{ doubleCount }}</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const useCounter = useCounterStore();
|
||||
const { count, doubleCount } = storeToRefs(useCounter);
|
||||
</script>
|
||||
54
src/views/Design/Index.vue
Normal file
54
src/views/Design/Index.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div>
|
||||
<draggable
|
||||
v-model:data="questionInfo.questions"
|
||||
item-key="id"
|
||||
handle=".moverQues"
|
||||
chosenClass="chosen"
|
||||
animation="300"
|
||||
:scroll="true"
|
||||
>
|
||||
<template #item="{ element, index }">
|
||||
<choose-question
|
||||
: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>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineAsyncComponent, ref, onMounted } from 'vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
// 修改访问方式
|
||||
const store = storeToRefs(counterStore);
|
||||
// import 组件
|
||||
const Draggable = defineAsyncComponent(() => {
|
||||
return import('./components/Draggable.vue');
|
||||
});
|
||||
const BaseSelect = defineAsyncComponent(() => {
|
||||
return import('./components/Questions/BaseSelect.vue');
|
||||
});
|
||||
const ChooseQuestion = defineAsyncComponent(() => {
|
||||
return import('./components/ChooseQuestion.vue');
|
||||
});
|
||||
const questionInfo = ref({ questions: [] });
|
||||
const chooseQuestionId = ref('');
|
||||
|
||||
// 获取选中的题目的ID
|
||||
const getChooseQuestionId = (questionItem) => {
|
||||
chooseQuestionId.value = questionItem.id;
|
||||
};
|
||||
onMounted(() => {
|
||||
questionInfo.value = store.questionsInfo.value;
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
40
src/views/Design/QuestionEdit.vue
Normal file
40
src/views/Design/QuestionEdit.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="container question-edit-container">
|
||||
<BaseSelectEdit v-if="questionElement.question_type === 1" :element="questionElement"></BaseSelectEdit>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ref, onBeforeMount, defineAsyncComponent } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 组件
|
||||
const BaseSelectEdit = defineAsyncComponent(() => import('@/views/Design/components/QuestionsEdit/BaseSelectEdit.vue'));
|
||||
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
// 修改访问方式
|
||||
const { questionsInfo } = storeToRefs(counterStore);
|
||||
const questionIndex = ref(-1);
|
||||
const questionElement = ref({});
|
||||
|
||||
onBeforeMount(() => {
|
||||
// 获取 query 参数
|
||||
if (route.query.id) {
|
||||
// 查找对应数据
|
||||
questionElement.value = questionsInfo.value.questions.find((item, index) => {
|
||||
if (item.id === route.query.id) {
|
||||
questionIndex.value = index;
|
||||
return item;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
122
src/views/Design/components/ChooseQuestion.vue
Normal file
122
src/views/Design/components/ChooseQuestion.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div class="choose-question-container">
|
||||
<div :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)">
|
||||
<i class="icon iconfont choose-question-active-container-icon" v-html="item.icon"></i>
|
||||
<div class="choose-question-active-container-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
// 此方法目前为空,未来可能扩展
|
||||
}
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
chooseQuestionId: {
|
||||
type: String,
|
||||
default: '0'
|
||||
}
|
||||
});
|
||||
const element = ref(props.element);
|
||||
// emit 事件
|
||||
|
||||
// 选中题目后出现的操作
|
||||
const questionAction = ref([
|
||||
{
|
||||
icon: '',
|
||||
name: '编辑',
|
||||
key: 'edit',
|
||||
class: ''
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
name: '复制',
|
||||
key: 'copy',
|
||||
class: ''
|
||||
},
|
||||
{
|
||||
icon: '',
|
||||
name: '移动',
|
||||
key: 'moveUp',
|
||||
class: 'moverQues'
|
||||
},
|
||||
// {
|
||||
// icon:'',
|
||||
// name:'下移',
|
||||
// key:'moveDown',
|
||||
// class:''
|
||||
// },
|
||||
{
|
||||
icon: '',
|
||||
name: '删除',
|
||||
key: 'delete',
|
||||
class: ''
|
||||
}
|
||||
]);
|
||||
const emit = defineEmits(['getChooseQuestionId']);
|
||||
|
||||
// 选中题目
|
||||
const chooseItem = () => {
|
||||
// 使用从 defineProps 接收的 element 对象
|
||||
emit('getChooseQuestionId', props.element);
|
||||
};
|
||||
|
||||
const itemAction = (item) => {
|
||||
switch (item.key) {
|
||||
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-active {
|
||||
outline: 1px dashed #409eff;
|
||||
}
|
||||
|
||||
& .choose-question-active-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 20px;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
|
||||
& .choose-question-active-container-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
& .choose-question-active-container-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
104
src/views/Design/components/Draggable.vue
Normal file
104
src/views/Design/components/Draggable.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div ref="draggable">
|
||||
<div
|
||||
v-for="(element, index) in data"
|
||||
:key="element.id || element.pageId"
|
||||
:data_id="element[itemKey] || index"
|
||||
:data_index="index"
|
||||
:data_key="element.id || element.pageId"
|
||||
>
|
||||
<slot name="item" :element="element" :index="index"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sortable from 'sortablejs';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
export default {
|
||||
name: 'Draggable',
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
itemKey: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
handle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
filter: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
chosenClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
animation: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
scroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
group: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
move: {
|
||||
type: Function,
|
||||
default: () => {
|
||||
// 后续扩展
|
||||
}
|
||||
}
|
||||
},
|
||||
emits: ['update:data', 'end'],
|
||||
setup(props, context) {
|
||||
const sortable = ref(null);
|
||||
const draggable = ref(null);
|
||||
const copyData = reactive([]);
|
||||
const options = {
|
||||
handle: props.handle,
|
||||
filter: props.filter,
|
||||
chosenClass: props.chosenClass,
|
||||
animation: props.animation,
|
||||
scroll: props.scroll,
|
||||
scrollSensitivity: 100,
|
||||
forceFallback: true,
|
||||
scrollSpeed: 30,
|
||||
group: props.group,
|
||||
onMove: (evt) => {
|
||||
const index = evt.related.getAttribute('data_index');
|
||||
evt.newIndex = Number(index);
|
||||
return props.move(evt);
|
||||
},
|
||||
// 拖动结束
|
||||
onEnd: (evt) => {
|
||||
evt.stopPropagation();
|
||||
const tempData = JSON.parse(JSON.stringify(props.data));
|
||||
const oldEle = tempData[evt.oldIndex];
|
||||
tempData.splice(evt.oldIndex, 1);
|
||||
tempData.splice(evt.newIndex, 0, oldEle);
|
||||
context.emit('update:data', tempData);
|
||||
context.emit('end', evt);
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
if (sortable.value) sortable.value.destory();
|
||||
sortable.value = Sortable.create(draggable.value, options);
|
||||
});
|
||||
return {
|
||||
copyData,
|
||||
draggable
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
45
src/views/Design/components/Questions/BaseSelect.vue
Normal file
45
src/views/Design/components/Questions/BaseSelect.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<van-field
|
||||
v-model="element.stem"
|
||||
:label="element.stem"
|
||||
:required="element.config.is_required=== 1"
|
||||
label-align="top"
|
||||
>
|
||||
<template #input>
|
||||
<van-checkbox-group>
|
||||
<template v-for="item in element.options">
|
||||
<van-checkbox
|
||||
v-for="(it, index) in item"
|
||||
:key="index"
|
||||
:name="it.value"
|
||||
:label="it.label"
|
||||
:disabled="it.disabled"
|
||||
icon-size="0.35rem"
|
||||
>
|
||||
<template #default>
|
||||
<!-- {{it}}-->
|
||||
<div v-html="it.option"></div>
|
||||
</template>
|
||||
</van-checkbox>
|
||||
</template>
|
||||
</van-checkbox-group>
|
||||
</template>
|
||||
</van-field>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
stem: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
const element = ref(props.element);
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
82
src/views/Design/components/QuestionsEdit/BaseSelectEdit.vue
Normal file
82
src/views/Design/components/QuestionsEdit/BaseSelectEdit.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div class="container base-select-edit-container">
|
||||
<van-field
|
||||
label="题目"
|
||||
required
|
||||
placeholder="请输入题目内容"
|
||||
label-align="top"
|
||||
type="textarea"
|
||||
/>
|
||||
<div class="base-select-edit-divider">选项</div>
|
||||
<van-cell-group v-for="(item,index) in props.element.options" :key="index" :name="item.value">
|
||||
<van-field
|
||||
v-for="(it,itIndex) in item" :key="itIndex" v-model="it.option" placeholder="输入选项"
|
||||
label-width="0.25rem"
|
||||
>
|
||||
<template #label>
|
||||
<van-icon name="clear" class="del" />
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<van-field label-width="0.25rem" class="flex align-center flex-start" readonly>
|
||||
<template #label>
|
||||
<van-icon name="add" class="plus" />
|
||||
</template>
|
||||
<template #input>
|
||||
<div class="plus" @click="addOption">添加选项</div>
|
||||
</template>
|
||||
<template #button>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
// 或者使用其他 UUID 库
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
});
|
||||
const element = ref(props.element);
|
||||
// 增加选项
|
||||
const addOption = () => {
|
||||
element.value.options[element.value.options.length - 1].push({
|
||||
id: uuidv4(),
|
||||
is_fixed: 0,
|
||||
is_other: 0,
|
||||
is_remove_other: 0,
|
||||
option: '',
|
||||
option_config: { image_url: [], title: '', instructions: [], option_type: 0, limit_right_content: '' },
|
||||
option_index: 1,
|
||||
parent_id: 0,
|
||||
type: 0,
|
||||
cascade: [],
|
||||
config: []
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.base-select-edit-container {
|
||||
& .base-select-edit-divider {
|
||||
margin: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
& .van-field__value {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
& .del {
|
||||
color: red
|
||||
}
|
||||
|
||||
& .plus {
|
||||
color: #1989fa
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,16 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const useCounter = useCounterStore();
|
||||
const { count, doubleCount } = storeToRefs(useCounter);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<div>Home</div>
|
||||
<div>count: {{ count }}</div>
|
||||
<div>doubleCount: {{ doubleCount }}</div>
|
||||
<el-button @click="useCounter.increment()">累加</el-button>
|
||||
</main>
|
||||
</template>
|
||||
@@ -4,6 +4,7 @@
|
||||
"env.d.ts",
|
||||
"src/**/*",
|
||||
"src/**/*.vue",
|
||||
"src/**/**/*.vue",
|
||||
"./auto-imports.d.ts",
|
||||
"./components.d.ts",
|
||||
"./amfe-flexible.d.ts"
|
||||
|
||||
@@ -5,31 +5,38 @@ import vue from '@vitejs/plugin-vue'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
// import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
import {VantResolver} from 'unplugin-vue-components/resolvers';
|
||||
import postCssPxToRem from 'postcss-pxtorem'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: '0.0.0.0', // 监听所有网络接口
|
||||
port: 3000, // 你也可以指定端口
|
||||
},
|
||||
css: {
|
||||
postcss:{
|
||||
plugins:[
|
||||
// postCssPxToRem({
|
||||
// rootValue:37.5,
|
||||
// propList:['*'],
|
||||
// })
|
||||
postCssPxToRem({
|
||||
rootValue: 37.5,
|
||||
propList: ['*'],
|
||||
})
|
||||
]
|
||||
},
|
||||
preprocessorOptions: {
|
||||
scss: {}
|
||||
scss: {
|
||||
api: 'modern-compiler', // or 'modern'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
resolvers: [VantResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
resolvers: [VantResolver()],
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
|
||||
Reference in New Issue
Block a user