Merge branch 'feature/feature-20250331-h5' into uat
This commit is contained in:
4
auto-imports.d.ts
vendored
4
auto-imports.d.ts
vendored
@@ -5,4 +5,6 @@
|
|||||||
// Generated by unplugin-auto-import
|
// Generated by unplugin-auto-import
|
||||||
// biome-ignore lint: disable
|
// biome-ignore lint: disable
|
||||||
export {}
|
export {}
|
||||||
declare global {}
|
declare global {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
11
components.d.ts
vendored
11
components.d.ts
vendored
@@ -8,15 +8,9 @@ export {}
|
|||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
|
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
|
||||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
|
||||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
|
||||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
ElSpace: typeof import('element-plus/es')['ElSpace']
|
|
||||||
ElText: typeof import('element-plus/es')['ElText']
|
|
||||||
RichText: typeof import('./src/components/RichText.vue')['default']
|
RichText: typeof import('./src/components/RichText.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
@@ -29,8 +23,6 @@ declare module 'vue' {
|
|||||||
VanCol: typeof import('vant/es')['Col']
|
VanCol: typeof import('vant/es')['Col']
|
||||||
VanDivider: typeof import('vant/es')['Divider']
|
VanDivider: typeof import('vant/es')['Divider']
|
||||||
VanField: typeof import('vant/es')['Field']
|
VanField: typeof import('vant/es')['Field']
|
||||||
VanGrid: typeof import('vant/es')['Grid']
|
|
||||||
VanGridItem: typeof import('vant/es')['GridItem']
|
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
VanPicker: typeof import('vant/es')['Picker']
|
VanPicker: typeof import('vant/es')['Picker']
|
||||||
@@ -38,12 +30,9 @@ declare module 'vue' {
|
|||||||
VanRadio: typeof import('vant/es')['Radio']
|
VanRadio: typeof import('vant/es')['Radio']
|
||||||
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||||
VanRow: typeof import('vant/es')['Row']
|
VanRow: typeof import('vant/es')['Row']
|
||||||
VanSearch: typeof import('vant/es')['Search']
|
|
||||||
VanStepper: typeof import('vant/es')['Stepper']
|
VanStepper: typeof import('vant/es')['Stepper']
|
||||||
VanSwitch: typeof import('vant/es')['Switch']
|
VanSwitch: typeof import('vant/es')['Switch']
|
||||||
VanTab: typeof import('vant/es')['Tab']
|
VanTab: typeof import('vant/es')['Tab']
|
||||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
|
||||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
|
||||||
VanTabs: typeof import('vant/es')['Tabs']
|
VanTabs: typeof import('vant/es')['Tabs']
|
||||||
YLCascader: typeof import('./src/components/YLCascader.vue')['default']
|
YLCascader: typeof import('./src/components/YLCascader.vue')['default']
|
||||||
YLInput: typeof import('./src/components/YLInput.vue')['default']
|
YLInput: typeof import('./src/components/YLInput.vue')['default']
|
||||||
|
|||||||
@@ -19,11 +19,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"axios": "^1.8.2",
|
"axios": "^1.8.2",
|
||||||
|
"cos-js-sdk-v5": "^1.8.7",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"element-plus": "^2.7.8",
|
"element-plus": "^2.7.8",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
|
"shrinkpng": "^1.2.0-beta.1",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vant": "^4.9.17",
|
"vant": "^4.9.17",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { onMounted } from 'vue';
|
|||||||
import appBridge from '@/assets/js/appBridge';
|
import appBridge from '@/assets/js/appBridge';
|
||||||
import utils from '@/assets/js/common';
|
import utils from '@/assets/js/common';
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async() => {
|
||||||
if (utils.getParameter('digitalYiliToken')) {
|
if (utils.getParameter('digitalYiliToken')) {
|
||||||
// 隐藏/显示 header
|
// 隐藏/显示 header
|
||||||
appBridge.setHeaderShown(false);
|
appBridge.setHeaderShown(false);
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ export default class CommonApi {
|
|||||||
};
|
};
|
||||||
/* eslint-disable no-useless-escape */
|
/* eslint-disable no-useless-escape */
|
||||||
const reg = /\\|\/|\?|\?|\*|"|“|”|'|‘|’|<|>|{|}|\[|\]|\【|\】|:|:|、|\^|\$|!|~|`|\s|\+/g;
|
const reg = /\\|\/|\?|\?|\*|"|“|”|'|‘|’|<|>|{|}|\[|\]|\【|\】|:|:|、|\^|\$|!|~|`|\s|\+/g;
|
||||||
name =
|
name
|
||||||
name ||
|
= name
|
||||||
getRandomFileName(file?.name?.replace(reg, '') ?? '' ?? `${new Date().getTime()}.png`);
|
|| getRandomFileName(file?.name?.replace(reg, '') ?? '' ?? `${new Date().getTime()}.png`);
|
||||||
const res = await CommonApi.getOssInfo();
|
const res = await CommonApi.getOssInfo();
|
||||||
/* eslint-enable no-useless-escape */
|
/* eslint-enable no-useless-escape */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
.van-nav-bar {
|
.van-nav-bar {
|
||||||
padding-top: calc(var(--status-bar-height) + 10px) !important;
|
padding-top: calc(var(--status-bar-height) + 15px) !important;
|
||||||
// height: calc(46px + var(--status-bar-height)) !important;
|
z-index:999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.van-cell {
|
.van-cell {
|
||||||
padding: 8px !important;
|
padding: 8px !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,11 +311,14 @@ export default {
|
|||||||
* @returns {Boolean} 操作是否成功
|
* @returns {Boolean} 操作是否成功
|
||||||
*/
|
*/
|
||||||
async h5RouterBack(router) {
|
async h5RouterBack(router) {
|
||||||
const canGoBack = this.routerCanGoBack(router);
|
const routerCanGoBack = () => {
|
||||||
if (canGoBack) {
|
const position = router.options.history.state?.position;
|
||||||
|
return typeof position === 'number' && position > 0;
|
||||||
|
};
|
||||||
|
if (routerCanGoBack()) {
|
||||||
router.go(-1);
|
router.go(-1);
|
||||||
} else {
|
} else {
|
||||||
this.navigateBack();
|
appBridge.navigateBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -170,8 +170,8 @@ const getMaxDateLimit = computed(() => {
|
|||||||
props.format
|
props.format
|
||||||
);
|
);
|
||||||
const tempStr = '0000-12-31 23:59:59';
|
const tempStr = '0000-12-31 23:59:59';
|
||||||
const result =
|
const result
|
||||||
props.maxDate.length !== 0 && thisMax.length > props.maxDate.length
|
= props.maxDate.length !== 0 && thisMax.length > props.maxDate.length
|
||||||
? thisMax.slice(0, props.maxDate.length) + tempStr.slice(props.maxDate.length)
|
? thisMax.slice(0, props.maxDate.length) + tempStr.slice(props.maxDate.length)
|
||||||
: thisMax;
|
: thisMax;
|
||||||
return result.slice(0, props.format.length);
|
return result.slice(0, props.format.length);
|
||||||
@@ -194,8 +194,8 @@ function onChange({ selectedValues, columnIndex }) {
|
|||||||
renderMinuteColumns,
|
renderMinuteColumns,
|
||||||
renderSecondColumns
|
renderSecondColumns
|
||||||
];
|
];
|
||||||
updateColumns[columnIndex] &&
|
updateColumns[columnIndex]
|
||||||
updateColumns[columnIndex](changeValue, getMinDateLimit.value, getMaxDateLimit.value, false);
|
&& updateColumns[columnIndex](changeValue, getMinDateLimit.value, getMaxDateLimit.value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染全部列
|
// 渲染全部列
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
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');
|
||||||
src:
|
src:
|
||||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
|
||||||
format('embedded-opentype'),
|
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.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.ttf?t=1545807318834') format('truetype'),
|
||||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
|
||||||
format('svg');
|
format('svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
font-family: 'iconfont logo';
|
|
||||||
font-size: 160px;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
font-size: 160px;
|
||||||
|
font-family: 'iconfont logo';
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
line-height: 42px;
|
|
||||||
color: #666;
|
color: #666;
|
||||||
|
line-height: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tabs {
|
#tabs {
|
||||||
@@ -38,17 +38,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#tabs li {
|
#tabs li {
|
||||||
cursor: pointer;
|
|
||||||
width: 100px;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 16px;
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
width: 100px;
|
||||||
|
height: 40px;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tabs .active {
|
#tabs .active {
|
||||||
@@ -62,25 +62,25 @@
|
|||||||
|
|
||||||
/* 页面布局 */
|
/* 页面布局 */
|
||||||
.main {
|
.main {
|
||||||
padding: 30px 100px;
|
|
||||||
width: 960px;
|
width: 960px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 30px 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main .logo {
|
.main .logo {
|
||||||
color: #333;
|
overflow: hidden;
|
||||||
text-align: left;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
line-height: 1;
|
|
||||||
height: 110px;
|
height: 110px;
|
||||||
margin-top: -50px;
|
margin-top: -50px;
|
||||||
overflow: hidden;
|
margin-bottom: 30px;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: left;
|
||||||
*zoom: 1;
|
*zoom: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main .logo a {
|
.main .logo a {
|
||||||
font-size: 160px;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
|
font-size: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.helps {
|
.helps {
|
||||||
@@ -88,25 +88,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.helps pre {
|
.helps pre {
|
||||||
padding: 20px;
|
overflow: auto;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
|
padding: 20px;
|
||||||
border: solid 1px #e7e1cd;
|
border: solid 1px #e7e1cd;
|
||||||
background-color: #fffdef;
|
background-color: #fffdef;
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon_lists {
|
.icon_lists {
|
||||||
width: 100% !important;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
width: 100% !important;
|
||||||
*zoom: 1;
|
*zoom: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon_lists li {
|
.icon_lists li {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
text-align: center;
|
margin-bottom: 10px;
|
||||||
list-style: none !important;
|
list-style: none !important;
|
||||||
|
text-align: center;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@
|
|||||||
.icon_lists .icon {
|
.icon_lists .icon {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
line-height: 100px;
|
|
||||||
font-size: 42px;
|
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
font-size: 42px;
|
||||||
|
line-height: 100px;
|
||||||
-webkit-transition:
|
-webkit-transition:
|
||||||
font-size 0.25s linear,
|
font-size 0.25s linear,
|
||||||
width 0.25s linear;
|
width 0.25s linear;
|
||||||
@@ -137,15 +137,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon_lists .svg-icon {
|
.icon_lists .svg-icon {
|
||||||
/* 通过设置 font-size 来改变图标大小 */
|
|
||||||
width: 1em;
|
|
||||||
/* 图标和文字相邻时,垂直对齐 */
|
/* 图标和文字相邻时,垂直对齐 */
|
||||||
vertical-align: -0.15em;
|
vertical-align: -0.15em;
|
||||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
|
||||||
fill: currentColor;
|
|
||||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||||
normalize.css 中也包含这行 */
|
normalize.css 中也包含这行 */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
/* 通过设置 font-size 来改变图标大小 */
|
||||||
|
width: 1em;
|
||||||
|
|
||||||
|
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||||
|
fill: currentcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon_lists li .name,
|
.icon_lists li .name,
|
||||||
@@ -170,10 +173,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown h1 {
|
.markdown h1 {
|
||||||
|
margin-bottom: 24px;
|
||||||
color: #404040;
|
color: #404040;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown h2,
|
.markdown h2,
|
||||||
@@ -181,10 +184,10 @@
|
|||||||
.markdown h4,
|
.markdown h4,
|
||||||
.markdown h5,
|
.markdown h5,
|
||||||
.markdown h6 {
|
.markdown h6 {
|
||||||
color: #404040;
|
|
||||||
margin: 1.6em 0 0.6em 0;
|
|
||||||
font-weight: 500;
|
|
||||||
clear: both;
|
clear: both;
|
||||||
|
margin: 1.6em 0 0.6em;
|
||||||
|
color: #404040;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown h1 {
|
.markdown h1 {
|
||||||
@@ -212,11 +215,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown hr {
|
.markdown hr {
|
||||||
|
clear: both;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
margin: 16px 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
background: #e9e9e9;
|
background: #e9e9e9;
|
||||||
margin: 16px 0;
|
|
||||||
clear: both;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown p {
|
.markdown p {
|
||||||
@@ -259,8 +262,8 @@
|
|||||||
.markdown code {
|
.markdown code {
|
||||||
margin: 0 3px;
|
margin: 0 3px;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
background: #eee;
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown strong,
|
.markdown strong,
|
||||||
@@ -269,24 +272,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown > table {
|
.markdown > table {
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 0px;
|
|
||||||
empty-cells: show;
|
|
||||||
border: 1px solid #e9e9e9;
|
|
||||||
width: 95%;
|
width: 95%;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
empty-cells: show;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown > table th {
|
.markdown > table th {
|
||||||
white-space: nowrap;
|
|
||||||
color: #333;
|
color: #333;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown > table th,
|
.markdown > table th,
|
||||||
.markdown > table td {
|
.markdown > table td {
|
||||||
border: 1px solid #e9e9e9;
|
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,11 +298,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown blockquote {
|
.markdown blockquote {
|
||||||
font-size: 90%;
|
|
||||||
color: #999;
|
|
||||||
border-left: 4px solid #e9e9e9;
|
|
||||||
padding-left: 0.8em;
|
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
|
padding-left: 0.8em;
|
||||||
|
border-left: 4px solid #e9e9e9;
|
||||||
|
color: #999;
|
||||||
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown blockquote p {
|
.markdown blockquote p {
|
||||||
@@ -307,9 +310,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown .anchor {
|
.markdown .anchor {
|
||||||
|
margin-left: 8px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
margin-left: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown .waiting {
|
.markdown .waiting {
|
||||||
@@ -322,8 +325,8 @@
|
|||||||
.markdown h4:hover .anchor,
|
.markdown h4:hover .anchor,
|
||||||
.markdown h5:hover .anchor,
|
.markdown h5:hover .anchor,
|
||||||
.markdown h6:hover .anchor {
|
.markdown h6:hover .anchor {
|
||||||
opacity: 1;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown > br,
|
.markdown > br,
|
||||||
@@ -333,10 +336,10 @@
|
|||||||
|
|
||||||
.hljs {
|
.hljs {
|
||||||
display: block;
|
display: block;
|
||||||
background: white;
|
|
||||||
padding: 0.5em;
|
|
||||||
color: #333333;
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
background: white;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-comment,
|
.hljs-comment,
|
||||||
@@ -372,7 +375,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-tag {
|
.hljs-tag {
|
||||||
color: #333333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-title,
|
.hljs-title,
|
||||||
@@ -385,13 +388,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
color: #55a532;
|
|
||||||
background-color: #eaffea;
|
background-color: #eaffea;
|
||||||
|
color: #55a532;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-deletion {
|
.hljs-deletion {
|
||||||
color: #bd2c00;
|
|
||||||
background-color: #ffecec;
|
background-color: #ffecec;
|
||||||
|
color: #bd2c00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-link {
|
.hljs-link {
|
||||||
@@ -399,8 +402,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 代码高亮 */
|
/* 代码高亮 */
|
||||||
|
|
||||||
/* PrismJS 1.15.0
|
/* PrismJS 1.15.0
|
||||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prism.js default theme for JavaScript, CSS and HTML
|
* prism.js default theme for JavaScript, CSS and HTML
|
||||||
* Based on dabblet (http://dabblet.com)
|
* Based on dabblet (http://dabblet.com)
|
||||||
@@ -408,21 +413,19 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc
|
|||||||
*/
|
*/
|
||||||
code[class*='language-'],
|
code[class*='language-'],
|
||||||
pre[class*='language-'] {
|
pre[class*='language-'] {
|
||||||
color: black;
|
|
||||||
background: none;
|
background: none;
|
||||||
text-shadow: 0 1px white;
|
color: black;
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
|
line-height: 1.5;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
text-shadow: 0 1px white;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
word-spacing: normal;
|
word-spacing: normal;
|
||||||
word-break: normal;
|
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
line-height: 1.5;
|
word-break: normal;
|
||||||
|
|
||||||
-moz-tab-size: 4;
|
-moz-tab-size: 4;
|
||||||
-o-tab-size: 4;
|
-o-tab-size: 4;
|
||||||
tab-size: 4;
|
tab-size: 4;
|
||||||
|
|
||||||
-webkit-hyphens: none;
|
-webkit-hyphens: none;
|
||||||
-moz-hyphens: none;
|
-moz-hyphens: none;
|
||||||
-ms-hyphens: none;
|
-ms-hyphens: none;
|
||||||
@@ -433,16 +436,16 @@ pre[class*='language-']::-moz-selection,
|
|||||||
pre[class*='language-'] ::-moz-selection,
|
pre[class*='language-'] ::-moz-selection,
|
||||||
code[class*='language-']::-moz-selection,
|
code[class*='language-']::-moz-selection,
|
||||||
code[class*='language-'] ::-moz-selection {
|
code[class*='language-'] ::-moz-selection {
|
||||||
text-shadow: none;
|
|
||||||
background: #b3d4fc;
|
background: #b3d4fc;
|
||||||
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre[class*='language-']::selection,
|
pre[class*='language-']::selection,
|
||||||
pre[class*='language-'] ::selection,
|
pre[class*='language-'] ::selection,
|
||||||
code[class*='language-']::selection,
|
code[class*='language-']::selection,
|
||||||
code[class*='language-'] ::selection {
|
code[class*='language-'] ::selection {
|
||||||
text-shadow: none;
|
|
||||||
background: #b3d4fc;
|
background: #b3d4fc;
|
||||||
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
@@ -454,9 +457,9 @@ code[class*='language-'] ::selection {
|
|||||||
|
|
||||||
/* Code blocks */
|
/* Code blocks */
|
||||||
pre[class*='language-'] {
|
pre[class*='language-'] {
|
||||||
padding: 1em;
|
|
||||||
margin: 0.5em 0;
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
:not(pre) > code[class*='language-'],
|
:not(pre) > code[class*='language-'],
|
||||||
@@ -510,8 +513,8 @@ pre[class*='language-'] {
|
|||||||
.token.url,
|
.token.url,
|
||||||
.language-css .token.string,
|
.language-css .token.string,
|
||||||
.style .token.string {
|
.style .token.string {
|
||||||
|
background: hsla(0deg, 0%, 100%, 0.5);
|
||||||
color: #9a6e3a;
|
color: #9a6e3a;
|
||||||
background: hsla(0, 0%, 100%, 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.token.atrule,
|
.token.atrule,
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.main .logo {
|
.main .logo {
|
||||||
margin-top: 0;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main .logo a {
|
.main .logo a {
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
|
|
||||||
.main .logo .sub-title {
|
.main .logo .sub-title {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
font-size: 22px;
|
|
||||||
color: #fff;
|
|
||||||
background: linear-gradient(-45deg, #3967ff, #b500fe);
|
background: linear-gradient(-45deg, #3967ff, #b500fe);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 22px;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'mobilefont'; /* Project id 4841764 */
|
font-family: mobilefont; /* Project id 4841764 */
|
||||||
src:
|
src:
|
||||||
url('iconfont.woff2?t=1742102742566') format('woff2'),
|
url('iconfont.woff2?t=1742102742566') format('woff2'),
|
||||||
url('iconfont.woff?t=1742102742566') format('woff'),
|
url('iconfont.woff?t=1742102742566') format('woff'),
|
||||||
@@ -7,133 +7,133 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont {
|
.mobilefont {
|
||||||
font-family: 'mobilefont' !important;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: mobilefont !important;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-rubber:before {
|
.mobilefont-rubber::before {
|
||||||
content: '\ea15';
|
content: '\ea15';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-huabi:before {
|
.mobilefont-huabi::before {
|
||||||
content: '\e61f';
|
content: '\e61f';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-chexiao:before {
|
.mobilefont-chexiao::before {
|
||||||
content: '\e6e2';
|
content: '\e6e2';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-shangchuan:before {
|
.mobilefont-shangchuan::before {
|
||||||
content: '\e613';
|
content: '\e613';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-qingkong:before {
|
.mobilefont-qingkong::before {
|
||||||
content: '\e6dc';
|
content: '\e6dc';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-jiacu:before {
|
.mobilefont-jiacu::before {
|
||||||
content: '\e71d';
|
content: '\e71d';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-qingxie:before {
|
.mobilefont-qingxie::before {
|
||||||
content: '\e71e';
|
content: '\e71e';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-xiahuaxian:before {
|
.mobilefont-xiahuaxian::before {
|
||||||
content: '\e720';
|
content: '\e720';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-tupian:before {
|
.mobilefont-tupian::before {
|
||||||
content: '\e730';
|
content: '\e730';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-del1:before {
|
.mobilefont-del1::before {
|
||||||
content: '\e637';
|
content: '\e637';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-gengduo:before {
|
.mobilefont-gengduo::before {
|
||||||
content: '\e600';
|
content: '\e600';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-delete1:before {
|
.mobilefont-delete1::before {
|
||||||
content: '\e66d';
|
content: '\e66d';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-del:before {
|
.mobilefont-del::before {
|
||||||
content: '\e6f5';
|
content: '\e6f5';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-option:before {
|
.mobilefont-option::before {
|
||||||
content: '\e6ff';
|
content: '\e6ff';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-setting:before {
|
.mobilefont-setting::before {
|
||||||
content: '\e633';
|
content: '\e633';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-add:before {
|
.mobilefont-add::before {
|
||||||
content: '\e686';
|
content: '\e686';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-radiobox:before {
|
.mobilefont-radiobox::before {
|
||||||
content: '\e75b';
|
content: '\e75b';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-juzhendafen:before {
|
.mobilefont-juzhendafen::before {
|
||||||
content: '\e641';
|
content: '\e641';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-checkbox-checked:before {
|
.mobilefont-checkbox-checked::before {
|
||||||
content: '\e6c3';
|
content: '\e6c3';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-nps:before {
|
.mobilefont-nps::before {
|
||||||
content: '\e6b0';
|
content: '\e6b0';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-input:before {
|
.mobilefont-input::before {
|
||||||
content: '\e6fd';
|
content: '\e6fd';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-juzhentiankong:before {
|
.mobilefont-juzhentiankong::before {
|
||||||
content: '\e62e';
|
content: '\e62e';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-wenjianshangchuan:before {
|
.mobilefont-wenjianshangchuan::before {
|
||||||
content: '\e631';
|
content: '\e631';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-qianming:before {
|
.mobilefont-qianming::before {
|
||||||
content: '\e661';
|
content: '\e661';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-tuwen:before {
|
.mobilefont-tuwen::before {
|
||||||
content: '\e62c';
|
content: '\e62c';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-juzhenduoxuan:before {
|
.mobilefont-juzhenduoxuan::before {
|
||||||
content: '\e818';
|
content: '\e818';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-juzhendanxuan:before {
|
.mobilefont-juzhendanxuan::before {
|
||||||
content: '\13c7f';
|
content: '\13c7f';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-edit2:before {
|
.mobilefont-edit2::before {
|
||||||
content: '\e630';
|
content: '\e630';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-copy:before {
|
.mobilefont-copy::before {
|
||||||
content: '\e632';
|
content: '\e632';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-delete:before {
|
.mobilefont-delete::before {
|
||||||
content: '\e63f';
|
content: '\e63f';
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobilefont-sort:before {
|
.mobilefont-sort::before {
|
||||||
content: '\e6a0';
|
content: '\e6a0';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,15 @@ import appBridge from '@/assets/js/appBridge';
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
appBridge.h5RouterBack(router);
|
if (window.history.length > 1) {
|
||||||
|
router.go(-1);
|
||||||
|
} else {
|
||||||
|
appBridge.navigateBack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.common-layout {
|
.common-layout {
|
||||||
//min-height: calc(100vh);
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export const surveyQuestion =
|
export const surveyQuestion
|
||||||
'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';
|
= 'https://yls-api-uat.dctest.digitalyili.com/api/console/surveys/RWNK9BYp/questions';
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ service.interceptors.request.use(
|
|||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
if (
|
if (
|
||||||
response.status === 200 ||
|
response.status === 200
|
||||||
response.status === 201 ||
|
|| response.status === 201
|
||||||
response.status === 202 ||
|
|| response.status === 202
|
||||||
response.status === 204
|
|| response.status === 204
|
||||||
) {
|
) {
|
||||||
if (response.config.method === 'put') {
|
if (response.config.method === 'put') {
|
||||||
// message.success('保存中...');
|
// message.success('保存中...');
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ service.interceptors.request.use(
|
|||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
if (
|
if (
|
||||||
response.status === 200 ||
|
response.status === 200
|
||||||
response.status === 201 ||
|
|| response.status === 201
|
||||||
response.status === 202 ||
|
|| response.status === 202
|
||||||
response.status === 204
|
|| response.status === 204
|
||||||
) {
|
) {
|
||||||
if (response.config.method === 'put') {
|
if (response.config.method === 'put') {
|
||||||
// message.success('保存中...');
|
// message.success('保存中...');
|
||||||
|
|||||||
@@ -52,8 +52,8 @@
|
|||||||
<martrix-question
|
<martrix-question
|
||||||
v-if="
|
v-if="
|
||||||
element.question_type === 8 ||
|
element.question_type === 8 ||
|
||||||
element.question_type === 9 ||
|
element.question_type === 9 ||
|
||||||
element.question_type === 10
|
element.question_type === 10
|
||||||
"
|
"
|
||||||
:element="computedElement(element)"
|
:element="computedElement(element)"
|
||||||
:index="index"
|
:index="index"
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
:index="index"
|
:index="index"
|
||||||
:active="chooseQuestionId === element.id"
|
:active="chooseQuestionId === element.id"
|
||||||
@update:element="updateElement"
|
@update:element="updateElement"
|
||||||
></file-upload>
|
/>
|
||||||
|
|
||||||
<!--图文-->
|
<!--图文-->
|
||||||
<TextWithImages
|
<TextWithImages
|
||||||
|
|||||||
@@ -134,23 +134,23 @@ const openOptionActionModel = (item, index) => {
|
|||||||
// 上下移动
|
// 上下移动
|
||||||
const optionMove = (action) => {
|
const optionMove = (action) => {
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case 'up':
|
case 'up':
|
||||||
if (activeIndex.value === 0) {
|
if (activeIndex.value === 0) {
|
||||||
moveShow.value = false;
|
moveShow.value = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 向上移动
|
// 向上移动
|
||||||
element.value.splice(activeIndex.value - 1, 0, element.value.splice(activeIndex.value, 1)[0]);
|
element.value.splice(activeIndex.value - 1, 0, element.value.splice(activeIndex.value, 1)[0]);
|
||||||
activeIndex.value -= 1;
|
activeIndex.value -= 1;
|
||||||
break;
|
break;
|
||||||
case 'down':
|
case 'down':
|
||||||
if (activeIndex.value === element.value.length - 1) {
|
if (activeIndex.value === element.value.length - 1) {
|
||||||
moveShow.value = false;
|
moveShow.value = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
element.value.splice(activeIndex.value + 1, 0, element.value.splice(activeIndex.value, 1)[0]);
|
element.value.splice(activeIndex.value + 1, 0, element.value.splice(activeIndex.value, 1)[0]);
|
||||||
activeIndex.value += 1;
|
activeIndex.value += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -260,8 +260,8 @@ const getSkipTypeText = (skipType) => {
|
|||||||
const ls = [];
|
const ls = [];
|
||||||
logics.map((item) => {
|
logics.map((item) => {
|
||||||
if (
|
if (
|
||||||
item.skip_type === skipType &&
|
item.skip_type === skipType
|
||||||
item.question_index === activeQuestion.value.question_index
|
&& item.question_index === activeQuestion.value.question_index
|
||||||
) {
|
) {
|
||||||
ls.push(item);
|
ls.push(item);
|
||||||
}
|
}
|
||||||
@@ -277,13 +277,13 @@ const getSkipTypeText = (skipType) => {
|
|||||||
|
|
||||||
const questionSetting = (type) => {
|
const questionSetting = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'before':
|
case 'before':
|
||||||
questionBeforeShow.value = true;
|
questionBeforeShow.value = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'after':
|
case 'after':
|
||||||
questionBeforeShow.value = true;
|
questionBeforeShow.value = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
skipType.value = type === 'before' ? 1 : 0;
|
skipType.value = type === 'before' ? 1 : 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -144,8 +144,8 @@
|
|||||||
<BeforeRate
|
<BeforeRate
|
||||||
v-if="
|
v-if="
|
||||||
log.logic !== 'always' &&
|
log.logic !== 'always' &&
|
||||||
log.is_answer !== 0 &&
|
log.is_answer !== 0 &&
|
||||||
[5, 106].includes(log.question_type)
|
[5, 106].includes(log.question_type)
|
||||||
"
|
"
|
||||||
:activeQuestion="activeQuestion"
|
:activeQuestion="activeQuestion"
|
||||||
:logic="log"
|
:logic="log"
|
||||||
|
|||||||
@@ -108,9 +108,9 @@ function isSurplus() {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
parseFloat(((localConfig.value.max - localConfig.value.min) * 1000).toFixed(4, 10)) %
|
parseFloat(((localConfig.value.max - localConfig.value.min) * 1000).toFixed(4, 10))
|
||||||
parseFloat((localConfig.value.score_interval * 1000).toFixed(4, 10)) ===
|
% parseFloat((localConfig.value.score_interval * 1000).toFixed(4, 10))
|
||||||
0
|
=== 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-field
|
<van-field
|
||||||
v-model="element.stem"
|
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1" label-align="top"
|
||||||
:label="element.stem"
|
|
||||||
:required="element.config.is_required === 1"
|
|
||||||
label-align="top"
|
|
||||||
class="contenteditable-question-title base-select"
|
class="contenteditable-question-title base-select"
|
||||||
>
|
>
|
||||||
<template #left-icon>
|
<template #left-icon>
|
||||||
{{ index + 1 }}
|
{{ index + 1 }}
|
||||||
</template>
|
</template>
|
||||||
<template #label>
|
<template #label>
|
||||||
<contenteditable
|
<contenteditable v-model="element.stem" className="contenteditable-label" :active="active" @blur="emitValue">
|
||||||
v-model="element.stem"
|
</contenteditable>
|
||||||
className="contenteditable-label"
|
|
||||||
:active="active"
|
|
||||||
@blur="emitValue"
|
|
||||||
></contenteditable>
|
|
||||||
</template>
|
</template>
|
||||||
<template #input>
|
<template #input>
|
||||||
<template v-for="(item, optionIndex) in element.options" :key="item.id">
|
<template v-for="(item, optionIndex) in element.options" :key="item.id">
|
||||||
<van-radio-group v-if="element.question_type === 1" v-model="choiceValue">
|
<van-radio-group v-if="element.question_type === 1" v-model="choiceValue">
|
||||||
<option-action
|
<option-action
|
||||||
v-model:data="element.options[optionIndex]"
|
:data="isPreview ? item.options : item" :active="active" :question="element"
|
||||||
:active="active"
|
|
||||||
:question="element"
|
|
||||||
handle=".moverQues"
|
handle=".moverQues"
|
||||||
>
|
>
|
||||||
<template #item="{ element: it, index: itIndex }">
|
<template #item="{ element: it, index: itIndex }">
|
||||||
<van-radio
|
<van-radio
|
||||||
:key="itIndex"
|
:key="itIndex" :name="it.option_index" :label="it.label" :disabled="it.disabled"
|
||||||
:name="it.option_index"
|
|
||||||
:label="it.label"
|
|
||||||
:disabled="it.disabled"
|
|
||||||
icon-size="0.45rem"
|
icon-size="0.45rem"
|
||||||
>
|
>
|
||||||
<!-- 自定义文本 -->
|
<!-- 自定义文本 -->
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex align-center van-cell">
|
<div class="flex align-center van-cell">
|
||||||
<contenteditable
|
<contenteditable v-model="it.option" className="contenteditable-input" :active="active">
|
||||||
v-model="it.option"
|
|
||||||
className="contenteditable-input"
|
|
||||||
:active="active"
|
|
||||||
>
|
|
||||||
<template #right-icon>
|
<template #right-icon>
|
||||||
<div v-if="active" class="moverQues">
|
<div v-if="active" class="moverQues">
|
||||||
<van-icon class-prefix="mobilefont" name="option "></van-icon>
|
<van-icon class-prefix="mobilefont" name="option "></van-icon>
|
||||||
@@ -60,26 +44,17 @@
|
|||||||
|
|
||||||
<van-checkbox-group v-if="element.question_type === 2" v-model="value" shape="square">
|
<van-checkbox-group v-if="element.question_type === 2" v-model="value" shape="square">
|
||||||
<option-action
|
<option-action
|
||||||
v-model:data="element.options[optionIndex]"
|
v-model:data="element.options[optionIndex]" handle=".moverQues" :active="active"
|
||||||
handle=".moverQues"
|
|
||||||
:active="active"
|
|
||||||
:question="element"
|
:question="element"
|
||||||
>
|
>
|
||||||
<template #item="{ element: it, index: itIndex }">
|
<template #item="{ element: it, index: itIndex }">
|
||||||
<van-checkbox
|
<van-checkbox
|
||||||
:key="itIndex"
|
:key="itIndex" :name="it.option_index" :label="it.label" :disabled="it.disabled"
|
||||||
:name="it.option_index"
|
|
||||||
:label="it.label"
|
|
||||||
:disabled="it.disabled"
|
|
||||||
icon-size="0.45rem"
|
icon-size="0.45rem"
|
||||||
>
|
>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex align-center van-cell">
|
<div class="flex align-center van-cell">
|
||||||
<contenteditable
|
<contenteditable v-model="it.option" className="contenteditable-input" :active="active">
|
||||||
v-model="it.option"
|
|
||||||
className="contenteditable-input"
|
|
||||||
:active="active"
|
|
||||||
>
|
|
||||||
<template #right-icon>
|
<template #right-icon>
|
||||||
<div v-if="active" class="moverQues">
|
<div v-if="active" class="moverQues">
|
||||||
<van-icon class-prefix="mobilefont" name="option "></van-icon>
|
<van-icon class-prefix="mobilefont" name="option "></van-icon>
|
||||||
@@ -103,7 +78,12 @@
|
|||||||
import OptionAction from '@/views/Design/components/ActionCompoents/OptionAction.vue';
|
import OptionAction from '@/views/Design/components/ActionCompoents/OptionAction.vue';
|
||||||
import { defineAsyncComponent, toRefs, ref } from 'vue';
|
import { defineAsyncComponent, toRefs, ref } from 'vue';
|
||||||
|
|
||||||
const choiceValue = ref('checked');
|
// 是否是预览
|
||||||
|
const isPreview = defineModel('isPreview', { default: false });
|
||||||
|
const choiceValue = defineModel('answer', { default: '1', type: String });
|
||||||
|
|
||||||
|
console.log(`choiceValue.value`, choiceValue.value);
|
||||||
|
|
||||||
const Contenteditable = defineAsyncComponent(() => import('@/components/contenteditable.vue'));
|
const Contenteditable = defineAsyncComponent(() => import('@/components/contenteditable.vue'));
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
element: {
|
element: {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #input>
|
<template #input>
|
||||||
<textarea
|
<textarea
|
||||||
|
v-model="completionValue"
|
||||||
class="other_input"
|
class="other_input"
|
||||||
:placeholder="element.config.placeholder"
|
:placeholder="element.config.placeholder"
|
||||||
:rows="element.config.line_height"
|
:rows="element.config.line_height"
|
||||||
@@ -29,6 +30,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { toRefs } from 'vue';
|
import { toRefs } from 'vue';
|
||||||
|
|
||||||
|
const completionValue = defineModel('completionValue', { default: '' });
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
element: {
|
element: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ const { element } = toRefs(props);
|
|||||||
*/
|
*/
|
||||||
const tableInputTypeMapping = (/** regx?: any */) => {
|
const tableInputTypeMapping = (/** regx?: any */) => {
|
||||||
switch (element.value.question_type) {
|
switch (element.value.question_type) {
|
||||||
case 8:
|
case 8:
|
||||||
return 'text';
|
return 'text';
|
||||||
case 9:
|
case 9:
|
||||||
return 'radio';
|
return 'radio';
|
||||||
case 10:
|
case 10:
|
||||||
return 'checkbox';
|
return 'checkbox';
|
||||||
default:
|
default:
|
||||||
return 'radio';
|
return 'radio';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,29 +3,23 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<td v-for="col in columns" :key="col.option">
|
<td v-for="col in cols" :key="col.option">
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||||
<input
|
<input
|
||||||
v-if="col.editor"
|
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
@click="handleRowNameChange(col.option!)"
|
||||||
/>
|
/>
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option" />
|
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||||
<th v-html="row.option" />
|
<th v-html="row.option"></th>
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
<td v-for="(col, colIndex) in cols" :key="colIndex">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox" :name="`R${rowIndex + 1}`" :value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
:checked="isOptionChecked(rowIndex, colIndex)" @change="handleMatrixRadioChange(rowIndex, colIndex)"
|
||||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
|
||||||
@change="handleColNameChange(row.option, col.option, $event)"
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -37,50 +31,73 @@
|
|||||||
import { defineProps } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import { vFocus } from '@/utils/directives/useVFocus';
|
||||||
|
|
||||||
const props = defineProps<{
|
// 记录行和列的索引
|
||||||
rows: { option: string }[];
|
const rowRecord = defineModel<number[][]>('rowRecord', { required: false, default: () => [] });
|
||||||
columns: { option: string; editor?: boolean }[];
|
// const matrixAnswer = defineModel<{ [key: string]: 1 }>('matrixAnswer', { required: false, default: () => ({}) });
|
||||||
questionType: number;
|
// 检查 rowRecord 是否存在
|
||||||
matrixAnswer: { [key: string]: any };
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
rowRecord: (number | string)[];
|
|
||||||
|
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
|
defineProps<{
|
||||||
|
rows: OptionType[];
|
||||||
|
cols: OptionType[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
/* const emits = */ defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||||
|
|
||||||
|
// 判断是否选中
|
||||||
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
// [
|
||||||
return !!props.matrixAnswer[key];
|
// [0, 1],
|
||||||
|
// [0, 1]
|
||||||
|
// ]
|
||||||
|
if (!rowRecord.value[rowIndex]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return rowRecord.value[rowIndex].includes(colIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRowNameChange = () => {
|
const handleRowNameChange = (/* value: string */) => {
|
||||||
|
// console.log(`row change: ${value}`);
|
||||||
// 你可以在这里添加其他逻辑
|
// 你可以在这里添加其他逻辑
|
||||||
};
|
};
|
||||||
|
|
||||||
// const handleColNameChange = (rowOption: string, colOption: string, e: Event) => {
|
// 当 matrix radio 选中时,更新 rowRecord 和 matrixAnswer
|
||||||
// const target = e.target as HTMLInputElement;
|
function handleMatrixRadioChange(row: number, col: number) {
|
||||||
// const col = props.columns.findIndex(option => option.option === colOption);
|
// 获取 colIndexArray
|
||||||
// const row = props.rows.findIndex(option => option.option === rowOption);
|
if (!rowRecord.value[row]) {
|
||||||
//
|
// 如果没有对应的row,创建一个
|
||||||
// if (props.questionType === 10) {
|
rowRecord.value[row] = [];
|
||||||
// if (target.checked) {
|
}
|
||||||
// props.rowRecord[col] = (props.rowRecord[col] || []).concat(row + 1);
|
// cols 的逻辑 和 handleMatrixRadioChange 一致
|
||||||
// } else {
|
const cols = rowRecord.value[row];
|
||||||
// props.rowRecord[col] = (props.rowRecord[col] || []).filter(item => item !== row + 1);
|
|
||||||
// }
|
// 检查 cols 对应的 col 是否有 数值
|
||||||
// const newMatrixAnswer: { [key: string]: boolean } = {};
|
if (cols.includes(col)) {
|
||||||
// const newRowRecord: (number | string)[] = [...props.rowRecord];
|
// 如果有,删除
|
||||||
// props.rows.forEach((rowOption, rowIndex) => {
|
cols.splice(cols.indexOf(col), 1);
|
||||||
// const colOptions = newRowRecord[rowIndex];
|
} else {
|
||||||
// if (colOptions) {
|
// 如果没有,添加
|
||||||
// colOptions.forEach((col: any) => {
|
cols.push(col);
|
||||||
// newMatrixAnswer[`R${rowIndex + 1}_C${col}`] = true;
|
}
|
||||||
// });
|
|
||||||
// }
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
// });
|
}
|
||||||
// }
|
// const handleColNameChange = (rowOption: string, colOption: string) => {
|
||||||
//
|
// // const target = e.target as HTMLInputElement;
|
||||||
// emits('update:matrixAnswer', newMatrixAnswer);
|
// const col = props.columns.findIndex((option) => option.option === colOption);
|
||||||
// emits('update:rowRecord', newRowRecord);
|
// const row = props.rows.findIndex((option) => option.option === rowOption);
|
||||||
|
|
||||||
|
// if (props.questionType === 9) {
|
||||||
|
// props.rowRecord[col] = row + 1;
|
||||||
|
// props.matrixAnswer = {};
|
||||||
|
// props.rowRecord.forEach((row, index) => {
|
||||||
|
// props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||||
|
// emits('update:rowRecord', props.rowRecord);
|
||||||
// };
|
// };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ const matrixAnswer = ref({
|
|||||||
*/
|
*/
|
||||||
const tableInputTypeMapping = (/** regx?: any */) => {
|
const tableInputTypeMapping = (/** regx?: any */) => {
|
||||||
switch (element.question_type) {
|
switch (element.question_type) {
|
||||||
case 8:
|
case 8:
|
||||||
return 'text';
|
return 'text';
|
||||||
case 9:
|
case 9:
|
||||||
return 'radio';
|
return 'radio';
|
||||||
case 10:
|
case 10:
|
||||||
return 'checkbox';
|
return 'checkbox';
|
||||||
default:
|
default:
|
||||||
return 'radio';
|
return 'radio';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,55 +67,55 @@ function handleColNameChange(rowOption: string, colOption: string, e: any) {
|
|||||||
|
|
||||||
// 不同的 question_type 的 matrix 问卷处理不同的结果
|
// 不同的 question_type 的 matrix 问卷处理不同的结果
|
||||||
switch (element.question_type) {
|
switch (element.question_type) {
|
||||||
case 8: {
|
case 8: {
|
||||||
// 获取输入框元素
|
// 获取输入框元素
|
||||||
const inputElement = e.target as HTMLInputElement;
|
const inputElement = e.target as HTMLInputElement;
|
||||||
// 如果没有获取到输入框元素,则直接返回
|
// 如果没有获取到输入框元素,则直接返回
|
||||||
if (!inputElement) return;
|
if (!inputElement) return;
|
||||||
// 将输入框的值保存到 rowRecord 对应位置
|
// 将输入框的值保存到 rowRecord 对应位置
|
||||||
rowRecord[col] = e!.target!.value;
|
rowRecord[col] = e!.target!.value;
|
||||||
// 清空 matrixAnswer 的 answer 属性
|
// 清空 matrixAnswer 的 answer 属性
|
||||||
matrixAnswer.value.answer = {};
|
matrixAnswer.value.answer = {};
|
||||||
// 遍历所有行选项
|
// 遍历所有行选项
|
||||||
element.options[0].forEach((_, rowIndex) => {
|
element.options[0].forEach((_, rowIndex) => {
|
||||||
// 获取当前行记录
|
// 获取当前行记录
|
||||||
const colOptions = rowRecord[rowIndex];
|
const colOptions = rowRecord[rowIndex];
|
||||||
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
|
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
|
||||||
if (colOptions) {
|
if (colOptions) {
|
||||||
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col + 1}`] = colOptions;
|
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col + 1}`] = colOptions;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 9:
|
case 9:
|
||||||
// 将选择的行索引加1后保存到 rowRecord 对应位置
|
// 将选择的行索引加1后保存到 rowRecord 对应位置
|
||||||
rowRecord[col] = row + 1;
|
rowRecord[col] = row + 1;
|
||||||
// 清空 matrixAnswer 的 answer 属性
|
// 清空 matrixAnswer 的 answer 属性
|
||||||
matrixAnswer.value.answer = {};
|
matrixAnswer.value.answer = {};
|
||||||
// 遍历 rowRecord,更新 matrixAnswer 的 answer 属性
|
// 遍历 rowRecord,更新 matrixAnswer 的 answer 属性
|
||||||
rowRecord.forEach((row, index) => {
|
rowRecord.forEach((row, index) => {
|
||||||
matrixAnswer.value.answer[`${index + 1}_${row}`] = 1;
|
matrixAnswer.value.answer[`${index + 1}_${row}`] = 1;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
// 将选择的行索引加1后添加到 rowRecord 对应位置的数组中
|
// 将选择的行索引加1后添加到 rowRecord 对应位置的数组中
|
||||||
rowRecord[col] = (rowRecord[col] || []).concat(row + 1);
|
rowRecord[col] = (rowRecord[col] || []).concat(row + 1);
|
||||||
// 清空 matrixAnswer 的 answer 属性
|
// 清空 matrixAnswer 的 answer 属性
|
||||||
matrixAnswer.value.answer = {};
|
matrixAnswer.value.answer = {};
|
||||||
// 遍历所有行选项
|
// 遍历所有行选项
|
||||||
element.options[0].forEach((rowOption, rowIndex) => {
|
element.options[0].forEach((rowOption, rowIndex) => {
|
||||||
// 获取当前行记录
|
// 获取当前行记录
|
||||||
const colOptions = rowRecord[rowIndex];
|
const colOptions = rowRecord[rowIndex];
|
||||||
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
|
// 如果当前行有记录,则更新 matrixAnswer 的 answer 属性
|
||||||
if (colOptions) {
|
if (colOptions) {
|
||||||
colOptions.forEach((col: any) => {
|
colOptions.forEach((col: any) => {
|
||||||
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col}`] = true;
|
matrixAnswer.value.answer[`R${rowIndex + 1}_C${col}`] = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,14 +3,10 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<td v-for="col in columns" :key="col.option">
|
<td v-for="col in cols" :key="col.option">
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||||
<input
|
<input
|
||||||
v-if="col.editor"
|
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
@click="handleRowNameChange(col.option!)"
|
||||||
/>
|
/>
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||||
@@ -20,13 +16,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||||
<th v-html="row.option"></th>
|
<th v-html="row.option"></th>
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
<td v-for="(col, colIndex) in cols" :key="colIndex">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio" :name="`R${rowIndex + 1}`" :value="`${rowIndex + 1}_${colIndex + 1}`"
|
||||||
:name="`R${rowIndex + 1}`"
|
:checked="isOptionChecked(rowIndex, colIndex)" @change="handleMatrixRadioChange(rowIndex, colIndex)"
|
||||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
|
||||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
|
||||||
@change="handleColNameChange(row.option, col.option, $event)"
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -38,19 +31,28 @@
|
|||||||
import { defineProps } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import { vFocus } from '@/utils/directives/useVFocus';
|
||||||
|
|
||||||
const props = defineProps<{
|
// 记录行和列的索引
|
||||||
rows: { option: string }[];
|
const rowRecord = defineModel<number[]>('rowRecord', { required: false, default: () => [] });
|
||||||
columns: { option: string; editor?: boolean }[];
|
// const matrixAnswer = defineModel<{ [key: string]: 1 }>('matrixAnswer', { required: false, default: () => ({}) });
|
||||||
questionType: number;
|
// 检查 rowRecord 是否存在
|
||||||
matrixAnswer: { [key: string]: any };
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
rowRecord: (number | string)[];
|
|
||||||
|
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
|
defineProps<{
|
||||||
|
rows: OptionType[];
|
||||||
|
cols: OptionType[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
/* const emits = */ defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||||
|
|
||||||
|
// 判断是否选中
|
||||||
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
const isOptionChecked = (rowIndex: number, colIndex: number): boolean => {
|
||||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
// console.log(`rowIndex: ${rowIndex}, colIndex: ${colIndex}`);
|
||||||
return !!props.matrixAnswer[key];
|
// console.log(`rowRecord.value[rowIndex] === colIndex`, rowRecord.value[rowIndex] === colIndex);
|
||||||
|
|
||||||
|
return rowRecord.value[rowIndex] === colIndex;
|
||||||
|
// const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
||||||
|
// return !!matrixAnswer.value?.[key];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRowNameChange = (/* value: string */) => {
|
const handleRowNameChange = (/* value: string */) => {
|
||||||
@@ -58,21 +60,29 @@ const handleRowNameChange = (/* value: string */) => {
|
|||||||
// 你可以在这里添加其他逻辑
|
// 你可以在这里添加其他逻辑
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 当 matrix radio 选中时,更新 rowRecord 和 matrixAnswer
|
||||||
|
function handleMatrixRadioChange(row: number, col: number) {
|
||||||
|
rowRecord.value[row] = col;
|
||||||
|
// matrixAnswer.value = {};
|
||||||
|
// rowRecord.value.forEach((row, col) => {
|
||||||
|
// matrixAnswer.value[`${col + 1}_${row}`] = 1;
|
||||||
|
// });
|
||||||
|
}
|
||||||
// const handleColNameChange = (rowOption: string, colOption: string) => {
|
// const handleColNameChange = (rowOption: string, colOption: string) => {
|
||||||
// // const target = e.target as HTMLInputElement;
|
// // const target = e.target as HTMLInputElement;
|
||||||
// const col = props.columns.findIndex((option) => option.option === colOption);
|
// const col = props.columns.findIndex((option) => option.option === colOption);
|
||||||
// const row = props.rows.findIndex((option) => option.option === rowOption);
|
// const row = props.rows.findIndex((option) => option.option === rowOption);
|
||||||
//
|
|
||||||
// if (props.questionType === 9) {
|
// if (props.questionType === 9) {
|
||||||
// props.rowRecord[col] = row + 1;
|
// props.rowRecord[col] = row + 1;
|
||||||
// props.matrixAnswer = {};
|
// props.matrixAnswer = {};
|
||||||
// props.rowRecord.forEach((row, index) => {
|
// props.rowRecord.forEach((row, index) => {
|
||||||
// props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
// props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// emits('update:matrixAnswer', props.matrixAnswer);
|
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||||
// emits('update:rowRecord', props.rowRecord);
|
// emits('update:rowRecord', props.rowRecord);
|
||||||
// };
|
// };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,10 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<td v-for="col in columns" :key="col.option">
|
<td v-for="col in cols" :key="col.option">
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
||||||
<input
|
<input
|
||||||
v-if="col.editor"
|
v-if="col.editor" v-model="col.option" v-focus type="text" @focusout="col.editor = false"
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
@click="handleRowNameChange(col.option!)"
|
||||||
/>
|
/>
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
||||||
@@ -20,11 +16,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||||
<th v-html="row.option"></th>
|
<th v-html="row.option"></th>
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
<td v-for="(col, colIndex) in cols" :key="colIndex">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text" :name="`R${rowIndex + 1}`" :value="getInputValue(rowIndex, colIndex)"
|
||||||
:value="matrixAnswer[`${rowIndex + 1}_${colIndex + 1}`]"
|
@change="handleMatrixTextChange(rowIndex, colIndex, $event)"
|
||||||
@change="handleColNameChange(row.option, col.option, $event, rowIndex, colIndex)"
|
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -33,36 +28,66 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineProps, defineEmits } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import { vFocus } from '@/utils/directives/useVFocus';
|
||||||
|
|
||||||
const props = defineProps<{
|
// 记录行和列的索引
|
||||||
rows: { option: string }[];
|
const rowRecord = defineModel<string[][]>('rowRecord', { required: false, default: () => [] });
|
||||||
columns: { option: string; editor?: boolean }[];
|
// const matrixAnswer = defineModel<{ [key: string]: 1 }>('matrixAnswer', { required: false, default: () => ({}) });
|
||||||
questionType: number;
|
// 检查 rowRecord 是否存在
|
||||||
matrixAnswer: { [key: string]: any };
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
|
|
||||||
|
/* const isPreview = */defineModel<boolean>('isPreview', { required: false, default: false });
|
||||||
|
defineProps<{
|
||||||
|
rows: OptionType[];
|
||||||
|
cols: OptionType[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emits = defineEmits(['update:matrixAnswer']);
|
// const emits = defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
||||||
|
|
||||||
const handleRowNameChange = (/* value: string */) => {
|
const handleRowNameChange = (/* value: string */) => {
|
||||||
// console.log(`row change: ${value}`);
|
// console.log(`row change: ${value}`);
|
||||||
// 你可以在这里添加其他逻辑
|
// 你可以在这里添加其他逻辑
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleColNameChange = (
|
function getInputValue(row: number, col: number) {
|
||||||
rowOption: string,
|
console.log(`row: ${row}, col: ${col}`);
|
||||||
colOption: string,
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
e: Event,
|
|
||||||
rowIndex: number,
|
|
||||||
colIndex: number
|
|
||||||
) => {
|
|
||||||
const target = e.target as HTMLInputElement;
|
|
||||||
const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
|
||||||
const newMatrixAnswer = { ...props.matrixAnswer, [key]: target.value };
|
|
||||||
|
|
||||||
emits('update:matrixAnswer', newMatrixAnswer);
|
return rowRecord.value?.[row]?.[col] ?? '';
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// 当 matrix text 选中时,更新 rowRecord 和 matrixAnswer
|
||||||
|
function handleMatrixTextChange(row: number, col: number, e: Event) {
|
||||||
|
const target = e.target as HTMLInputElement;
|
||||||
|
const inputValue = target.value;
|
||||||
|
|
||||||
|
// 获取 colIndexArray
|
||||||
|
if (!rowRecord.value[row]) {
|
||||||
|
// 如果没有对应的row,创建一个
|
||||||
|
rowRecord.value[row] = [];
|
||||||
|
}
|
||||||
|
// cols 的逻辑 和 handleMatrixRadioChange 一致
|
||||||
|
const cols = rowRecord.value[row];
|
||||||
|
cols[col] = inputValue;
|
||||||
|
console.log(`rowRecord:`, rowRecord.value);
|
||||||
|
}
|
||||||
|
// const handleColNameChange = (rowOption: string, colOption: string) => {
|
||||||
|
// // const target = e.target as HTMLInputElement;
|
||||||
|
// const col = props.columns.findIndex((option) => option.option === colOption);
|
||||||
|
// const row = props.rows.findIndex((option) => option.option === rowOption);
|
||||||
|
|
||||||
|
// if (props.questionType === 9) {
|
||||||
|
// props.rowRecord[col] = row + 1;
|
||||||
|
// props.matrixAnswer = {};
|
||||||
|
// props.rowRecord.forEach((row, index) => {
|
||||||
|
// props.matrixAnswer[`${index + 1}_${row}`] = 1;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// emits('update:matrixAnswer', props.matrixAnswer);
|
||||||
|
// emits('update:rowRecord', props.rowRecord);
|
||||||
|
// };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<van-field
|
<van-field
|
||||||
v-model="element.stem"
|
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1"
|
||||||
:label="element.stem"
|
|
||||||
:required="element.config.is_required === 1"
|
|
||||||
label-align="top"
|
label-align="top"
|
||||||
>
|
>
|
||||||
<template #left-icon>
|
<template #left-icon>
|
||||||
@@ -13,12 +11,13 @@
|
|||||||
<contenteditable v-model="element.stem" :active="active" @blur="saveStem"></contenteditable>
|
<contenteditable v-model="element.stem" :active="active" @blur="saveStem"></contenteditable>
|
||||||
</template>
|
</template>
|
||||||
<template #input>
|
<template #input>
|
||||||
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
<div v-for="(optionItem, optionItemIndex) in isPreview ? element.list : element.options" :key="optionItemIndex">
|
||||||
<div
|
<div
|
||||||
v-for="(item, optionIndex) in optionItem"
|
v-for="(item, optionIndex) in isPreview ? optionItem.options : optionItem" :key="optionIndex"
|
||||||
:key="optionIndex"
|
|
||||||
@click="chooseOption(item)"
|
@click="chooseOption(item)"
|
||||||
>
|
>
|
||||||
|
<RateCharacter v-model="rate" :index="optionIndex" :config="element.config" @change="handleRateChange">
|
||||||
|
</RateCharacter>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<p>{{ element.config.prompt_left }}</p>
|
<p>{{ element.config.prompt_left }}</p>
|
||||||
<p>{{ element.config.prompt_center }}</p>
|
<p>{{ element.config.prompt_center }}</p>
|
||||||
@@ -36,6 +35,7 @@
|
|||||||
import { ref, toRefs } from 'vue';
|
import { ref, toRefs } from 'vue';
|
||||||
import RateCharacter from './RateCharacter.vue';
|
import RateCharacter from './RateCharacter.vue';
|
||||||
|
|
||||||
|
const isPreview = defineModel('isPreview', { default: false });
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
element: {
|
element: {
|
||||||
type: Object
|
type: Object
|
||||||
@@ -51,6 +51,36 @@ const props = defineProps({
|
|||||||
sn: { type: String, default: '' },
|
sn: { type: String, default: '' },
|
||||||
questionType: { type: [String, Number], default: 4 }
|
questionType: { type: [String, Number], default: 4 }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// answer 的答案以 矩阵形式存储, 例如 [4,7],上层更新答案的时候也容易
|
||||||
|
const rates = defineModel('rates', { default: [] });
|
||||||
|
const rate = ref(0);
|
||||||
|
|
||||||
|
// 不知道的 BUG ,开始的时候不能重置颜色。 故如此
|
||||||
|
setTimeout(() => {
|
||||||
|
rate.value = localStorage.getItem(props.sn);
|
||||||
|
console.log(`rate value:`, rate.value);
|
||||||
|
// if (rates.value[0] !== undefined) {
|
||||||
|
// console.log(`rates value:`, rates.value);
|
||||||
|
// rate.value = rates.value[0]
|
||||||
|
// }
|
||||||
|
// else return
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param index {number} 索引
|
||||||
|
* @param rate {number} 具体数值
|
||||||
|
*/
|
||||||
|
function handleRateChange(index, rate) {
|
||||||
|
// 如果没有查询到对应索引的数值, 那么就直接push一个,直到有数值为止
|
||||||
|
while (rates.value.length < index) {
|
||||||
|
rates.value.push(NaN);
|
||||||
|
}
|
||||||
|
rates.value[index] = rate;
|
||||||
|
localStorage.setItem(props.sn, rate.value);
|
||||||
|
}
|
||||||
|
|
||||||
const { element } = toRefs(props);
|
const { element } = toRefs(props);
|
||||||
const chooseId = ref('');
|
const chooseId = ref('');
|
||||||
const emit = defineEmits(['update:element']);
|
const emit = defineEmits(['update:element']);
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul :key="test">
|
||||||
<li
|
<li
|
||||||
v-for="(rate, rateIndex) in rateItem"
|
v-for="(rate, rateIndex) in rateItem" :key="rateIndex" class="rate_item" :class="{ active_item: rate.active }"
|
||||||
:key="rateIndex"
|
|
||||||
class="rate_item"
|
|
||||||
:class="{ active_item: rate.active }"
|
|
||||||
@click="getItem(rate)"
|
@click="getItem(rate)"
|
||||||
>
|
>
|
||||||
{{ rate.label }}
|
{{ rate.label }}
|
||||||
@@ -40,6 +37,11 @@ const rateItem = ref([
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const test = ref(1);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
test.value = 2;
|
||||||
|
}, 300);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
config: {
|
config: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -49,6 +51,8 @@ const props = defineProps({
|
|||||||
|
|
||||||
const model = defineModel();
|
const model = defineModel();
|
||||||
|
|
||||||
|
const index = defineModel('index');
|
||||||
|
const emit = defineEmits(['change']);
|
||||||
const renderScore = (min, max, interval) => {
|
const renderScore = (min, max, interval) => {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (let i = min; i <= max; i += interval) {
|
for (let i = min; i <= max; i += interval) {
|
||||||
@@ -64,15 +68,18 @@ const renderScore = (min, max, interval) => {
|
|||||||
rateItem.value = result;
|
rateItem.value = result;
|
||||||
};
|
};
|
||||||
// 重置颜色
|
// 重置颜色
|
||||||
const getItem = (value) => {
|
function getItem(value) {
|
||||||
model.value = value.label;
|
model.value = value.label;
|
||||||
rateItem.value.forEach((item, index) => {
|
rateItem.value.forEach((item, index) => {
|
||||||
rateItem.value[index].active = item.label <= value.label;
|
rateItem.value[index].active = item.label <= value.label;
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
watch(model, () => {
|
watch(model, () => {
|
||||||
getItem({ label: model.value, active: false });
|
getItem({ label: model.value, active: false });
|
||||||
|
emit('change', index.value, model.value);
|
||||||
|
}, {
|
||||||
|
// immediate: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听 min、max 和 score_interval 的变化
|
// 监听 min、max 和 score_interval 的变化
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
class="iconfont active-icon"
|
class="iconfont active-icon"
|
||||||
:style="{ marginRight: isLastPage ? '0' : '16px' }"
|
:style="{ marginRight: isLastPage ? '0' : '16px' }"
|
||||||
@click="activePage"
|
@click="activePage"
|
||||||
></i
|
></i>
|
||||||
>
|
|
||||||
<template v-if="!isLastPage">
|
<template v-if="!isLastPage">
|
||||||
<i class="iconfont moverQues" style="margin-right: 16px"></i>
|
<i class="iconfont moverQues" style="margin-right: 16px"></i>
|
||||||
<i class="iconfont" @click="deleteHandle"></i>
|
<i class="iconfont" @click="deleteHandle"></i>
|
||||||
|
|||||||
@@ -38,11 +38,12 @@ type questionsList = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type question = {
|
type question = {
|
||||||
|
answer?: unknown;
|
||||||
id?: string;
|
id?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
stem?: string;
|
stem?: string;
|
||||||
other?: string;
|
other?: string;
|
||||||
list: questionsList[][];
|
list: questionsList[];
|
||||||
question_index?: number;
|
question_index?: number;
|
||||||
question_type?: number;
|
question_type?: number;
|
||||||
config?: Config;
|
config?: Config;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const router = useRouter();
|
|||||||
const contentShow = ref(false);
|
const contentShow = ref(false);
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async() => {
|
||||||
contentShow.value = true;
|
contentShow.value = true;
|
||||||
// if (utils.getSessionStorage('xToken')) {
|
// if (utils.getSessionStorage('xToken')) {
|
||||||
// const appToken = utils.getParameter('digitalYiliToken');
|
// const appToken = utils.getParameter('digitalYiliToken');
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import { consoleSurveys } from '@/api/home/index.js';
|
|||||||
const survey = ref({
|
const survey = ref({
|
||||||
project_name: ''
|
project_name: ''
|
||||||
});
|
});
|
||||||
const fetchSurveys = async () => {
|
const fetchSurveys = async() => {
|
||||||
const params = {
|
const params = {
|
||||||
page: 1,
|
page: 1,
|
||||||
per_page: 10,
|
per_page: 10,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const marketList = ref([]);
|
|||||||
const active = ref(null);
|
const active = ref(null);
|
||||||
const marketInfo = ref([]);
|
const marketInfo = ref([]);
|
||||||
|
|
||||||
const getTableList = async () => {
|
const getTableList = async() => {
|
||||||
const res = await getListScene();
|
const res = await getListScene();
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
res.data.data.forEach((item) => {
|
res.data.data.forEach((item) => {
|
||||||
@@ -32,7 +32,7 @@ const getTableList = async () => {
|
|||||||
getMarketInfo(marketList.value[0]);
|
getMarketInfo(marketList.value[0]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const getMarketInfo = async (item) => {
|
const getMarketInfo = async(item) => {
|
||||||
const code = marketList.value.filter((market, index) => item === index)[0].code;
|
const code = marketList.value.filter((market, index) => item === index)[0].code;
|
||||||
const params = {
|
const params = {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
<div v-for="item in 10" :key="item" class="template">
|
<div v-for="item in 10" :key="item" class="template">
|
||||||
<img src="https://picsum.photos/131/128" width="110" height="100" alt="" />
|
<img src="https://picsum.photos/131/128" width="110" height="100" alt="" />
|
||||||
<span>报名/签到模板</span>
|
<span>报名/签到模板</span>
|
||||||
<span style="color: rgb(127, 127, 127)"
|
<span style="color: rgb(127, 127, 127)">报名签到 | 引用 {{ item }} 次 | 创建人: {{ '张三' }}</span>
|
||||||
>报名签到 | 引用 {{ item }} 次 | 创建人: {{ '张三' }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -105,8 +105,7 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
|
|||||||
top: 0;
|
top: 0;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
padding: 28px 13px 19px 7px;
|
padding: 28px 13px 19px 7px;
|
||||||
background: url('https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbb370d01215f9cedc28d567c637c011047f83a99fbb5e7ac348ebd0ef0015f32')
|
background: url('https://lanhu-oss-2537-2.lanhuapp.com/SketchPngbb370d01215f9cedc28d567c637c011047f83a99fbb5e7ac348ebd0ef0015f32') 100% no-repeat;
|
||||||
100% no-repeat;
|
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
||||||
@@ -130,7 +129,7 @@ import { Io5EllipsisHorizontalSharp } from 'vue-icons-plus/io5';
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > :nth-child(2) {
|
&> :nth-child(2) {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
|
|||||||
@@ -299,6 +299,7 @@
|
|||||||
:config="question.config"
|
:config="question.config"
|
||||||
:question="question"
|
:question="question"
|
||||||
isMobile
|
isMobile
|
||||||
|
:questionIndex="question.question_index"
|
||||||
@change-answer="onRelation($event, question)"
|
@change-answer="onRelation($event, question)"
|
||||||
/>
|
/>
|
||||||
<!-- <!– 地理位置题 –>-->
|
<!-- <!– 地理位置题 –>-->
|
||||||
|
|||||||
@@ -227,8 +227,8 @@ export default defineComponent({
|
|||||||
.map((option) => {
|
.map((option) => {
|
||||||
return this.wares.find(
|
return this.wares.find(
|
||||||
(ware) =>
|
(ware) =>
|
||||||
ware.question_index === option.question_index &&
|
ware.question_index === option.question_index
|
||||||
ware.option_index === option.option_index
|
&& ware.option_index === option.option_index
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
wares = wares.filter((x) => x);
|
wares = wares.filter((x) => x);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
debounce(func, wait) {
|
debounce(func, wait) {
|
||||||
let timeout;
|
let timeout;
|
||||||
return function (...args) {
|
return function(...args) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
timeout = setTimeout(() => func.apply(this, args), wait);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,341 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-field
|
<choice v-model:answer="choiceValue" :element="question" :index="answerIndex" :is-preview="true" />
|
||||||
v-model="stem"
|
|
||||||
:label="element.stem"
|
|
||||||
:required="element.config.is_required === 1"
|
|
||||||
label-align="top"
|
|
||||||
class="base-select"
|
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
|
|
||||||
</template>
|
|
||||||
<template #input>
|
|
||||||
<template v-for="listItem in list" :key="listItem.options">
|
|
||||||
<template v-for="(option, optionIndex) in listItem.options" :key="option.option">
|
|
||||||
<!-- 单选题 -->
|
|
||||||
<van-radio-group v-if="question?.question_type === 1" v-model="choiceValue">
|
|
||||||
<van-radio :name="optionIndex">{{ getDomText(option.option!) }}</van-radio>
|
|
||||||
</van-radio-group>
|
|
||||||
<!-- 多选题 -->
|
|
||||||
<van-checkbox-group
|
|
||||||
v-else-if="question!.question_type! === 2"
|
|
||||||
v-model="choiceValue"
|
|
||||||
shape="square"
|
|
||||||
>
|
|
||||||
<van-checkbox :name="optionIndex">{{ getDomText(option.option!) }}</van-checkbox>
|
|
||||||
</van-checkbox-group>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineAsyncComponent, ref, watch } from 'vue';
|
import { watch, ref } from 'vue';
|
||||||
import { getDomText } from '@/utils/utils';
|
import Choice from '@/views/Design/components/Questions/Choice.vue';
|
||||||
|
|
||||||
|
type answerType = {
|
||||||
|
options: any[];
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
// // 预览新增 v-model
|
// // 预览新增 v-model
|
||||||
const answer = defineModel('answer');
|
const answer = defineModel<answerType>('answer', { default: undefined });
|
||||||
// const answerIndex = defineModel('answerIndex');
|
const answerIndex = defineModel<number>('answerIndex');
|
||||||
const stem = defineModel('stem');
|
// const stem = defineModel<string>('stem', { default: '' });4
|
||||||
const question = defineModel<question>('question', {});
|
const question = defineModel<question>('question', { default: { config: { is_required: false } } });
|
||||||
const list = defineModel<questionsList[]>('list');
|
const list = defineModel<questionsList[]>('list', { default: [[]] });
|
||||||
|
|
||||||
|
const choiceValue = ref<string>((answer.value?.value - 1).toString() ?? '0');
|
||||||
|
|
||||||
|
// 初始化数据,因为 preview 的数据源和 element 的数据源不相同, 所以需要配置一遍数据
|
||||||
|
initData();
|
||||||
|
function initData() {
|
||||||
|
question.value.options = list.value;
|
||||||
|
}
|
||||||
// // 预览新增 emit ['changeAnswer', 'previous', 'next']
|
// // 预览新增 emit ['changeAnswer', 'previous', 'next']
|
||||||
const emit = defineEmits(['update:element', 'changeAnswer', 'previous', 'next', 'update:element']);
|
const emit = defineEmits(['update:element', 'changeAnswer', 'previous', 'next', 'update:element']);
|
||||||
|
|
||||||
// 用戶選擇的答案
|
watch(
|
||||||
const choiceValue = ref(answer.value?.value - 1 ?? undefined);
|
() => choiceValue.value,
|
||||||
const Contenteditable = defineAsyncComponent(() => import('@/components/contenteditable.vue'));
|
() => {
|
||||||
|
const res = {
|
||||||
// console.log(`choice question.value:`, question.value);
|
options: list.value.flatMap((group) => group.options || []),
|
||||||
watch(choiceValue, () => {
|
value: Number(choiceValue.value) + 1
|
||||||
answer.value = {
|
};
|
||||||
options: list.value.flatMap((group) => group.options || []),
|
answer.value = res;
|
||||||
value: choiceValue.value + 1
|
emit('changeAnswer', res);
|
||||||
};
|
}
|
||||||
// console.log(answer.value);
|
);
|
||||||
|
|
||||||
// 需要在 question 里面附加 answer 信息
|
|
||||||
// question.value[`answer`] =
|
|
||||||
emit('changeAnswer', {
|
|
||||||
options: list.value.flatMap((group) => group.options || []),
|
|
||||||
value: choiceValue.value + 1
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// console.log(`question:`, question.value);
|
|
||||||
// console.log(`list: `, list.value);
|
|
||||||
// const props = defineProps({
|
|
||||||
// // 预览新增 props
|
|
||||||
// config: {
|
|
||||||
// type: Object,
|
|
||||||
// default: () => {
|
|
||||||
// return {};
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// hideOptions: {
|
|
||||||
// type: Object,
|
|
||||||
// default: () => {
|
|
||||||
// return {};
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// answerSn: {
|
|
||||||
// type: String,
|
|
||||||
// default: ''
|
|
||||||
// },
|
|
||||||
// answerSurveySn: {
|
|
||||||
// type: String,
|
|
||||||
// default: ''
|
|
||||||
// },
|
|
||||||
// // 原先 props
|
|
||||||
// element: {
|
|
||||||
// type: Object,
|
|
||||||
// default: () => {
|
|
||||||
// return {
|
|
||||||
// config: {
|
|
||||||
// is_required: undefined
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// active: {
|
|
||||||
// type: Boolean,
|
|
||||||
// default: false
|
|
||||||
// },
|
|
||||||
// index: {
|
|
||||||
// type: Number,
|
|
||||||
// default: 0
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// initData();
|
|
||||||
//
|
|
||||||
// function initData() {
|
|
||||||
// // 当预览时, 某些数据可能不存在
|
|
||||||
// // 若 element有些数据不存在, 默认去 props 里面 取值
|
|
||||||
// !props.element.stem && (props.element.stem = stem.value);
|
|
||||||
//
|
|
||||||
// !props.element.options && (props.element.stem = stem.value);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log(`props.element`, props.element);
|
|
||||||
// console.log(`props.question: `, question.value);
|
|
||||||
// const { element } = toRefs(props);
|
|
||||||
|
|
||||||
const emitValue = () => {
|
|
||||||
// emit('update:element', element.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// const value = ref(''); // 值
|
|
||||||
// const options = ref([]); // 选项
|
|
||||||
// const optionGroups = ref([]); // 分组
|
|
||||||
//
|
|
||||||
// console.log(`radio input question: `, props.question);
|
|
||||||
//
|
|
||||||
// // 初始化
|
|
||||||
// function init() {
|
|
||||||
// props.list.forEach((list) => {
|
|
||||||
// options.value = [...options.value, ...list.options];
|
|
||||||
// });
|
|
||||||
// if (props.answer) {
|
|
||||||
// value.value = Object.keys(props.answer)[0];
|
|
||||||
// options.value.forEach((option) => {
|
|
||||||
// if (option.is_other && option.option_key === value.value) {
|
|
||||||
// option.value = props.answer[value.value];
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// init();
|
|
||||||
//
|
|
||||||
// // 选项分组
|
|
||||||
// function setOptionGroups() {
|
|
||||||
// optionGroups.value = [];
|
|
||||||
// const copyOptions = JSON.parse(JSON.stringify(options.value));
|
|
||||||
// props.config.option_groups?.option_group.forEach((optionGroup) => {
|
|
||||||
// const group = {
|
|
||||||
// title: optionGroup.title,
|
|
||||||
// options: []
|
|
||||||
// };
|
|
||||||
// optionGroup.groups.forEach((groups) => {
|
|
||||||
// const index = copyOptions.findIndex((option) => option.option_key === groups.option_key);
|
|
||||||
// if (index === -1) return;
|
|
||||||
// group.options.push(copyOptions.splice(index, 1)[0]);
|
|
||||||
// });
|
|
||||||
// group.options = sortOptions(
|
|
||||||
// group.options,
|
|
||||||
// props.question.config.select_random && props.question.config.option_group_random_inside
|
|
||||||
// );
|
|
||||||
// optionGroups.value.push(group);
|
|
||||||
// });
|
|
||||||
// optionGroups.value = sortOptions(
|
|
||||||
// optionGroups.value,
|
|
||||||
// props.question.config.select_random && props.question.config.option_group_random_outside
|
|
||||||
// );
|
|
||||||
// // 若是 group 是undefined ,默认给一个空对象
|
|
||||||
// const group = optionGroups.value.find((group) => !group.title) ?? {};
|
|
||||||
// // console.log(group);
|
|
||||||
// group.options = sortOptions(copyOptions, props.question.config.select_random);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 排序(固定项和其他项不参与随机)
|
|
||||||
// function sortOptions(oldOptions, isRandom) {
|
|
||||||
// const sorts = [];
|
|
||||||
// const fixed = [];
|
|
||||||
// const others = [];
|
|
||||||
// const removeOther = [];
|
|
||||||
// oldOptions.forEach((option) => {
|
|
||||||
// if (option.is_remove_other) {
|
|
||||||
// removeOther.push(option);
|
|
||||||
// } else if (option.is_other) {
|
|
||||||
// others.push(option);
|
|
||||||
// } else if (option.is_fixed) {
|
|
||||||
// fixed.push(option);
|
|
||||||
// } else {
|
|
||||||
// sorts.push(option);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return [...randomOptions(sorts, isRandom), ...fixed, ...others, ...removeOther];
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 选择回调
|
|
||||||
// function changeValue(e) {
|
|
||||||
// // 更新答案
|
|
||||||
// const option = options.value.find((option) => option.option_key === e.target.value);
|
|
||||||
// context.emit('update:answer', {
|
|
||||||
// [e.target.value]: option.value || (option.is_other ? '' : '1')
|
|
||||||
// });
|
|
||||||
// // 清空未选中项输入框值
|
|
||||||
// options.value.forEach((option) => {
|
|
||||||
// if (option.is_other && option.option_key !== e.target.value) {
|
|
||||||
// option.value = '';
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// function onChangeValue(key) {
|
|
||||||
// value.value = key;
|
|
||||||
// changeValue({ target: { value: key } });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 输入回调
|
|
||||||
// function changeInput(e, key) {
|
|
||||||
// const option = options.value.find((option) => option.option_key === key);
|
|
||||||
// option.value = e.target.value;
|
|
||||||
// value.value = key;
|
|
||||||
// // 更新答案
|
|
||||||
// context.emit('update:answer', { [key]: e.target.value });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 监听答案
|
|
||||||
// watch(
|
|
||||||
// () => props.answer,
|
|
||||||
// () => {
|
|
||||||
// context.emit('changeAnswer', {
|
|
||||||
// options: optionGroups.value.flatMap((group) => group.options || []),
|
|
||||||
// value: value.value
|
|
||||||
// });
|
|
||||||
// // 质量控制
|
|
||||||
// const timer = setTimeout(() => {
|
|
||||||
// if (value.value) {
|
|
||||||
// const index = optionGroups.value
|
|
||||||
// .flatMap((group) => group.options.map((option) => option))
|
|
||||||
// .findIndex((option) => option.option_key === value.value);
|
|
||||||
// context.emit('update:answerIndex', `${index}`);
|
|
||||||
// } else if (props.answerIndex) {
|
|
||||||
// context.emit('update:answerIndex', '');
|
|
||||||
// }
|
|
||||||
// clearTimeout(timer);
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// deep: true,
|
|
||||||
// immediate: true
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// // 监听list,更新关联选项
|
|
||||||
// watch(
|
|
||||||
// () => props.list,
|
|
||||||
// () => {
|
|
||||||
// // 更新关联题选项
|
|
||||||
// let newOptions = [];
|
|
||||||
// props.list.forEach((list) => {
|
|
||||||
// newOptions = [...newOptions, ...list.options];
|
|
||||||
// });
|
|
||||||
// // 其他项
|
|
||||||
// newOptions.forEach((option) => {
|
|
||||||
// if (option.is_other && option.option_key === value.value) {
|
|
||||||
// const timer = setTimeout(() => {
|
|
||||||
// option.value = props.answer[value.value];
|
|
||||||
// clearTimeout(timer);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// if (
|
|
||||||
// !compareArrayByField(options.value, newOptions, 'option_key') ||
|
|
||||||
// !compareArrayByField(options.value, newOptions, 'option')
|
|
||||||
// ) {
|
|
||||||
// options.value = newOptions;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 清空值和答案
|
|
||||||
// if (
|
|
||||||
// value.value &&
|
|
||||||
// options.value.findIndex((option) => option.option_key === value.value) === -1
|
|
||||||
// ) {
|
|
||||||
// // 清空值
|
|
||||||
// value.value = '';
|
|
||||||
// // 清空答案
|
|
||||||
// context.emit('update:answer', null);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// deep: true
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// // 监听list,更新关联选项
|
|
||||||
// watch(
|
|
||||||
// () => options.value,
|
|
||||||
// (val, oldVal) => {
|
|
||||||
// if (
|
|
||||||
// compareArrayByField(val, oldVal || [], 'option_key') &&
|
|
||||||
// compareArrayByField(val, oldVal || [], 'option')
|
|
||||||
// ) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// setOptionGroups();
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// deep: true,
|
|
||||||
// immediate: true
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// const onHoldToCart = (target) => {
|
|
||||||
// value.value = target.option_key;
|
|
||||||
//
|
|
||||||
// changeValue({
|
|
||||||
// target: {
|
|
||||||
// value: target.option_key
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const cartWaresLength = computed(() => {
|
|
||||||
// if (!props.answer) return 0;
|
|
||||||
// return Object.keys(props.answer).length;
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// console.log(`car wares length:`, cartWaresLength.value);
|
|
||||||
//
|
|
||||||
// // 显示分组标题
|
|
||||||
// function showGroupTitle(groupOptions) {
|
|
||||||
// const option = groupOptions.find((option) => !props.hideOptions.includes(option.option_key));
|
|
||||||
// return !!option;
|
|
||||||
// }
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.choice-html {
|
.choice-html {
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-field v-model="inputValue" v-focus placeholder="请输入内容"> </van-field>
|
<!-- <van-field v-model="inputValue" v-focus placeholder="请输入内容"> </van-field>-->
|
||||||
|
<!-- <completion />-->
|
||||||
|
<completion
|
||||||
|
v-model:completionValue="completionValue"
|
||||||
|
:index="answerIndex"
|
||||||
|
:element="question"
|
||||||
|
></completion>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineEmits, ref, watch } from 'vue';
|
import { defineEmits, ref, watch } from 'vue';
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import Completion from '@/views/Design/components/Questions/Completion.vue';
|
||||||
// 预览新增 v-model
|
// 预览新增 v-model
|
||||||
// const config = defineModel('config');
|
// const config = defineModel('config');
|
||||||
const answer = defineModel<{ value: string | number }>('answer');
|
const answer = defineModel<{ value: string | number }>('answer', { default: { value: '' } });
|
||||||
// const answerIndex = defineModel('answerIndex');
|
const answerIndex = defineModel<number>('answerIndex');
|
||||||
// const stem = defineModel('stem');
|
// const stem = defineModel('stem');
|
||||||
const question = defineModel<question>('question', {});
|
const question = defineModel<question>('question', {});
|
||||||
// const list = defineModel<questionsList[]>('list');
|
// const list = defineModel<questionsList[]>('list');
|
||||||
@@ -17,82 +23,24 @@ const question = defineModel<question>('question', {});
|
|||||||
|
|
||||||
// // 预览新增 emit ['changeAnswer', 'previous', 'next']
|
// // 预览新增 emit ['changeAnswer', 'previous', 'next']
|
||||||
const emit = defineEmits(['previous', 'next', 'update:modelValue', 'saveOption', 'changeAnswer']);
|
const emit = defineEmits(['previous', 'next', 'update:modelValue', 'saveOption', 'changeAnswer']);
|
||||||
// console.log(answer);
|
|
||||||
const inputValue = ref(answer.value?.value ?? '');
|
console.log(`answer`, answer.value);
|
||||||
|
console.log(question.value);
|
||||||
|
const completionValue = ref(answer.value?.value ?? '');
|
||||||
// console.log(`question:`, question.value);
|
// console.log(`question:`, question.value);
|
||||||
// console.log(`list: `, list.value);
|
// console.log(`list: `, list.value);
|
||||||
|
|
||||||
// console.log(question.value);
|
|
||||||
// 进行提交答案
|
// 进行提交答案
|
||||||
watch(inputValue, () => {
|
watch(
|
||||||
const res = {
|
() => completionValue.value,
|
||||||
value: inputValue.value
|
() => {
|
||||||
};
|
const res = {
|
||||||
|
value: completionValue.value
|
||||||
question.value.answer = res;
|
};
|
||||||
emit('changeAnswer', res);
|
answer.value = res;
|
||||||
});
|
question.value!.answer = res;
|
||||||
|
emit('changeAnswer', res);
|
||||||
// function handleKeyDown() {
|
}
|
||||||
// emit('changeAnswer', {
|
);
|
||||||
// options: list.value,
|
|
||||||
// value: inputValue.value + 1
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const props = defineProps({
|
|
||||||
// modelValue: {
|
|
||||||
// type: Object,
|
|
||||||
// required: false,
|
|
||||||
// default: () => {
|
|
||||||
// return {};
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const selectTextTypeModel = ref(false);
|
|
||||||
// const textTypeList = [
|
|
||||||
// {
|
|
||||||
// text: '不限',
|
|
||||||
// value: 0
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '整数',
|
|
||||||
// value: 1
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '小数',
|
|
||||||
// value: 2
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '字母',
|
|
||||||
// value: 3
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '中文',
|
|
||||||
// value: 4
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: 'email',
|
|
||||||
// value: 5
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '手机号',
|
|
||||||
// value: 6
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// text: '身份证号',
|
|
||||||
// value: 7
|
|
||||||
// }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// const selectText = (textType) => {
|
|
||||||
// return textTypeList.filter((item) => item.value === textType)[0]?.text;
|
|
||||||
// };
|
|
||||||
// const confirm = ({ selectedValues }) => {
|
|
||||||
// actionQuestion.value.config.text_type = Number(selectedValues[0]);
|
|
||||||
// selectTextTypeModel.value = false;
|
|
||||||
// emit('saveOption');
|
|
||||||
// };
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
|
|||||||
@@ -1,82 +1,20 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { showSuccessToast, showFailToast } from 'vant';
|
import FileUpload from '@/views/Design/components/Questions/FileUpload.vue';
|
||||||
|
const questionIndex = defineModel<number>('questionIndex', { default: NaN });
|
||||||
// const { element } = defineProps({
|
const question = defineModel<question>('question', {});
|
||||||
// element: {
|
// 接口还未稳定
|
||||||
// require: false
|
// 需要的数据暂时先放在这里
|
||||||
// }
|
// 格式如下
|
||||||
// });
|
// {
|
||||||
|
// "name": "3-12.png",
|
||||||
// const config = defineModel('question', { required: false });
|
// "size": 238875,
|
||||||
// console.log(config.value);
|
// "type": "image/png",
|
||||||
/**
|
// "url": "https://test-cxp-public-web-1302259445.cos.ap-beijing.myqcloud.com/uat-yls/answer/7JjQp7am/1742022258458_388_3-12.png"
|
||||||
* 文件大小限制
|
// }
|
||||||
* @property {number} max - 最大文件大小
|
|
||||||
* @property {number} min - 最小文件大小
|
|
||||||
*/
|
|
||||||
const fileLimit = {
|
|
||||||
// 默认4MB
|
|
||||||
max: 1024 * 1024 * 40,
|
|
||||||
min: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件
|
|
||||||
* @description 上传文件
|
|
||||||
*/
|
|
||||||
function handleFileUpload() {
|
|
||||||
const fileInput = document.createElement('input');
|
|
||||||
fileInput.type = 'file';
|
|
||||||
// fileInput.accept = '.jpg,.jpeg,.png,.gif';
|
|
||||||
// fileInput.multiple = true;
|
|
||||||
fileInput.click();
|
|
||||||
|
|
||||||
fileInput.addEventListener('change', handleFileChange);
|
|
||||||
|
|
||||||
function handleFileChange(event: Event) {
|
|
||||||
const files = (event.target as HTMLInputElement).files;
|
|
||||||
if (files) {
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
|
||||||
const file = files[i];
|
|
||||||
// console.log(file.size);
|
|
||||||
|
|
||||||
if (file.size > fileLimit.max) {
|
|
||||||
showFailToast(`文件太大,超过${fileLimit.max / 1024 / 1024}MB`);
|
|
||||||
return;
|
|
||||||
} else if (file.size < fileLimit.min) {
|
|
||||||
showFailToast(`文件太小,小于${fileLimit.min / 1024 / 1024}MB`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 这里保留上传的区域
|
|
||||||
|
|
||||||
// 成功
|
|
||||||
showSuccessToast('成功文案');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<van-field>
|
<!-- 文件上传题 -->
|
||||||
<template #input>
|
<file-upload :element="question" :index="questionIndex" :active="false" />
|
||||||
<div>
|
|
||||||
<div class="file-upload-label" @click="handleFileUpload">
|
|
||||||
<van-icon name="photo"></van-icon>
|
|
||||||
<span>上传文件</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style scoped></style>
|
||||||
.file-upload-label {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,132 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<table class="matrix-table">
|
<MatrixCheckbox
|
||||||
<thead>
|
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
|
||||||
<tr>
|
:is-preview="true"
|
||||||
<th></th>
|
/>
|
||||||
<td v-for="col in columns" :key="col.option">
|
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
|
||||||
<input
|
|
||||||
v-if="col.editor"
|
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
|
||||||
/>
|
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
|
||||||
<th v-html="row.option" />
|
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
|
||||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
|
||||||
@change="handleColValueChange(row.option, col.option)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import MatrixCheckbox from '@/views/Design/components/Questions/MatrixCheckbox.vue';
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
const rows = defineModel<OptionType[]>('rows', { required: false, default: [] });
|
|
||||||
const columns = defineModel<OptionType[]>('columns', { required: false, default: [] });
|
|
||||||
// const questionType = defineModel<number>('questionType', { required: false });
|
// const questionType = defineModel<number>('questionType', { required: false });
|
||||||
// const matrixAnswer = defineModel<{ [key: string]: any }>('matrixAnswer', { required: false });
|
|
||||||
const rowRecord = defineModel<number[]>('rowRecord', { required: false });
|
// 矩阵多选的答案类型
|
||||||
|
type answerType = {
|
||||||
|
[key: string]: 1;
|
||||||
|
};
|
||||||
|
|
||||||
// preview props
|
// preview props
|
||||||
// const stem = defineModel('stem');
|
// const stem = defineModel('stem');
|
||||||
const list = defineModel<questionsList[]>('list', { required: false });
|
// const list = defineModel<questionsList[]>('list', { required: false });
|
||||||
// const config = defineModel<OptionConfigType>('config', { required: false });
|
// const config = defineModel<OptionConfigType>('config', { required: false });
|
||||||
// const question = defineModel('question');
|
const question = defineModel<question>('question');
|
||||||
// const answer = defineModel('answer');
|
const emit = defineEmits(['changeAnswer', 'previous', 'next']);
|
||||||
|
// 示例
|
||||||
|
// {
|
||||||
|
// "1_1": 1,
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_1": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
// }
|
||||||
|
const answer = defineModel<answerType>('answer', {
|
||||||
|
// 临时赋值, 用于测试
|
||||||
|
// default: () => ({
|
||||||
|
// "1_1": 1,
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_1": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
// })
|
||||||
|
});
|
||||||
// const answerIndex = defineModel('answerIndex');
|
// const answerIndex = defineModel('answerIndex');
|
||||||
// const answerSn = defineModel('answerSn');
|
// const answerSn = defineModel('answerSn');
|
||||||
// const answerSurveySn = defineModel('answerSurveySn');
|
// const answerSurveySn = defineModel('answerSurveySn');
|
||||||
|
|
||||||
initData();
|
// 记录行和列的索引
|
||||||
|
// 记录的格式如下,
|
||||||
|
// [
|
||||||
|
// [0, 1],
|
||||||
|
// [0, 1]
|
||||||
|
// ]
|
||||||
|
const rowRecord = ref<number[][]>([]);
|
||||||
|
|
||||||
// 数据初始化
|
// 假如 answer 有数值,需要解析 answer ,然后传递 record 给子组件
|
||||||
function initData() {
|
answer.value && parseAnswer(answer.value);
|
||||||
if (!list.value) return;
|
|
||||||
console.log(list.value);
|
|
||||||
if (list.value[0].options.length >= 1) rows.value = list.value[0].options;
|
|
||||||
if (list.value[1].options.length >= 1) columns.value = list.value[1].options;
|
|
||||||
|
|
||||||
// 矩阵多选数组形式 [[1,2],[3]], 长度和 行数有关, 选中的位置跟里面的位置有关
|
console.log(`answer value`, answer.value);
|
||||||
rowRecord.value = new Array(rows.value.length).fill(new Array(columns.value.length).fill(0));
|
/**
|
||||||
|
* 解析 answer
|
||||||
|
*/
|
||||||
|
function parseAnswer(answer: answer) {
|
||||||
|
console.log(`come in parseAnswer`);
|
||||||
|
const rowRecordList: number[][] = [];
|
||||||
|
Object.entries(answer).forEach(([key]) => {
|
||||||
|
const [row, col] = key.split('_').map(Number);
|
||||||
|
if (!rowRecordList[row - 1]) rowRecordList[row - 1] = [];
|
||||||
|
rowRecordList[row - 1].push(col - 1);
|
||||||
|
});
|
||||||
|
rowRecord.value = rowRecordList;
|
||||||
|
|
||||||
|
return rowRecordList;
|
||||||
}
|
}
|
||||||
|
// 查看parseAnswer的返回值
|
||||||
|
// console.log(`parseAnswer value:`, parseAnswer(answer.value!))
|
||||||
|
|
||||||
// console.log(`stem:`, stem.value);
|
/**
|
||||||
// console.log(`list:`, list.value);
|
* 获取行和列的内容
|
||||||
// console.log(`config:`, config.value);
|
* 行的内容在 question.list[0].options
|
||||||
// console.log(`question:`, question.value);
|
* 列的内容在 question.list[1].options
|
||||||
// console.log(`answer:`, answer.value);
|
*/
|
||||||
// console.log(`answerIndex:`, answerIndex.value);
|
const rows = computed(() => question.value?.list[0]?.options ?? []);
|
||||||
// console.log(`answerSn:`, answerSn.value);
|
const cols = computed(() => question.value?.list[1]?.options ?? []);
|
||||||
// console.log(`answerSurveySn:`, answerSurveySn.value);
|
|
||||||
|
|
||||||
// rows.value && console.log(`matrix rows:`, rows.value);
|
watch(rowRecord, () => {
|
||||||
// columns.value && console.log(`matrix columns:`, columns.value);
|
console.log(`record has changed`, rowRecord.value);
|
||||||
// columns.value && console.log(`matrix questionType:`, questionType.value);
|
// 重新生成 answer
|
||||||
// columns.value && console.log(`matrix matrixAnswer:`, matrixAnswer.value);
|
const newAnswer: answer = {};
|
||||||
// columns.value && console.log(`matrix rowRecord:`, rowRecord.value);
|
rowRecord.value.forEach((rowOptions, rowIndex) => {
|
||||||
|
rowOptions.forEach((colIndex) => {
|
||||||
|
newAnswer[`${rowIndex + 1}_${colIndex + 1}`] = 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
answer.value = newAnswer;
|
||||||
|
emit('changeAnswer', newAnswer);
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
/* const emits = */
|
|
||||||
defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
|
||||||
|
|
||||||
const isOptionChecked = (/* rowIndex: number, colIndex: number */): boolean => {
|
|
||||||
// const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
|
||||||
// console.log(key);
|
|
||||||
// return !!matrixAnswer.value[key];
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRowNameChange = (/* value: string */) => {
|
|
||||||
// console.log(`row change: ${value}`);
|
|
||||||
// 你可以在这里添加其他逻辑
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleColValueChange = (rowOption: string, colOption: string) => {
|
|
||||||
// const target = e.target as HTMLInputElement;
|
|
||||||
// 寻找行列的索引
|
|
||||||
const col = columns.value.findIndex((option) => option.option === colOption);
|
|
||||||
const row = rows.value.findIndex((option) => option.option === rowOption);
|
|
||||||
|
|
||||||
// 此处的矩阵是由二维数组组成,两者是通过 索引和 索引对应的数值来表示
|
|
||||||
// rowRecord 是负责记录的数组
|
|
||||||
// 记录之后清空结果对象,遍历数组获取相应的结果内容给 matrixAnswer
|
|
||||||
// rowRecord.value[row] = col;
|
|
||||||
// matrixAnswer.value = {};
|
|
||||||
// rowRecord.value.forEach((row, col) => {
|
|
||||||
// matrixAnswer.value[`${col + 1}_${row + 1}`] = 1;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// 获取row行对应的数组
|
|
||||||
const rowArray = rowRecord.value[row];
|
|
||||||
// console.log(...rowRecord.value);
|
|
||||||
// console.log(`rowArray`, rowArray);
|
|
||||||
// 检查第 col 个元素
|
|
||||||
const value = rowArray[col];
|
|
||||||
if (value) {
|
|
||||||
// 若元素存在,则变动元素数值
|
|
||||||
rowArray[col] = 0;
|
|
||||||
} else {
|
|
||||||
// 不存在记录为1
|
|
||||||
rowArray[col] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(...rowRecord.value);
|
|
||||||
// emits('update:matrixAnswer', matrixAnswer.value);
|
|
||||||
// emits('update:rowRecord', rowRecord.value);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,117 +1,80 @@
|
|||||||
<template>
|
<template>
|
||||||
<table class="matrix-table">
|
<matrix-radio
|
||||||
<thead>
|
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
|
||||||
<tr>
|
:is-preview="true"
|
||||||
<th></th>
|
></matrix-radio>
|
||||||
<!-- 1 是行标签 -->
|
|
||||||
<td v-for="col in columns" :key="col.option">
|
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
|
||||||
<input
|
|
||||||
v-if="col.editor"
|
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
|
||||||
/>
|
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<!-- 0 是列标签 -->
|
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
|
||||||
<th v-html="row.option"></th>
|
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
:name="`R${rowIndex + 1}`"
|
|
||||||
:value="`${rowIndex + 1}_${colIndex + 1}`"
|
|
||||||
:checked="isOptionChecked(rowIndex, colIndex)"
|
|
||||||
@change="handleColValueChange(row.option, col.option, $event)"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import matrixRadio from '@/views/Design/components/Questions/MatrixRadio.vue';
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
const rows = defineModel<OptionType[]>('rows', { required: false, default: [] });
|
|
||||||
const columns = defineModel<OptionType[]>('columns', { required: false, default: [] });
|
|
||||||
// const questionType = defineModel<number>('questionType', { required: false });
|
// const questionType = defineModel<number>('questionType', { required: false });
|
||||||
const matrixAnswer = defineModel<{ [key: string]: any }>('matrixAnswer', { required: false });
|
|
||||||
const rowRecord = defineModel<number[]>('rowRecord', { required: false });
|
// 矩阵单选的答案类型
|
||||||
|
type answerType = {
|
||||||
|
[key: string]: 1;
|
||||||
|
};
|
||||||
|
|
||||||
// preview props
|
// preview props
|
||||||
// const stem = defineModel('stem');
|
// const stem = defineModel('stem');
|
||||||
const list = defineModel<questionsList[]>('list', { required: false });
|
// const list = defineModel<questionsList[]>('list', { required: false });
|
||||||
// const config = defineModel<OptionConfigType>('config', { required: false });
|
// const config = defineModel<OptionConfigType>('config', { required: false });
|
||||||
// const question = defineModel('question');
|
const question = defineModel<question>('question');
|
||||||
// const answer = defineModel('answer');
|
const emit = defineEmits(['changeAnswer', 'previous', 'next']);
|
||||||
|
// 示例
|
||||||
|
// {
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
// }
|
||||||
|
const answer = defineModel<answerType>('answer', {
|
||||||
|
// 临时赋值, 用于测试
|
||||||
|
default: () => ({
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
})
|
||||||
|
});
|
||||||
// const answerIndex = defineModel('answerIndex');
|
// const answerIndex = defineModel('answerIndex');
|
||||||
// const answerSn = defineModel('answerSn');
|
// const answerSn = defineModel('answerSn');
|
||||||
// const answerSurveySn = defineModel('answerSurveySn');
|
// const answerSurveySn = defineModel('answerSurveySn');
|
||||||
|
// 记录行和列的索引
|
||||||
|
const rowRecord = ref<number[]>([]);
|
||||||
|
|
||||||
initData();
|
// 假如 answer 有数值,需要解析 answer ,然后传递 record 给子组件
|
||||||
// 数据初始化
|
answer.value && parseAnswer(answer.value);
|
||||||
function initData() {
|
|
||||||
if (!list.value) return;
|
|
||||||
// console.log(list.value);
|
|
||||||
rows.value = list.value[0].options;
|
|
||||||
columns.value = list.value[1].options;
|
|
||||||
|
|
||||||
rowRecord.value = new Array(rows.value.length);
|
/**
|
||||||
|
* 解析 answer
|
||||||
|
*/
|
||||||
|
function parseAnswer(answer: answerType) {
|
||||||
|
console.log(`come in parseAnswer`);
|
||||||
|
const rowRecordList: number[] = [];
|
||||||
|
Object.entries(answer).forEach(([key]) => {
|
||||||
|
const [row, col] = key.split('_');
|
||||||
|
rowRecordList[Number(row) - 1] = Number(col) - 1;
|
||||||
|
});
|
||||||
|
rowRecord.value = rowRecordList;
|
||||||
|
return rowRecordList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`stem:`, stem.value);
|
/**
|
||||||
// console.log(`list:`, list.value);
|
* 获取行和列的内容
|
||||||
// console.log(`config:`, config.value);
|
* 行的内容在 question.list[0].options
|
||||||
// console.log(`question:`, question.value);
|
* 列的内容在 question.list[1].options
|
||||||
// console.log(`answer:`, answer.value);
|
*/
|
||||||
// console.log(`answerIndex:`, answerIndex.value);
|
const rows = computed(() => question.value?.list[0]?.options ?? []);
|
||||||
// console.log(`answerSn:`, answerSn.value);
|
const cols = computed(() => question.value?.list[1]?.options ?? []);
|
||||||
// console.log(`answerSurveySn:`, answerSurveySn.value);
|
|
||||||
//
|
|
||||||
// rows.value && console.log(`matrix rows:`, rows.value);
|
|
||||||
// columns.value && console.log(`matrix columns:`, columns.value);
|
|
||||||
// columns.value && console.log(`matrix questionType:`, questionType.value);
|
|
||||||
// columns.value && console.log(`matrix matrixAnswer:`, matrixAnswer.value);
|
|
||||||
// columns.value && console.log(`matrix rowRecord:`, rowRecord.value);
|
|
||||||
|
|
||||||
/* const emits = */
|
watch(rowRecord, () => {
|
||||||
defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
console.log(`record has changed`, rowRecord.value);
|
||||||
|
// 生成 answer
|
||||||
const isOptionChecked = (/* rowIndex: number, colIndex: number */): boolean => {
|
const newAnswer: answerType = {};
|
||||||
// const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
|
||||||
// console.log(key);
|
|
||||||
// return !!matrixAnswer.value[key];
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRowNameChange = (/* value: string */) => {
|
|
||||||
// console.log(`row change: ${value}`);
|
|
||||||
// 你可以在这里添加其他逻辑
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleColValueChange = (rowOption: string, colOption: string) => {
|
|
||||||
// const target = e.target as HTMLInputElement;
|
|
||||||
// 寻找行列的索引
|
|
||||||
const col = columns.value.findIndex((option) => option.option === colOption);
|
|
||||||
const row = rows.value.findIndex((option) => option.option === rowOption);
|
|
||||||
|
|
||||||
// 此处的矩阵是由一维数组组成,两者是通过 索引和 索引对应的数值来表示
|
|
||||||
// rowRecord 是负责记录的数组
|
|
||||||
// 记录之后清空结果对象,遍历数组获取相应的结果内容给 matrixAnswer
|
|
||||||
rowRecord.value[row] = col;
|
|
||||||
matrixAnswer.value = {};
|
|
||||||
rowRecord.value.forEach((row, col) => {
|
rowRecord.value.forEach((row, col) => {
|
||||||
matrixAnswer.value[`${col + 1}_${row + 1}`] = 1;
|
newAnswer[`${col + 1}_${row + 1}`] = 1;
|
||||||
});
|
});
|
||||||
// emits('update:matrixAnswer', matrixAnswer.value);
|
answer.value = newAnswer;
|
||||||
// emits('update:rowRecord', rowRecord.value);
|
emit('changeAnswer', newAnswer);
|
||||||
};
|
}, { deep: true });
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,109 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<table class="matrix-table">
|
<MatrixText
|
||||||
<thead>
|
v-model:rowRecord="rowRecord" v-model:matrix-radio-answer="answer!" :rows="rows" :cols="cols"
|
||||||
<tr>
|
:is-preview="true"
|
||||||
<th></th>
|
/>
|
||||||
<td v-for="col in columns" :key="col.option">
|
|
||||||
<!-- 编辑状态,单次点击出输入框,失焦后关闭 -->
|
|
||||||
<input
|
|
||||||
v-if="col.editor"
|
|
||||||
v-model="col.option"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
@focusout="col.editor = false"
|
|
||||||
@click="handleRowNameChange(col.option!)"
|
|
||||||
/>
|
|
||||||
<span v-else @click="handleRowNameChange(col.option!)" v-html="col.option"></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
|
||||||
<th v-html="row.option"></th>
|
|
||||||
<td v-for="(col, colIndex) in columns" :key="colIndex">
|
|
||||||
<input type="text" @change="handleColValueChange(rowIndex, colIndex, $event)" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { vFocus } from '@/utils/directives/useVFocus';
|
import MatrixText from '@/views/Design/components/Questions/MatrixText.vue';
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
const rows = defineModel<OptionType[]>('rows', { required: false, default: [] });
|
|
||||||
const columns = defineModel<OptionType[]>('columns', { required: false, default: [] });
|
|
||||||
// const questionType = defineModel<number>('questionType', { required: false });
|
// const questionType = defineModel<number>('questionType', { required: false });
|
||||||
const matrixAnswer = defineModel<{ [key: string]: any }>('matrixAnswer', { required: false });
|
|
||||||
const rowRecord = defineModel<number[]>('rowRecord', { required: false });
|
// 矩阵多选的答案类型
|
||||||
|
type answerType = {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
|
||||||
// preview props
|
// preview props
|
||||||
// const stem = defineModel('stem');
|
// const stem = defineModel('stem');
|
||||||
const list = defineModel<questionsList[]>('list', { required: false });
|
// const list = defineModel<questionsList[]>('list', { required: false });
|
||||||
// const config = defineModel<OptionConfigType>('config', { required: false });
|
// const config = defineModel<OptionConfigType>('config', { required: false });
|
||||||
// const question = defineModel('question');
|
const question = defineModel<question>('question');
|
||||||
// const answer = defineModel('answer');
|
const emit = defineEmits(['changeAnswer', 'previous', 'next']);
|
||||||
|
// 示例
|
||||||
|
// {
|
||||||
|
// "1_1": 1,
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_1": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
// }
|
||||||
|
const answer = defineModel<answerType>('answer', {
|
||||||
|
// 临时赋值, 用于测试
|
||||||
|
// default: () => ({
|
||||||
|
// "1_1": 1,
|
||||||
|
// "1_2": 1,
|
||||||
|
// "2_1": 1,
|
||||||
|
// "2_2": 1
|
||||||
|
// })
|
||||||
|
});
|
||||||
// const answerIndex = defineModel('answerIndex');
|
// const answerIndex = defineModel('answerIndex');
|
||||||
// const answerSn = defineModel('answerSn');
|
// const answerSn = defineModel('answerSn');
|
||||||
// const answerSurveySn = defineModel('answerSurveySn');
|
// const answerSurveySn = defineModel('answerSurveySn');
|
||||||
|
|
||||||
initData();
|
// 记录行和列的索引
|
||||||
// 数据初始化
|
// 记录的格式如下,
|
||||||
function initData() {
|
// [
|
||||||
if (!list.value) return;
|
// ['', ''],
|
||||||
// console.log(list.value);
|
// ['', '']
|
||||||
rows.value = list.value[0].options;
|
// ]
|
||||||
columns.value = list.value[1].options;
|
const rowRecord = ref<string[][]>([]);
|
||||||
|
|
||||||
rowRecord.value = new Array(rows.value.length);
|
// 假如 answer 有数值,需要解析 answer ,然后传递 record 给子组件
|
||||||
}
|
answer.value && parseAnswer(answer.value);
|
||||||
|
|
||||||
// console.log(`stem:`, stem.value);
|
console.log(`answer value`, answer.value);
|
||||||
// console.log(`list:`, list.value);
|
/**
|
||||||
// console.log(`config:`, config.value);
|
* 解析 answer
|
||||||
// console.log(`question:`, question.value);
|
*/
|
||||||
// console.log(`answer:`, answer.value);
|
function parseAnswer(answer: answerType) {
|
||||||
// console.log(`answerIndex:`, answerIndex.value);
|
const rowRecordList: string[][] = [];
|
||||||
// console.log(`answerSn:`, answerSn.value);
|
Object.entries(answer).forEach(([key, value]) => {
|
||||||
// console.log(`answerSurveySn:`, answerSurveySn.value);
|
const [row, col] = key.split('_');
|
||||||
//
|
// 如果对应位置不存在数组, 重新建立
|
||||||
// rows.value && console.log(`matrix rows:`, rows.value);
|
if (!rowRecordList[Number(row) - 1]) rowRecordList[Number(row) - 1] = [];
|
||||||
// columns.value && console.log(`matrix columns:`, columns.value);
|
console.log(`value ${value}`);
|
||||||
// columns.value && console.log(`matrix questionType:`, questionType.value);
|
rowRecordList[Number(row) - 1][Number(col) - 1] = value;
|
||||||
// columns.value && console.log(`matrix matrixAnswer:`, matrixAnswer.value);
|
|
||||||
// columns.value && console.log(`matrix rowRecord:`, rowRecord.value);
|
|
||||||
|
|
||||||
/* const emits = */
|
|
||||||
defineEmits(['update:matrixAnswer', 'update:rowRecord']);
|
|
||||||
|
|
||||||
// const isOptionChecked = (/*rowIndex: number, colIndex: number*/): boolean => {
|
|
||||||
// const key = `R${rowIndex + 1}_C${colIndex + 1}`;
|
|
||||||
// console.log(key);
|
|
||||||
// return !!matrixAnswer.value[key];
|
|
||||||
// };
|
|
||||||
|
|
||||||
const handleRowNameChange = (/* value: string */) => {
|
|
||||||
// console.log(`row change: ${value}`);
|
|
||||||
// 你可以在这里添加其他逻辑
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleColValueChange = (row: number, col: number) => {
|
|
||||||
// const target = e.target as HTMLInputElement;
|
|
||||||
// 寻找行列的索引
|
|
||||||
// const col = columns.value.findIndex((option) => option.option === colOption);
|
|
||||||
// const row = rows.value.findIndex((option) => option.option === rowOption);
|
|
||||||
// console.log(row, col);
|
|
||||||
// 此处的矩阵是由一维数组组成,两者是通过 索引和 索引对应的数值来表示
|
|
||||||
// rowRecord 是负责记录的数组
|
|
||||||
// 记录之后清空结果对象,遍历数组获取相应的结果内容给 matrixAnswer
|
|
||||||
rowRecord.value[row] = col;
|
|
||||||
matrixAnswer.value = {};
|
|
||||||
rowRecord.value.forEach((row, col) => {
|
|
||||||
matrixAnswer.value[`${col + 1}_${row + 1}`] = 1;
|
|
||||||
});
|
});
|
||||||
// emits('update:matrixAnswer', matrixAnswer.value);
|
rowRecord.value = rowRecordList;
|
||||||
// emits('update:rowRecord', rowRecord.value);
|
|
||||||
};
|
return rowRecordList;
|
||||||
|
}
|
||||||
|
// 查看parseAnswer的返回值
|
||||||
|
// console.log(`parseAnswer value:`, parseAnswer(answer.value!))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取行和列的内容
|
||||||
|
* 行的内容在 question.list[0].options
|
||||||
|
* 列的内容在 question.list[1].options
|
||||||
|
*/
|
||||||
|
const rows = computed(() => question.value?.list[0]?.options ?? []);
|
||||||
|
const cols = computed(() => question.value?.list[1]?.options ?? []);
|
||||||
|
|
||||||
|
watch(rowRecord, () => {
|
||||||
|
// 重新生成 answer
|
||||||
|
const newAnswer: answerType = {};
|
||||||
|
rowRecord.value.forEach((rows, rowIndex) => {
|
||||||
|
rows.forEach((col, colIndex) => {
|
||||||
|
newAnswer[`${rowIndex + 1}_${colIndex + 1}`] = col;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
answer.value = newAnswer;
|
||||||
|
emit('changeAnswer', newAnswer);
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,72 +1,43 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<n-p-s v-model:element="question" v-model:rates="rates" :active="false" :isPreview="true" />
|
||||||
<van-field
|
|
||||||
v-model="stem"
|
|
||||||
:label="stem"
|
|
||||||
:required="question.config.is_required === 1"
|
|
||||||
label-align="top"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
{{ index + 1 }}
|
|
||||||
</template>
|
|
||||||
<template #label>
|
|
||||||
<contenteditable v-model="stem" :active="active" @blur="saveStem"></contenteditable>
|
|
||||||
</template>
|
|
||||||
<template #input>
|
|
||||||
<div v-for="(optionItem, optionItemIndex) in list" :key="optionItemIndex">
|
|
||||||
<div
|
|
||||||
v-for="(item, optionIndex) in optionItem.options"
|
|
||||||
:key="optionIndex"
|
|
||||||
@click="chooseOption(item)"
|
|
||||||
>
|
|
||||||
<RateCharacter v-model="answerValue" :config="config"></RateCharacter>
|
|
||||||
<div class="tips">
|
|
||||||
<p>{{ config.prompt_left }}</p>
|
|
||||||
<p>{{ config.prompt_center }}</p>
|
|
||||||
<p>{{ config.prompt_right }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import NPS from '@/views/Design/components/Questions/NPS.vue';
|
||||||
import RateCharacter from '@/views/Design/components/Questions/RateCharacter.vue';
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
const answerValue = ref(false);
|
const question = defineModel<question>('question', { default: { config: { is_required: false } } });
|
||||||
// const isPreview = defineModel('isPreview', { required: false });
|
const answer = defineModel<{ [key: string]: number }>('answer', { default: undefined });
|
||||||
const stem = defineModel('stem', { required: false });
|
|
||||||
const element = defineModel('element', { required: false });
|
|
||||||
const question = defineModel('question', { required: false });
|
|
||||||
const list = defineModel('list', { required: false });
|
|
||||||
const config = defineModel('config', { required: false });
|
|
||||||
const index = defineModel('index', { required: false });
|
|
||||||
const active = defineModel('active', { required: false });
|
|
||||||
// const sn = defineModel('sn', { required: false });
|
|
||||||
// const questionType = defineModel('questionType', { required: false });
|
|
||||||
|
|
||||||
const chooseId = ref('');
|
// rates 数值取决与 answer , 没有数据重新建立一个对应长度的数组
|
||||||
const emit = defineEmits(['update:element']);
|
const rates = ref(answer.value ? getRates() : new Array(question.value.list[0].options!.length));
|
||||||
const saveStem = () => {
|
// // 预览新增 emit ['changeAnswer', 'previous', 'next']
|
||||||
emit('update:element', element.value);
|
const emit = defineEmits(['changeAnswer', 'previous', 'next', 'update:element']);
|
||||||
};
|
|
||||||
|
|
||||||
const chooseOption = (item) => {
|
// 获取 rates
|
||||||
chooseId.value = item.id;
|
function getRates() {
|
||||||
};
|
const keys = Object.keys(answer.value);
|
||||||
|
return keys.map((item) => {
|
||||||
|
return answer.value[item];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(answer.value && getRates());
|
||||||
|
watch(
|
||||||
|
rates,
|
||||||
|
() => {
|
||||||
|
const res = {};
|
||||||
|
rates.value.map((item, index) => {
|
||||||
|
// index 是 key, item 是 value
|
||||||
|
res[index + 1] = item;
|
||||||
|
});
|
||||||
|
answer.value = res;
|
||||||
|
emit('changeAnswer', res);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped></style>
|
||||||
.content {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tips {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
color: #bfbfbf;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,28 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<van-field
|
<van-field
|
||||||
v-model="element.stem"
|
v-model="element.stem" :label="element.stem" :required="element.config.is_required === 1"
|
||||||
:label="element.stem"
|
|
||||||
:required="element.config.is_required === 1"
|
|
||||||
label-align="top"
|
label-align="top"
|
||||||
>
|
>
|
||||||
<template #left-icon>
|
<template #left-icon>
|
||||||
{{ index + 1 }}
|
{{ index + 1 }}
|
||||||
</template>
|
</template>
|
||||||
<template #label>
|
<template #label>
|
||||||
<contenteditable
|
<contenteditable v-model="element.stem" :active="active" @blur="emitValue"></contenteditable>
|
||||||
v-model="element.stem"
|
|
||||||
:active="active"
|
|
||||||
@blur="emitValue"
|
|
||||||
></contenteditable>
|
|
||||||
</template>
|
</template>
|
||||||
<template #input>
|
<template #input>
|
||||||
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
<div v-for="(optionItem, optionItemIndex) in element.options" :key="optionItemIndex">
|
||||||
<div
|
<div v-for="(item, optionIndex) in optionItem" :key="optionIndex" @click="chooseOption(item)">
|
||||||
v-for="(item, optionIndex) in optionItem"
|
|
||||||
:key="optionIndex"
|
|
||||||
@click="chooseOption(item)"
|
|
||||||
>
|
|
||||||
<contenteditable v-model="item.option" :active="active"></contenteditable>
|
<contenteditable v-model="item.option" :active="active"></contenteditable>
|
||||||
<RateCharacter :config="element.config"></RateCharacter>
|
<RateCharacter :config="element.config"></RateCharacter>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
@@ -39,7 +29,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRefs, watch } from 'vue';
|
import { ref, toRefs, watch } from 'vue';
|
||||||
import RateCharacter from './RateCharacter.vue';
|
// import RateCharacter from './RateCharacter.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
element: {
|
element: {
|
||||||
|
|||||||
@@ -102,37 +102,37 @@ export default defineComponent({
|
|||||||
const isEndUrl = computed(() => {
|
const isEndUrl = computed(() => {
|
||||||
const code = props.action ? props.action.code : props.code;
|
const code = props.action ? props.action.code : props.code;
|
||||||
return (
|
return (
|
||||||
(code === 20004 &&
|
(code === 20004
|
||||||
props.survey.screening_end_url_select &&
|
&& props.survey.screening_end_url_select
|
||||||
props.survey.screening_end_url) ||
|
&& props.survey.screening_end_url)
|
||||||
(code === 20011 && props.survey.success_end_url_select && props.survey.success_end_url) ||
|
|| (code === 20011 && props.survey.success_end_url_select && props.survey.success_end_url)
|
||||||
(code === 20016 && props.survey.quota_end_url_select && props.survey.quota_end_url)
|
|| (code === 20016 && props.survey.quota_end_url_select && props.survey.quota_end_url)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
function toEndUrl() {
|
function toEndUrl() {
|
||||||
switch (props.action.code) {
|
switch (props.action.code) {
|
||||||
case 20004: // 被甄别
|
case 20004: // 被甄别
|
||||||
if (props.survey.screening_end_url_select && props.survey.screening_end_url) {
|
if (props.survey.screening_end_url_select && props.survey.screening_end_url) {
|
||||||
const url = props.survey.screening_end_url;
|
const url = props.survey.screening_end_url;
|
||||||
toUrl(url);
|
toUrl(url);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 20011: // 成功
|
case 20011: // 成功
|
||||||
if (props.survey.success_end_url_select && props.survey.success_end_url) {
|
if (props.survey.success_end_url_select && props.survey.success_end_url) {
|
||||||
const url = props.survey.success_end_url;
|
const url = props.survey.success_end_url;
|
||||||
toUrl(url);
|
toUrl(url);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 20016: // 配额超限
|
case 20016: // 配额超限
|
||||||
if (props.survey.quota_end_url_select && props.survey.quota_end_url) {
|
if (props.survey.quota_end_url_select && props.survey.quota_end_url) {
|
||||||
const url = props.survey.quota_end_url;
|
const url = props.survey.quota_end_url;
|
||||||
toUrl(url);
|
toUrl(url);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -264,16 +264,16 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!compareArrayByField(options.value, newOptions, 'option_key') ||
|
!compareArrayByField(options.value, newOptions, 'option_key')
|
||||||
!compareArrayByField(options.value, newOptions, 'option')
|
|| !compareArrayByField(options.value, newOptions, 'option')
|
||||||
) {
|
) {
|
||||||
options.value = newOptions;
|
options.value = newOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空值和答案
|
// 清空值和答案
|
||||||
if (
|
if (
|
||||||
value.value &&
|
value.value
|
||||||
options.value.findIndex((option) => option.option_key === value.value) === -1
|
&& options.value.findIndex((option) => option.option_key === value.value) === -1
|
||||||
) {
|
) {
|
||||||
// 清空值
|
// 清空值
|
||||||
value.value = '';
|
value.value = '';
|
||||||
@@ -291,8 +291,8 @@ export default defineComponent({
|
|||||||
() => options.value,
|
() => options.value,
|
||||||
(val, oldVal) => {
|
(val, oldVal) => {
|
||||||
if (
|
if (
|
||||||
compareArrayByField(val, oldVal || [], 'option_key') &&
|
compareArrayByField(val, oldVal || [], 'option_key')
|
||||||
compareArrayByField(val, oldVal || [], 'option')
|
&& compareArrayByField(val, oldVal || [], 'option')
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ export default defineComponent({
|
|||||||
const value = matchValue.replace('[%cite(', '').replace(')%]', '');
|
const value = matchValue.replace('[%cite(', '').replace(')%]', '');
|
||||||
let replacement = ''; // 替换文本
|
let replacement = ''; // 替换文本
|
||||||
// 查找引用问题
|
// 查找引用问题
|
||||||
const question =
|
const question
|
||||||
props.questions.find((question) => {
|
= props.questions.find((question) => {
|
||||||
// 矩阵题
|
// 矩阵题
|
||||||
if (question.question_type >= 8 && question.question_type <= 11) {
|
if (question.question_type >= 8 && question.question_type <= 11) {
|
||||||
return question.title === value.split('_R')[0].split('_C')[0];
|
return question.title === value.split('_R')[0].split('_C')[0];
|
||||||
@@ -143,8 +143,8 @@ export default defineComponent({
|
|||||||
return question.title === value.split('_A')[0];
|
return question.title === value.split('_A')[0];
|
||||||
}
|
}
|
||||||
return question.title === value;
|
return question.title === value;
|
||||||
}) ||
|
})
|
||||||
props.questions.find((question) => {
|
|| props.questions.find((question) => {
|
||||||
// 矩阵题
|
// 矩阵题
|
||||||
if (question.question_type >= 8 && question.question_type <= 11) {
|
if (question.question_type >= 8 && question.question_type <= 11) {
|
||||||
return question.title === (value + cycleIndexStr).split('_R')[0].split('_C')[0];
|
return question.title === (value + cycleIndexStr).split('_R')[0].split('_C')[0];
|
||||||
@@ -171,8 +171,8 @@ export default defineComponent({
|
|||||||
replacement = answer[option.option_key];
|
replacement = answer[option.option_key];
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
question.question_type === 2 &&
|
question.question_type === 2
|
||||||
Object.keys(answer).length >= question.config.min_select
|
&& Object.keys(answer).length >= question.config.min_select
|
||||||
) {
|
) {
|
||||||
// 查找引用选项(多选)
|
// 查找引用选项(多选)
|
||||||
options.forEach((option) => {
|
options.forEach((option) => {
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ export const language = {
|
|||||||
zh: '请点击查看图片'
|
zh: '请点击查看图片'
|
||||||
},
|
},
|
||||||
NoteCantViewAfterTimeLimit: {
|
NoteCantViewAfterTimeLimit: {
|
||||||
en: "Note: Can't view after time limit",
|
en: 'Note: Can\'t view after time limit',
|
||||||
zh: '注意:超过显示时间限制后将无法再次查看'
|
zh: '注意:超过显示时间限制后将无法再次查看'
|
||||||
},
|
},
|
||||||
DisplayTimeLimitExceeded: {
|
DisplayTimeLimitExceeded: {
|
||||||
|
|||||||
@@ -250,10 +250,10 @@ function quesHandle(answer, logChild) {
|
|||||||
const matrixRateHandle = () => {
|
const matrixRateHandle = () => {
|
||||||
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
|
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
|
||||||
if (
|
if (
|
||||||
logChild.cell_index === 0 ||
|
logChild.cell_index === 0
|
||||||
logChild.row_index === 0 ||
|
|| logChild.row_index === 0
|
||||||
!logChild.operator ||
|
|| !logChild.operator
|
||||||
!logChild.value
|
|| !logChild.value
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -265,10 +265,10 @@ function quesHandle(answer, logChild) {
|
|||||||
const matrixInputHandle = () => {
|
const matrixInputHandle = () => {
|
||||||
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
|
// 如果配置的逻辑中参数为空,则代表没有配置逻辑匹配值,此时不做校验
|
||||||
if (
|
if (
|
||||||
logChild.cell_index === 0 ||
|
logChild.cell_index === 0
|
||||||
logChild.row_index === 0 ||
|
|| logChild.row_index === 0
|
||||||
!logChild.operator ||
|
|| !logChild.operator
|
||||||
!logChild.value
|
|| !logChild.value
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -428,59 +428,59 @@ function getConditionStatus(logChild) {
|
|||||||
if (answer) {
|
if (answer) {
|
||||||
try {
|
try {
|
||||||
switch (logChild.question_type) {
|
switch (logChild.question_type) {
|
||||||
case 1:
|
case 1:
|
||||||
quesStatus = quesHandles.choiceHandle(config);
|
quesStatus = quesHandles.choiceHandle(config);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
quesStatus = quesHandles.choiceCheckBoxHandle(config);
|
quesStatus = quesHandles.choiceCheckBoxHandle(config);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
quesStatus = quesHandles.cascaderHandle();
|
quesStatus = quesHandles.cascaderHandle();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
quesStatus = quesHandles.inputHandle();
|
quesStatus = quesHandles.inputHandle();
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
quesStatus = quesHandles.rateHandle();
|
quesStatus = quesHandles.rateHandle();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
quesStatus = quesHandles.dateTimeHandle();
|
quesStatus = quesHandles.dateTimeHandle();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
quesStatus = quesHandles.matrixInputHandle();
|
quesStatus = quesHandles.matrixInputHandle();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
quesStatus = quesHandles.matrixRadioHandle(config);
|
quesStatus = quesHandles.matrixRadioHandle(config);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
quesStatus = quesHandles.matrixCheckboxHandle(config);
|
quesStatus = quesHandles.matrixCheckboxHandle(config);
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
quesStatus = quesHandles.matrixRateHandle();
|
quesStatus = quesHandles.matrixRateHandle();
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
quesStatus = quesHandles.imgRadioHandle();
|
quesStatus = quesHandles.imgRadioHandle();
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
quesStatus = quesHandles.imgCheckBoxHandle();
|
quesStatus = quesHandles.imgCheckBoxHandle();
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
quesStatus = quesHandles.classifyHandle();
|
quesStatus = quesHandles.classifyHandle();
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
quesStatus = quesHandles.sortHandle();
|
quesStatus = quesHandles.sortHandle();
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 17:
|
||||||
quesStatus = quesHandles.constantSumHandle();
|
quesStatus = quesHandles.constantSumHandle();
|
||||||
break;
|
break;
|
||||||
case 23:
|
case 23:
|
||||||
quesStatus = quesHandles.agreementHandle();
|
quesStatus = quesHandles.agreementHandle();
|
||||||
break;
|
break;
|
||||||
case 101:
|
case 101:
|
||||||
quesStatus = quesHandles.psmHandle(config);
|
quesStatus = quesHandles.psmHandle(config);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.log(error);
|
// console.log(error);
|
||||||
@@ -519,10 +519,10 @@ function getlogicStatus(questionData) {
|
|||||||
// } else {
|
// } else {
|
||||||
// statusStr = statusStr + conditionStatus;
|
// statusStr = statusStr + conditionStatus;
|
||||||
// }
|
// }
|
||||||
statusStr =
|
statusStr
|
||||||
statusStr +
|
= statusStr
|
||||||
(logChild.logic === 'and' ? '&&' : logChild.logic === 'or' ? '||' : '') +
|
+ (logChild.logic === 'and' ? '&&' : logChild.logic === 'or' ? '||' : '')
|
||||||
conditionStatus;
|
+ conditionStatus;
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line no-eval
|
// eslint-disable-next-line no-eval
|
||||||
logs.logicStatus = eval(statusStr);
|
logs.logicStatus = eval(statusStr);
|
||||||
|
|||||||
@@ -105,8 +105,8 @@ export default function answerMock(questionsData, page) {
|
|||||||
} else if (logic.skip_type === 4) {
|
} else if (logic.skip_type === 4) {
|
||||||
// 只计算跳转后所在页面的隐藏逻辑,否则会出现只返回最后一道隐藏选项题目的情况,导致失效
|
// 只计算跳转后所在页面的隐藏逻辑,否则会出现只返回最后一道隐藏选项题目的情况,导致失效
|
||||||
const toPage = page + 1;
|
const toPage = page + 1;
|
||||||
const hasHiddenLogicQuizPage =
|
const hasHiddenLogicQuizPage
|
||||||
data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
|
= data.pages.findIndex((page) => page.includes(logic.question_index)) + 1;
|
||||||
if (hasHiddenLogicQuizPage === toPage) {
|
if (hasHiddenLogicQuizPage === toPage) {
|
||||||
// 选项隐藏逻辑
|
// 选项隐藏逻辑
|
||||||
updateOptionHidden(data.hide_options, logic);
|
updateOptionHidden(data.hide_options, logic);
|
||||||
|
|||||||
@@ -154,9 +154,9 @@ export default defineComponent({
|
|||||||
question.error = translatedText.value.ThisIsARequiredQuestion;
|
question.error = translatedText.value.ThisIsARequiredQuestion;
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
answer &&
|
answer
|
||||||
questionType === 1 &&
|
&& questionType === 1
|
||||||
Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1
|
||||||
) {
|
) {
|
||||||
// 单选题
|
// 单选题
|
||||||
isError = true;
|
isError = true;
|
||||||
@@ -302,9 +302,9 @@ export default defineComponent({
|
|||||||
} else if (answer && questionType === 12) {
|
} else if (answer && questionType === 12) {
|
||||||
question.error = '';
|
question.error = '';
|
||||||
} else if (
|
} else if (
|
||||||
answer &&
|
answer
|
||||||
questionType === 14 &&
|
&& questionType === 14
|
||||||
Object.keys(answer).length < config.min_select
|
&& Object.keys(answer).length < config.min_select
|
||||||
) {
|
) {
|
||||||
// 图片多选题
|
// 图片多选题
|
||||||
isError = true;
|
isError = true;
|
||||||
@@ -340,46 +340,46 @@ export default defineComponent({
|
|||||||
const { value } = answer;
|
const { value } = answer;
|
||||||
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
const newValue = value.replace(/\n|\r|\r\n/g, '');
|
||||||
switch (config.text_type) {
|
switch (config.text_type) {
|
||||||
case 3: // 字母
|
case 3: // 字母
|
||||||
isError =
|
isError
|
||||||
config.include_mark === 1
|
= config.include_mark === 1
|
||||||
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
? !/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||||
newValue
|
newValue
|
||||||
) || !newValue.length
|
) || !newValue.length
|
||||||
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
|
||||||
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
|
||||||
break;
|
break;
|
||||||
case 4: // 中文
|
case 4: // 中文
|
||||||
isError =
|
isError
|
||||||
config.include_mark === 1
|
= config.include_mark === 1
|
||||||
? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
||||||
newValue
|
newValue
|
||||||
) || !newValue.length
|
) || !newValue.length
|
||||||
: !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/.test(
|
: !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/.test(
|
||||||
newValue
|
newValue
|
||||||
) || !newValue.length;
|
) || !newValue.length;
|
||||||
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
|
||||||
break;
|
break;
|
||||||
case 5: // 邮箱
|
case 5: // 邮箱
|
||||||
isError =
|
isError
|
||||||
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
|
= !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
|
||||||
break;
|
break;
|
||||||
case 6: // 手机号
|
case 6: // 手机号
|
||||||
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
|
||||||
break;
|
break;
|
||||||
case 7: // 身份证号
|
case 7: // 身份证号
|
||||||
isError =
|
isError
|
||||||
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
|
= !/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
|
||||||
isError = true;
|
isError = true;
|
||||||
@@ -391,54 +391,54 @@ export default defineComponent({
|
|||||||
Object.keys(answer).forEach((key) => {
|
Object.keys(answer).forEach((key) => {
|
||||||
const value = answer[key];
|
const value = answer[key];
|
||||||
switch (config.text_type) {
|
switch (config.text_type) {
|
||||||
case 3: // 字母
|
case 3: // 字母
|
||||||
if (
|
if (
|
||||||
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
!/^[a-zA-Z·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterEnglishLetters;
|
question.error = translatedText.value.PleaseEnterEnglishLetters;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // 中文
|
case 4: // 中文
|
||||||
if (
|
if (
|
||||||
!/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
!/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterChineseWords;
|
question.error = translatedText.value.PleaseEnterChineseWords;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // 邮箱
|
case 5: // 邮箱
|
||||||
if (
|
if (
|
||||||
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
|
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
question.error = translatedText.value.PleaseEnterACorrectEmail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6: // 手机号
|
case 6: // 手机号
|
||||||
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
|
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectPhone;
|
question.error = translatedText.value.PleaseEnterACorrectPhone;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // 身份证号
|
case 7: // 身份证号
|
||||||
if (
|
if (
|
||||||
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
|
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterACorrectID;
|
question.error = translatedText.value.PleaseEnterACorrectID;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!question.error &&
|
!question.error
|
||||||
value.length < config.min &&
|
&& value.length < config.min
|
||||||
![1, 2].includes(config.text_type)
|
&& ![1, 2].includes(config.text_type)
|
||||||
) {
|
) {
|
||||||
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
|
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
|
||||||
}
|
}
|
||||||
@@ -814,8 +814,8 @@ export default defineComponent({
|
|||||||
const evt1 = {};
|
const evt1 = {};
|
||||||
|
|
||||||
if ([1].includes(question.question_type)) {
|
if ([1].includes(question.question_type)) {
|
||||||
evt1.value =
|
evt1.value
|
||||||
Object.keys(question.answer)
|
= Object.keys(question.answer)
|
||||||
.map((key) => (question.answer[key] ? key : undefined))
|
.map((key) => (question.answer[key] ? key : undefined))
|
||||||
.filter((i) => !!i)?.[0] || undefined;
|
.filter((i) => !!i)?.[0] || undefined;
|
||||||
evt1.options = question.list.flatMap((i) => i.options);
|
evt1.options = question.list.flatMap((i) => i.options);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const successImg =
|
const successImg
|
||||||
'https://files.axshare.com/gsc/DR6075/c7/5a/53/c75a534148d349f1bb8e185629f784ac/images/%E9%A2%84%E8%A7%88/u123.png?pageId=18fb9d8a-b9b7-465f-9bd7-625b1b78f72e';
|
= 'https://files.axshare.com/gsc/DR6075/c7/5a/53/c75a534148d349f1bb8e185629f784ac/images/%E9%A2%84%E8%A7%88/u123.png?pageId=18fb9d8a-b9b7-465f-9bd7-625b1b78f72e';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user