|
@@ -1,5 +1,5 @@
|
|
<template>
|
|
<template>
|
|
- <div class="flex scoring-panel" :class="getClass('', 'sticky')">
|
|
|
|
|
|
+ <div class="flex scoring-panel" :class="getClass('modal-panel', 'sticky')">
|
|
<toggle-dialog-render>
|
|
<toggle-dialog-render>
|
|
<svg-icon name="question"></svg-icon>
|
|
<svg-icon name="question"></svg-icon>
|
|
<span class="m-l-mini">{{ question.mainNumber }} - {{ question.subNumber }}{{ question.mainTitle }}</span>
|
|
<span class="m-l-mini">{{ question.mainNumber }} - {{ question.subNumber }}{{ question.mainTitle }}</span>
|
|
@@ -23,7 +23,7 @@
|
|
{{ scoreItem }}
|
|
{{ scoreItem }}
|
|
</div>
|
|
</div>
|
|
<toggle-dialog-render>
|
|
<toggle-dialog-render>
|
|
- <div class="flex items-center score-result">
|
|
|
|
|
|
+ <div class="flex items-center score-result" :class="{ 'score-valid-fail': scoreValidFail }">
|
|
<div class="flex-1 text-center">给分</div>
|
|
<div class="flex-1 text-center">给分</div>
|
|
<input
|
|
<input
|
|
ref="refInput1"
|
|
ref="refInput1"
|
|
@@ -38,15 +38,17 @@
|
|
</toggle-dialog-render>
|
|
</toggle-dialog-render>
|
|
</div>
|
|
</div>
|
|
<toggle-dialog-render dialog>
|
|
<toggle-dialog-render dialog>
|
|
- <input
|
|
|
|
- ref="refInput2"
|
|
|
|
- class="grid radius-base score-input dialog-score"
|
|
|
|
- :value="currentScore"
|
|
|
|
- @focus="onInputFocus"
|
|
|
|
- @blur="onBlur"
|
|
|
|
- @keydown="onValidScore"
|
|
|
|
- @input="scoreChange"
|
|
|
|
- />
|
|
|
|
|
|
+ <div class="grid radius-base dialog-score" :class="{ 'score-valid-fail': scoreValidFail }">
|
|
|
|
+ <input
|
|
|
|
+ ref="refInput2"
|
|
|
|
+ class="score-input"
|
|
|
|
+ :value="currentScore"
|
|
|
|
+ @focus="onInputFocus"
|
|
|
|
+ @blur="onBlur"
|
|
|
|
+ @keydown="onValidScore"
|
|
|
|
+ @input="scoreChange"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
</toggle-dialog-render>
|
|
</toggle-dialog-render>
|
|
<toggle-dialog-render>
|
|
<toggle-dialog-render>
|
|
<svg-icon
|
|
<svg-icon
|
|
@@ -63,7 +65,7 @@
|
|
import { watch, computed, ref, nextTick, withDefaults, defineComponent, useSlots } from 'vue'
|
|
import { watch, computed, ref, nextTick, withDefaults, defineComponent, useSlots } from 'vue'
|
|
import SvgIcon from '@/components/common/SvgIcon.vue'
|
|
import SvgIcon from '@/components/common/SvgIcon.vue'
|
|
import useVModel from '@/hooks/useVModel'
|
|
import useVModel from '@/hooks/useVModel'
|
|
-import { getNumbers } from '@/utils/common'
|
|
|
|
|
|
+import { getNumbers, isDefine } from '@/utils/common'
|
|
|
|
|
|
interface QuestionInfo {
|
|
interface QuestionInfo {
|
|
mainNumber: number
|
|
mainNumber: number
|
|
@@ -83,9 +85,10 @@ const props = withDefaults(
|
|
score?: number | string | undefined
|
|
score?: number | string | undefined
|
|
/** active 当前正在评分 */
|
|
/** active 当前正在评分 */
|
|
active: boolean
|
|
active: boolean
|
|
|
|
+ scoreValidFail: boolean | undefined
|
|
question: QuestionInfo
|
|
question: QuestionInfo
|
|
}>(),
|
|
}>(),
|
|
- { modal: false, toggleModal: true, score: void 0 }
|
|
|
|
|
|
+ { modal: false, toggleModal: true, score: void 0, scoreValidFail: false }
|
|
)
|
|
)
|
|
|
|
|
|
const emits = defineEmits(['focused', 'toggle-click', 'enter', 'update:score'])
|
|
const emits = defineEmits(['focused', 'toggle-click', 'enter', 'update:score'])
|
|
@@ -94,6 +97,8 @@ const dialogMode = ref<boolean>(props.modal)
|
|
|
|
|
|
const currentScore = useVModel(props, 'score')
|
|
const currentScore = useVModel(props, 'score')
|
|
|
|
|
|
|
|
+const scoreValidFail = useVModel(props, 'scoreValidFail')
|
|
|
|
+
|
|
const ToggleDialogRender = defineComponent({
|
|
const ToggleDialogRender = defineComponent({
|
|
name: 'DialogHideNode',
|
|
name: 'DialogHideNode',
|
|
inheritAttrs: false,
|
|
inheritAttrs: false,
|
|
@@ -111,10 +116,6 @@ const ToggleDialogRender = defineComponent({
|
|
},
|
|
},
|
|
})
|
|
})
|
|
|
|
|
|
-const getClass = (val: string, callback?: string) => {
|
|
|
|
- return dialogMode.value ? val : callback || ''
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
const question = computed(() => {
|
|
const question = computed(() => {
|
|
return props.question || ({} as QuestionInfo)
|
|
return props.question || ({} as QuestionInfo)
|
|
})
|
|
})
|
|
@@ -143,6 +144,10 @@ watch(
|
|
{ immediate: true, deep: true }
|
|
{ immediate: true, deep: true }
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+const getClass = (val: string, callback?: string) => {
|
|
|
|
+ return dialogMode.value ? val : callback || ''
|
|
|
|
+}
|
|
|
|
+
|
|
const onSetScore = (v: number | string) => {
|
|
const onSetScore = (v: number | string) => {
|
|
onInputFocus()
|
|
onInputFocus()
|
|
currentScore.value = v
|
|
currentScore.value = v
|
|
@@ -153,8 +158,10 @@ const onInputFocus = () => {
|
|
emits('focused')
|
|
emits('focused')
|
|
}
|
|
}
|
|
|
|
|
|
-const onBlur = () => {
|
|
|
|
|
|
+const onBlur = (e: Event) => {
|
|
focused.value = false
|
|
focused.value = false
|
|
|
|
+ const target = e.target as HTMLInputElement
|
|
|
|
+ target.value && scoreStrictValidFail(target.value)
|
|
}
|
|
}
|
|
|
|
|
|
const inputFocus = () => {
|
|
const inputFocus = () => {
|
|
@@ -183,6 +190,11 @@ const validScore = (score: number | string) => {
|
|
return scoreList.value.some((s) => `${s}`.startsWith(`${score}`))
|
|
return scoreList.value.some((s) => `${s}`.startsWith(`${score}`))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const scoreStrictValidFail = (score: number | string) => {
|
|
|
|
+ scoreValidFail.value = !scoreList.value.some((s) => `${s}` === `${score}`)
|
|
|
|
+ return scoreValidFail.value
|
|
|
|
+}
|
|
|
|
+
|
|
const deleteStringChart = (str: string, index: number) => {
|
|
const deleteStringChart = (str: string, index: number) => {
|
|
return str.substring(0, index) + str.substring(index + 1)
|
|
return str.substring(0, index) + str.substring(index + 1)
|
|
}
|
|
}
|
|
@@ -206,8 +218,10 @@ const onValidScore = (e: KeyboardEvent) => {
|
|
}
|
|
}
|
|
|
|
|
|
if ('Enter' === e.key) {
|
|
if ('Enter' === e.key) {
|
|
- if (oldScore) {
|
|
|
|
- emits('enter')
|
|
|
|
|
|
+ if (oldScore && !scoreStrictValidFail(oldScore)) {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ emits('enter')
|
|
|
|
+ })
|
|
}
|
|
}
|
|
e.preventDefault()
|
|
e.preventDefault()
|
|
return
|
|
return
|
|
@@ -250,10 +264,13 @@ const onToggleClick = () => {
|
|
background-color: $MainLayoutHeaderBg;
|
|
background-color: $MainLayoutHeaderBg;
|
|
font-size: $MediumFont;
|
|
font-size: $MediumFont;
|
|
margin-bottom: 6px;
|
|
margin-bottom: 6px;
|
|
|
|
+
|
|
|
|
+ &.modal-panel {
|
|
|
|
+ padding: 10px 0;
|
|
|
|
+ }
|
|
&.sticky {
|
|
&.sticky {
|
|
- // height: $MainLayoutHeaderHeight;
|
|
|
|
align-items: center;
|
|
align-items: center;
|
|
- padding: 10px 20px;
|
|
|
|
|
|
+ padding: 12px 20px;
|
|
}
|
|
}
|
|
|
|
|
|
.dialog-name {
|
|
.dialog-name {
|
|
@@ -294,7 +311,6 @@ const onToggleClick = () => {
|
|
height: 32px;
|
|
height: 32px;
|
|
line-height: 32px;
|
|
line-height: 32px;
|
|
min-width: 84px;
|
|
min-width: 84px;
|
|
- overflow: hidden;
|
|
|
|
margin-bottom: 8px;
|
|
margin-bottom: 8px;
|
|
|
|
|
|
.score-num {
|
|
.score-num {
|
|
@@ -312,17 +328,43 @@ const onToggleClick = () => {
|
|
.dialog-score {
|
|
.dialog-score {
|
|
width: 80px;
|
|
width: 80px;
|
|
place-items: center;
|
|
place-items: center;
|
|
- text-align: center;
|
|
|
|
background: $color--primary;
|
|
background: $color--primary;
|
|
color: $color--white;
|
|
color: $color--white;
|
|
font-size: 32px;
|
|
font-size: 32px;
|
|
outline: none;
|
|
outline: none;
|
|
|
|
+ .score-input {
|
|
|
|
+ background: inherit;
|
|
|
|
+ color: inherit;
|
|
|
|
+ font-size: inherit;
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
.score-input {
|
|
.score-input {
|
|
border: none;
|
|
border: none;
|
|
outline: none;
|
|
outline: none;
|
|
font-weight: bold;
|
|
font-weight: bold;
|
|
|
|
+ text-align: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .score-valid-fail {
|
|
|
|
+ position: relative;
|
|
|
|
+ // background-color: $DangerColor !important;
|
|
|
|
+ border: 1px solid $DangerColor;
|
|
|
|
+ box-shadow: 0 0 4px $DangerColor;
|
|
|
|
+ &:before {
|
|
|
|
+ content: '无效分值';
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 1em;
|
|
|
|
+ line-height: 1;
|
|
|
|
+ text-align: center;
|
|
|
|
+ top: -1.2em;
|
|
|
|
+ left: 50%;
|
|
|
|
+ transform: translateX(-50%);
|
|
|
|
+ font-size: 10px;
|
|
|
|
+ color: $DangerColor;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
.toggle-icon {
|
|
.toggle-icon {
|