refactor: 重构 materials/setters/widgets 目录下部分组件, 使用 Vue3 组合式 API 写法 (#146)

This commit is contained in:
alwayrun 2024-05-21 19:28:42 +08:00 committed by sudoooooo
parent e9b85f7878
commit 6c9044b457
20 changed files with 798 additions and 941 deletions

View File

@ -1,92 +1,78 @@
<template>
<el-checkbox
v-model="validValue"
@change="changeData"
v-model="modelValue"
@change="handleCheckboxChange"
:disabled="checkBoxDis"
:class="{ inline: !!formConfig?.inline }"
>
</el-checkbox>
</template>
<script>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'CheckBox',
data() {
return {
validValue: this.formConfig.value
interface Props {
formConfig: any
moduleConfig: any
}
},
props: {
formConfig: {
type: Object,
required: true
},
moduleConfig: {
type: Object,
required: true
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: boolean }): void
}
},
computed: {
checkBoxDis() {
return (
this.formConfig.key === 'randomSort' &&
this.moduleConfig?.optionOrigin?.length > 0 &&
this.moduleConfig?.extraOptions &&
this.moduleConfig?.extraOptions.length === 0
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(props.formConfig.value)
const checkBoxDis = computed(
() =>
props.formConfig.key === 'randomSort' &&
props.moduleConfig?.optionOrigin?.length > 0 &&
props.moduleConfig?.extraOptions &&
props.moduleConfig?.extraOptions?.length === 0
)
},
optionOrigin() {
return this.moduleConfig.optionOrigin
},
extraOptionsLength() {
return this.moduleConfig?.extraOptions?.length || []
}
},
watch: {
optionOrigin(newVal) {
if (
this.formConfig.key === 'randomSort' &&
newVal &&
this.moduleConfig?.extraOptions.length === 0
) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: 'randomSort',
value: false
})
this.validValue = false
}
},
extraOptionsLength(newVal) {
if (this.formConfig.key === 'randomSort' && this.moduleConfig?.optionOrigin && newVal === 0) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: 'randomSort',
value: false
})
this.validValue = false
}
},
'formConfig.value': {
immediate: true,
handler(newVal) {
if (newVal === this.validValue) {
return
}
this.validValue = !!newVal
}
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
const handleCheckboxChange = (value: boolean) => {
const key = props.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
const watchOptionOrigin = computed(() => props.moduleConfig.optionOrigin)
const watchExtraOptions = computed(() => props.moduleConfig?.extraOptions?.length || [])
const watchValue = computed(() => props.formConfig.value)
watch(watchOptionOrigin, (newVal) => {
const key = props.formConfig.key
const extraLen = props.moduleConfig?.extraOptions.length
if (key === 'randomSort' && newVal && extraLen === 0) {
emit(FORM_CHANGE_EVENT_KEY, { key: 'randomSort', value: false })
modelValue.value = false
}
})
watch(watchExtraOptions, (newVal) => {
const key = props.formConfig.key
const origin = props.moduleConfig?.optionOrigin
if (key === 'randomSort' && origin && newVal === 0) {
emit(FORM_CHANGE_EVENT_KEY, { key: 'randomSort', value: false })
modelValue.value = false
}
})
watch(
watchValue,
(newVal: boolean) => {
if (newVal !== modelValue.value) {
modelValue.value == !!newVal
}
},
{
immediate: true
}
)
</script>
<style lang="scss" scoped>
.inline {

View File

@ -1,10 +1,10 @@
<template>
<div class="checkbox-group">
<div class="customed-checkbox" v-for="item in this.formConfig.options" :key="item.key">
<div class="customed-checkbox" v-for="item in formConfig.options" :key="item.key">
<el-checkbox
v-model="values[item.key]"
v-model="optionsValue[item.key]"
:label="item.label"
@change="onChange(item.key, $event)"
@change="handleCheckboxChange(item.key, $event)"
>
</el-checkbox>
<el-tooltip v-if="item.tip" class="tooltip" effect="dark" placement="right">
@ -16,44 +16,43 @@
</div>
</div>
</template>
<script>
<script setup lang="ts">
import { watch, reactive } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'CheckboxGroup',
props: {
formConfig: {
type: Object,
default: () => ({})
interface Props {
formConfig: any
}
},
data() {
return {
values: this.formConfig.value
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: boolean }): void
}
},
watch: {
'formConfig.value': {
immediate: true,
deep: true,
handler(newVal) {
const keys = Object.keys(newVal)
for (const key of keys) {
if (newVal[key] !== this.values[key]) {
this.values[key] = newVal[key]
}
}
}
}
},
methods: {
onChange(key, value) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
const props = withDefaults(defineProps<Props>(), {
formConfig: {}
})
const emit = defineEmits<Emit>()
const handleCheckboxChange = (key: string, value: boolean) => {
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
const optionsValue = reactive<any>(props.formConfig?.value)
watch(
props.formConfig.value,
(val) => {
const keys = Object.keys(val)
for (const key of keys) {
if (val[key] !== optionsValue[key]) {
optionsValue[key] = val[key]
}
}
}
},
{ immediate: true, deep: true }
)
</script>
<style lang="scss" scoped>
.customed-checkbox {

View File

@ -1,33 +1,34 @@
<template>
<el-form-item>
<el-input
v-model="modelValue"
:placeholder="formConfig.placeholder"
:value="formConfig.value"
:maxLength="formConfig.maxlength"
@change="changeData"
:maxlength="formConfig.maxlength"
@change="handleInputChange"
>
<template #prepend>#</template>
</el-input>
</el-form-item>
</template>
<script>
<script setup lang="ts">
import { ref } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'ColorInput',
props: {
formConfig: {
type: Object,
required: true
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const modelValue = ref(props.formConfig.value)
const handleInputChange = (value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>

View File

@ -1,27 +1,28 @@
<template>
<el-form-item class="pick-wrap">
<el-color-picker :modelValue="formConfig.value" @change="changeData"></el-color-picker>
<el-color-picker
:modelValue="formConfig.value"
@change="handleColorPickerChange"
></el-color-picker>
</el-form-item>
</template>
<script>
<script setup lang="ts">
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'ColorPicker',
props: {
formConfig: {
type: Object,
required: true
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const handleColorPickerChange = (value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>
<style lang="scss" scoped>

View File

@ -17,20 +17,12 @@
<slot></slot>
</el-form-item>
</template>
<script>
export default {
name: 'FormItem',
components: {},
props: {
formConfig: {
type: Object,
required: true
}
},
data() {
return {}
}
<script setup lang="ts">
interface Props {
formConfig: any
}
defineProps<Props>()
</script>
<style lang="scss" scoped>
.item-label {

View File

@ -1,7 +1,7 @@
<template>
<div>
<el-row class="row">
<el-select :modelValue="backfillSelect" @change="onSelectChange">
<el-select :modelValue="selectModelValue" @change="handleSelectChange">
<el-option
v-for="item in options"
:label="`${item.label}`"
@ -13,83 +13,68 @@
<el-row v-show="showFormdataBackfillHour">
<el-switch
:inactive-text="formConfig.labels['baseConf.formdataBackfillHour']"
:value="hourSwitch"
@change="onSwitchChange"
:value="switchModelValue"
@change="handleSwitchChange"
></el-switch>
</el-row>
</div>
</template>
<script>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { cleanRichText } from '@/common/xss'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
const formdataBackfillKey = 'baseConf.formdataBackfill'
const formdataBackfillHourKey = 'baseConf.formdataBackfillHour'
export default {
name: 'FormDataBackFill',
data() {
return {
backfillSelect: this.formConfig.value[formdataBackfillKey],
hourSwitch: !!this.formConfig.value[formdataBackfillHourKey]
interface Props {
formConfig: any
}
},
props: {
formConfig: {
type: Object,
required: true
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
},
watch: {
'formConfig.value': {
deep: true,
handler(newVal) {
const formdataBackfill = newVal[formdataBackfillKey]
const formdataBackfillHour = !!newVal[formdataBackfillHourKey]
if (formdataBackfill !== this.backfillSelect) {
this.backfillSelect = formdataBackfill
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const selectModelValue = ref(props.formConfig.value[formdataBackfillKey])
const switchModelValue = ref(props.formConfig.value[formdataBackfillHourKey])
const showFormdataBackfillHour = computed(() =>
selectModelValue.value !== 'notallow' ? true : false
)
const options = computed(() => {
if (!Array.isArray(props.formConfig?.options)) {
return []
}
if (formdataBackfillHour !== this.hourSwitch) {
this.hourSwitch = formdataBackfillHour
}
}
}
},
computed: {
showFormdataBackfillHour() {
if (this.backfillSelect === 'notallow') {
return false
}
return true
},
options() {
let options = []
if (Array.isArray(this.formConfig?.options)) {
options = this.formConfig?.options
}
return options.map((item) => {
return props.formConfig?.options.map((item: any) => {
item.label = cleanRichText(item.label)
return item
})
}
},
methods: {
onSelectChange(newVal) {
this.changeData({ key: formdataBackfillKey, value: newVal })
},
onSwitchChange(newVal) {
this.changeData({
key: formdataBackfillHourKey,
value: newVal ? 24 : null
})
},
changeData({ key, value }) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
const handleSelectChange = (value: string) => {
emit(FORM_CHANGE_EVENT_KEY, { key: formdataBackfillKey, value })
}
const handleSwitchChange = (value: string) => {
emit(FORM_CHANGE_EVENT_KEY, { key: formdataBackfillHourKey, value: value ? 24 : null })
}
const watchValue = computed(() => props.formConfig.value)
watch(watchValue, (config) => {
const formdataBackfill = config[formdataBackfillKey]
const formdataBackfillHour = !!config[formdataBackfillHourKey]
if (formdataBackfill !== selectModelValue.value) {
selectModelValue.value = formdataBackfill
}
if (formdataBackfillHour !== switchModelValue.value) {
switchModelValue.value = formdataBackfillHour
}
})
}
}
}
</script>
<style lang="scss" scoped>
.row {

View File

@ -4,7 +4,7 @@
class="option-select"
placeholder="请选择"
:value="formConfig.value[formConfig.selectKey]"
@change="onChange($event, formConfig.selectKey)"
@change="handleInputChange($event, formConfig.selectKey)"
>
<el-option
v-for="item in formConfig.options"
@ -16,42 +16,35 @@
<template v-if="isShowNumberFn">
<span class="option-txt">提交</span>
<el-input-number
v-model="numberValue"
@change="onChange($event, formConfig.numberKey)"
v-model="modelValue"
@change="handleInputChange($event, formConfig.numberKey)"
></el-input-number>
<span class="option-txt"></span>
</template>
</el-form-item>
</template>
<script>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { get as _get } from 'lodash-es'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'FreqAndNumberLimit',
props: {
formConfig: {
type: Object,
required: true
}
},
computed: {
isShowNumberFn() {
return !!this.formConfig.value[this.formConfig.selectKey]
}
},
data() {
return {
numberValue: Number(_get(this.formConfig.value, this.formConfig.numberKey, 0))
}
},
methods: {
onChange(e, key) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value: e
})
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(Number(_get(props.formConfig.value, props.formConfig.numberKey, 0)))
const isShowNumberFn = computed(() => !!props.formConfig.value[props.formConfig.selectKey])
const handleInputChange = (value: string, key: string) => {
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>
<style lang="scss" scoped>

View File

@ -1,100 +1,81 @@
<template>
<el-input-number
:placeholder="formConfig.placeholder"
:modelValue="numberValue"
@change="changeData"
:min="min"
:max="max"
:modelValue="modelValue"
@change="handleInputChange"
:min="minModelValue"
:max="maxModelValue"
/>
</template>
<script>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'InputNumber',
props: {
formConfig: {
type: Object,
required: true
},
moduleConfig: {
type: Object,
required: true
interface Props {
formConfig: any
moduleConfig: any
}
},
data() {
return {
numberValue: 0
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: number }): void
}
},
watch: {
'formConfig.value': {
immediate: true,
handler(newVal) {
const val = parseInt(newVal || '0')
if (val === this.numberValue) {
return
}
this.numberValue = val
}
}
},
computed: {
min() {
const { min } = this.formConfig
const { type } = this.moduleConfig
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const setterTypes = ['checkbox', 'vote']
const modelValue = ref(props.formConfig.value || 0)
const minModelValue = computed(() => {
const { min } = props.formConfig
const { type } = props.moduleConfig
if (min !== undefined) {
if (typeof min === 'string') {
return this.judgeType(type)
? Number(this.moduleConfig[min])
: Number(Number(this.moduleConfig[min]) + 1)
} else if (typeof this.formConfig.min === 'function') {
return min(this.moduleConfig)
return setterTypes.includes(type)
? Number(props.moduleConfig[min])
: Number(Number(props.moduleConfig[min]) + 1)
} else if (typeof props.formConfig.min === 'function') {
return min(props.moduleConfig)
} else {
return Number(min)
}
}
return -Infinity
},
max() {
const { type } = this.moduleConfig
const { max, min } = this.formConfig
})
const maxModelValue = computed(() => {
const { type } = props.moduleConfig
const { max, min } = props.formConfig
if (max) {
if (typeof max === 'string') {
return this.judgeType(type) ? Number(this.moduleConfig[max]) : this.moduleConfig[max] - 1
return setterTypes.includes(type)
? Number(props.moduleConfig[max])
: props.moduleConfig[max] - 1
} else if (typeof max === 'function') {
return max(this.moduleConfig)
return max(props.moduleConfig)
}
return Number(max)
} else if (min !== undefined && Array.isArray(this.moduleConfig?.options)) {
// inputNumber checkbox, vote, matrix-checkbox,
return this.moduleConfig.options.length
} else if (min !== undefined && Array.isArray(props.moduleConfig?.options)) {
return props.moduleConfig.options.length
} else {
return Infinity
}
}
},
methods: {
judgeType(type) {
return ['checkbox', 'vote'].includes(type)
},
changeData(value) {
})
const handleInputChange = (value: number) => {
const key = props.formConfig.key
const reg = /^(-)?[0-9]+$/
if (!reg.test(value)) {
if (!reg.test(String(value))) {
ElMessage.warning('只能输入整数')
}
this.numberValue = value
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
}
}
modelValue.value = value
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>
<style lang="scss" scoped>

View File

@ -2,70 +2,44 @@
<el-input
class="custom-input"
:placeholder="formConfig.placeholder"
v-model="value"
@input="changeData"
:min="min"
:max="max"
v-model="modelValue"
@change="handleInputChange"
:min="minModelValue"
:max="maxModelValue"
type="number"
>
<template #append>%</template>
</el-input>
</template>
<script>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'InputPercent',
props: {
formConfig: {
type: Object,
required: true
interface Props {
formConfig: any
}
},
data() {
return {
value: ''
}
},
watch: {
'formConfig.value': {
immediate: true,
handler(newVal) {
let val = parseFloat(newVal)
if (val === this.value) {
return
}
this.value = val
}
}
},
computed: {
max() {
let max = parseFloat(this.formConfig.max)
if (isNaN(max)) {
max = 100
}
return max
},
min() {
let min = parseFloat(this.formConfig.min)
if (isNaN(min)) {
min = 0
}
return min
}
},
methods: {
changeData() {
const key = this.formConfig.key
let value = parseFloat(this.value)
value = Math.max(value, this.min)
value = Math.min(value, this.max)
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value: `${value}%`
})
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(parseFloat(props.formConfig.value))
const maxModelValue = computed(() => parseFloat(props.formConfig.max) || 100)
const minModelValue = computed(() => parseFloat(props.formConfig.min) || 0)
const handleInputChange = (val: string) => {
const key = props.formConfig.key
const value = Math.min(Math.max(parseFloat(val), minModelValue.value), maxModelValue.value)
let percent = ''
if (Number.isInteger(value)) {
percent = `${value}%`
}
emit(FORM_CHANGE_EVENT_KEY, { key, value: percent })
}
</script>
<style lang="scss" scoped>

View File

@ -1,54 +1,48 @@
<template>
<el-input :placeholder="formConfig.placeholder" v-model="inputData" @blur="changeData"></el-input>
<el-input
:placeholder="formConfig.placeholder"
v-model="modelValue"
@blur="handleInputBlur"
></el-input>
</template>
<script>
<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'InputSetter',
props: {
formConfig: {
type: Object,
required: true
interface Props {
formConfig: any
}
},
data() {
return {
inputData: this.formConfig.value || ''
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
},
watch: {
'formConfig.value': {
handler(newVal) {
if (newVal === this.inputData) {
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(props.formConfig.value || '')
const lazyValue = computed(() => props.formConfig.value)
const handleInputBlur = () => {
const { key, validate, value } = props.formConfig
const preValue = value || ''
if (validate && typeof validate == 'function') {
const validateResult: boolean = validate(modelValue.value)
if (!validateResult) {
return
}
this.inputData = newVal
}
if (preValue !== modelValue.value) {
emit(FORM_CHANGE_EVENT_KEY, { key, value: modelValue.value })
}
}
},
methods: {
saveData(val) {
this.inputData = val
},
changeData: function () {
let key = this.formConfig.key
if (this.formConfig.validate) {
const validateResult = this.formConfig.validate(this.inputData)
if (!validateResult) {
return false
watch(lazyValue, (value) => {
if (value !== modelValue.value) {
modelValue.value = value
}
}
const preValue = this.formConfig.value || ''
if (this.inputData === preValue) {
return false
}
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value: this.inputData
})
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -9,44 +9,31 @@
</label>
<el-input
:value="formConfig.value[item.key]"
@change="(val) => changeData(item.key, val)"
@input="(val) => changeData(item.key, val)"
@onchge="handleInputChange(item.key, $event)"
:placeholder="item.placeholder"
/>
</el-form-item>
</div>
</template>
<script>
<script setup lang="ts">
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'MultiInput',
props: {
formConfig: {
type: Object,
required: true
},
moduleConfig: {
type: Object,
required: true
}
},
methods: {
changeData(key, value) {
if (this.formConfig.key) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: this.formConfig.key + '.' + key,
value
})
} else if (this.formConfig.keys) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
} else {
// todo
}
interface Props {
formConfig: any
moduleConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const handleInputChange = (itemKey: string, value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key: `${key}.${itemKey}`, value })
}
</script>
<style lang="scss" scoped>

View File

@ -1,8 +1,8 @@
<template>
<el-select
:placeholder="formConfig.placeholder || formConfig.label"
:value="formConfig.value"
@input="changeData"
:placeholder="placeholder"
:value="modelValue"
@change="handleSelectChange"
multiple
popper-class="option-list-width"
:disabled="formConfig.disabled"
@ -17,42 +17,39 @@
</el-select>
</template>
<script>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { cleanRichText } from '@/common/xss'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'SelectSetter',
props: {
formConfig: {
type: Object,
required: true
interface Props {
formConfig: any
}
},
data() {
return {}
},
computed: {
options() {
let options = []
if (Array.isArray(this.formConfig?.options)) {
options = this.formConfig?.options
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: Array<string> }): void
}
return options.map((item) => {
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref([])
const placeholder = computed(() => props.formConfig.placeholder || props.formConfig.label)
const options = computed(() => {
if (!Array.isArray(props.formConfig?.options)) {
return []
}
return props.formConfig?.options.map((item: any) => {
item.label = cleanRichText(item.label)
return item
})
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
}
}
const handleSelectChange = (value: Array<string>) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>
<style lang="scss" scoped>

View File

@ -1,79 +1,78 @@
<template>
<div class="custom-time-range">
<el-config-provider :locale="locale">
<el-date-picker
v-model="begTime"
v-model="begModelTime"
type="datetime"
placeholder="开始日期"
format="YYYY-MM-DD HH:mm:ss"
@change="changeData(formConfig.keys[0], $event)"
>
</el-date-picker>
@change="handleDatePickerChange(formConfig.keys[0], $event)"
/>
<span class="seporator"></span>
<el-date-picker
v-model="endTime"
v-model="endModelTime"
type="datetime"
placeholder="结束日期"
format="YYYY-MM-DD HH:mm:ss"
@change="changeData(formConfig.keys[1], $event)"
>
</el-date-picker>
@change="handleDatePickerChange(formConfig.keys[1], $event)"
/>
</el-config-provider>
</div>
</template>
<script>
// elementformatmomentformat
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import moment from 'moment'
//
import 'moment/locale/zh-cn'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
//
moment.locale('zh-cn')
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'QuestionTime',
data() {
moment.locale('zh-cn')
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const format = 'yyyy-MM-DD HH:mm:ss'
const defaultBeginTime = new Date()
const defaultEndTime = moment(defaultBeginTime).add(10, 'year').toDate()
const format = 'yyyy-MM-DD HH:mm:ss'
return {
begTime: defaultBeginTime,
endTime: new Date(defaultEndTime),
format,
zhCn,
begTimeStr: moment(defaultBeginTime).format(format),
endTimeStr: moment(defaultEndTime).format(format)
}
},
props: {
formConfig: {
type: Object,
required: true
}
},
watch: {
'formConfig.value': {
handler([begTime, endTime]) {
if (!!begTime && begTime !== this.begTimeStr) {
this.begTimeStr = begTime
this.begTime = new Date(begTime)
}
if (!!endTime && endTime !== this.endTimeStr) {
this.endTimeStr = endTime
this.endTime = new Date(endTime)
const locale = ref(zhCn)
const begModelTime = ref(defaultBeginTime)
const endModelTime = ref(defaultEndTime)
const begTimeStr = ref(moment(defaultBeginTime).format(format))
const endTimeStr = ref(moment(defaultEndTime).format(format))
const handleDatePickerChange = (key: string, value: string) => {
console.log(key, value)
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
const watchValue = computed(() => props.formConfig.value)
watch(
watchValue,
([begTime, endTime]: any) => {
if (!!begTime && begTime !== begTimeStr.value) {
begTimeStr.value = begTime
begModelTime.value = new Date(begTime)
}
if (!!endTime && endTime !== endTimeStr.value) {
endTimeStr.value = endTime
endModelTime.value = new Date(endTime)
}
},
{
immediate: true,
deep: true
}
},
methods: {
async changeData(key, value) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value: moment(value).format(this.format)
})
}
}
}
)
</script>
<style lang="scss" scoped>
.custom-time-range {

View File

@ -1,74 +1,74 @@
<template>
<div>
<el-config-provider :locale="locale">
<el-time-picker
is-range
v-model="value"
v-model="modelValue"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
format="HH:mm:ss"
@change="onTimeChange"
@change="handleTimePickerChange"
popper-class="timeRange"
>
</el-time-picker>
</el-config-provider>
</div>
</template>
<script>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import moment from 'moment'
//
import 'moment/locale/zh-cn'
//
moment.locale('zh-cn')
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'QuestionTimeHour',
props: {
formConfig: {
type: Object,
required: true
}
},
data() {
return {
value: [],
timeValue: []
}
},
watch: {
'formConfig.value': {
handler([answerBeginTime = '00:00:00', answerEndTime = '23:59:59']) {
if (answerBeginTime !== this.timeValue[0] || answerEndTime !== this.timeValue[1]) {
this.timeValue = [answerBeginTime, answerEndTime]
moment.locale('zh-cn')
const ymd = '2023-01-01'
const time = []
time.push(`${ymd} ${answerBeginTime}`)
time.push(`${ymd} ${answerEndTime}`)
this.value = time
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const locale = ref(zhCn)
const modelValue = ref<any>([])
const timeValue = ref<any>([])
const handleTimePickerChange = (values: Array<string>) => {
if (!values) {
return
}
const keys = props.formConfig.keys
const times = values.map((item) => moment(item).format('HH:mm:ss'))
timeValue.value = times
times.forEach((value, idx) => emit(FORM_CHANGE_EVENT_KEY, { key: keys[idx], value }))
}
const watchValue = computed(() => props.formConfig.value)
watch(
watchValue,
([startTime = '00:00:00', endTime = '23:59:59']: Array<string>) => {
if (startTime !== timeValue.value[0] || endTime !== timeValue.value[1]) {
const times = [startTime, endTime]
const currentDate = moment(Date.now()).format('yyyy-MM-DD')
modelValue.value = times.map((time) => `${currentDate} ${time}`)
timeValue.value = times
}
},
{
immediate: true,
deep: true
}
},
methods: {
onTimeChange(data) {
if (!data) {
return
}
this.timeValue = data.map((item) => moment(item).format('HH:mm:ss'))
this.timeValue.forEach((item, i) => {
this.changeData(this.formConfig.keys[i], item)
})
},
changeData(key, value) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
}
}
}
)
</script>
<style lang="scss" scoped>
.star-question-begAndEndHour {

View File

@ -1,5 +1,9 @@
<template>
<el-radio-group v-model="validValue" @change="changeData" :disabled="formConfig.disabled">
<el-radio-group
v-model="modelValue"
@change="handleRadioGroupChange"
:disabled="formConfig.disabled"
>
<el-radio v-for="item in options" :key="item.value" :value="item.value" class="customed-radio">
<el-tooltip v-if="item.tip" class="item right" effect="dark">
<template #content>
@ -11,60 +15,47 @@
</el-radio>
</el-radio-group>
</template>
<script>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'RadioGroup',
computed: {
options() {
let options = []
if (Array.isArray(this.formConfig?.options)) {
options = this.formConfig?.options
interface Props {
formConfig: any
}
return options.map((item) => {
return item
})
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(props.formConfig.value || props.formConfig.defaultValue)
const options = computed(
() => (Array.isArray(props.formConfig?.options) && props.formConfig?.options) || []
)
const handleRadioGroupChange = (value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
watch(
props.formConfig,
(config) => {
if (config.value == null || config.value == undefined) {
modelValue.value = config.defaultValue
return
}
modelValue.value = config.value
},
data() {
let value
if (this.formConfig.value === undefined || this.formConfig.value === null) {
value = this.formConfig.defaultValue
} else {
value = this.formConfig.value
}
return {
validValue: value,
noMargin: this.formConfig.noMargin,
isActive: {}
}
},
props: {
formConfig: {
type: Object
}
},
watch: {
formConfig: {
handler(val) {
this.validValue =
val.value === undefined || val.value === null ? val.defaultValue : val.value
},
{
immediate: true,
deep: true
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
}
}
}
)
</script>
<style lang="scss" scoped>
.customed-radio {

View File

@ -1,18 +1,13 @@
<template>
<el-radio-group
v-model="validValue"
@change="changeData"
v-model="modelValue"
@change="handleRadioGroupChange"
class="radio-group"
popper-class="option-list-width"
:disabled="formConfig.disabled"
>
<el-radio v-for="item in options" :key="item.value" :value="item.value">
<el-tooltip
v-if="item.tip"
class="item right"
effect="dark"
:placement="setTipPosition(item)"
>
<el-tooltip v-if="item.tip" class="item right" effect="dark" placement="top">
<template #content>
<div v-html="item.tip"></div>
</template>
@ -31,66 +26,47 @@
</el-radio>
</el-radio-group>
</template>
<script>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
const tipPosition = {
前置限制条件: 'top'
interface Props {
formConfig: any
}
export default {
name: 'RadioSetter',
computed: {
options() {
let options = []
if (Array.isArray(this.formConfig?.options)) {
options = this.formConfig?.options
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
return options.map((item) => {
return item
})
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const modelValue = ref(props.formConfig.value || props.formConfig.defaultValue)
const options = computed(
() => (Array.isArray(props.formConfig?.options) && props.formConfig?.options) || []
)
const handleRadioGroupChange = (value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
watch(
props.formConfig,
(config) => {
if (config.value == null || config.value == undefined) {
modelValue.value = config.defaultValue
return
}
modelValue.value = config.value
},
data() {
let value
if (this.formConfig.value === undefined || this.formConfig.value === null) {
value = this.formConfig.defaultValue
} else {
value = this.formConfig.value
}
return {
validValue: value,
noMargin: this.formConfig.noMargin,
isActive: {}
}
},
props: {
formConfig: {
type: Object
}
},
watch: {
formConfig: {
handler(val) {
this.validValue =
val.value === undefined || val.value === null ? val.defaultValue : val.value
},
{
immediate: true,
deep: true
}
},
methods: {
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
},
setTipPosition(item) {
return tipPosition[item.label] || 'right'
}
}
}
)
</script>
<style lang="scss" scoped>
.star-radio-wrapper {

View File

@ -1,74 +1,82 @@
<template>
<div class="range-wrapper">
<el-input-number :modelValue="minValue" @change="changeDataMin" :min="0" />
<el-input-number
:modelValue="minModelValue"
@change="handleRangeChange('min', $event)"
:min="0"
/>
<span class="split-text"></span>
<el-input-number :modelValue="maxValue" @change="changeDataMax" :min="0" />
<el-input-number
:modelValue="maxModelValue"
@change="handleRangeChange('max', $event)"
:min="0"
/>
</div>
</template>
<script>
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'
<script setup lang="ts">
import { computed } from 'vue'
import { ElMessage } from 'element-plus'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'RangeSetter',
props: {
formConfig: {
type: Object,
required: true
import 'element-plus/theme-chalk/src/message.scss'
interface Props {
formConfig: any
}
},
data() {
return {}
},
computed: {
minValue() {
if (this.formConfig.key === 'textRange') {
return parseInt(this.formConfig?.value?.min?.value)
} else {
return this.formConfig?.value?.min?.value || 1
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: number }): void
}
},
maxValue() {
if (this.formConfig.key === 'textRange') {
return parseInt(this.formConfig?.value?.max?.value)
} else {
return this.formConfig?.value?.max?.value || 1
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const minModelValue = computed(() => {
const key = props.formConfig.key
const minValue = props.formConfig?.value?.min?.value
if (key === 'textRange') {
return parseInt(minValue)
}
return minValue || 1
})
const maxModelValue = computed(() => {
const key = props.formConfig.key
const maxValue = props.formConfig?.value?.max?.value
if (key === 'textRange') {
return parseInt(maxValue)
}
},
methods: {
changeDataMin(value) {
const key = this.formConfig.key
if (value > this.formConfig.value.max.value) {
return maxValue || 1
})
const handleRangeChange = (eventType: 'max' | 'min', value: number) => {
const key = props.formConfig.key
const initMinValue = props.formConfig.value.min.value
const initMaxValue = props.formConfig.value.max.value
if (
(eventType === 'max' && value < initMinValue) ||
(eventType === 'min' && value > initMaxValue)
) {
ElMessage({
type: 'info',
message: '最小值大于最大值,请重新输入!'
message:
eventType === 'min' ? '最小值大于最大值,请重新输入!' : '最大值小于最小值,请重新输入!'
})
} else {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: key + '.min.value',
return
}
emit(FORM_CHANGE_EVENT_KEY, {
key: `${key}.${eventType}.value`,
value
})
}
},
changeDataMax(value) {
const key = this.formConfig.key
if (value < this.formConfig.value.min.value) {
ElMessage({
type: 'info',
message: '最大值小于最小值,请重新输入!'
})
} else {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: key + '.max.value',
value
})
}
}
}
}
</script>
<style lang="scss" scoped>
.range-wrapper {

View File

@ -1,44 +1,33 @@
<template>
<RichEditor
:modelValue="formConfig.value"
@change="onChange"
@change="handleEditorValueChange('change', $event)"
:staticToolBar="true"
@input="onInput"
@input="handleEditorValueChange('input', $event)"
/>
</template>
<script>
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
<script setup lang="ts">
import RichEditor from '@/common/Editor/RichEditor.vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'RichText',
components: {
RichEditor
},
props: {
formConfig: {
type: Object,
default: () => ({})
interface Props {
formConfig: any
}
}, // value v-model
methods: {
onChange(newHtml) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: this.formConfig.key,
value: newHtml
})
this.$emit('change', newHtml)
},
onInput(newHtml) {
this.$emit(FORM_CHANGE_EVENT_KEY, {
key: this.formConfig.key,
value: newHtml
})
this.$emit('input', newHtml)
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
(ev: 'change' | 'input', value: string): void
}
const emit = defineEmits<Emit>()
const props = withDefaults(defineProps<Props>(), { formConfig: {} })
const handleEditorValueChange = (eventType: 'change' | 'input', value: string) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
emit(eventType, value)
}
</script>
<style lang="scss" scoped>

View File

@ -1,11 +1,9 @@
<template>
<el-select
:placeholder="
['matrixOptionsRely', 'optionOrigin'].includes(formConfig.key) ? '请选择' : formConfig.label
"
v-model="validValue"
:placeholder="placeholder"
v-model="modelValue"
:empty-values="[null, undefined]"
@change="changeData"
@change="handleSelectChange"
popper-class="option-list-width"
:disabled="formConfig.disabled"
:class="formConfig.contentClass"
@ -19,64 +17,74 @@
/>
</el-select>
</template>
<script>
<script setup lang="ts">
import { computed, watch, ref } from 'vue'
import { cleanRichText } from '@/common/xss'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'SelectSetter',
data() {
return {
validValue: !this.formConfig.value && this.formConfig.value != 0 ? '' : this.formConfig.value
interface Props {
formConfig: any
moduleConfig: any
}
},
props: {
formConfig: {
type: Object,
required: true
},
moduleConfig: {
type: Object,
required: true
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
}
},
watch: {
formConfig: {
handler(v) {
this.validValue = v.value
},
deep: true
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const placeholder = computed(() => {
const defaultValue = '请选择'
if (!['matrixOptionsRely', 'optionOrigin'].includes(props.formConfig.key)) {
return props.formConfig.label
}
},
computed: {
options() {
let options = []
if (Array.isArray(this.formConfig?.options)) {
options = this.formConfig?.options
return defaultValue
})
const options = computed(() => {
if (!Array.isArray(props.formConfig?.options)) {
return []
}
return options.map((item) => {
return props.formConfig?.options.map((item: any) => {
item.label = cleanRichText(item.label)
return item
})
}
},
methods: {
changeData(value) {
const { key, valueSetter } = this.formConfig
})
const modelValue = ref(
!props.formConfig.value && props.formConfig.value != 0 ? '' : props.formConfig.value
)
const handleSelectChange = (value: string) => {
const { key, valueSetter } = props.formConfig
if (valueSetter && typeof valueSetter == 'function') {
let status = valueSetter(value, this.moduleConfig)
if (status) {
this.validValue = this.moduleConfig[key]
let verification: boolean = valueSetter(value, props.moduleConfig)
if (!verification) {
return
}
modelValue.value = props.moduleConfig[key]
}
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
}
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
watch(
props.formConfig,
(newValue) => {
if (modelValue.value != newValue.value) {
modelValue.value = newValue.value
}
},
{ deep: true }
)
</script>
<style lang="scss" scoped>
.option-list-width {

View File

@ -2,40 +2,36 @@
<el-form-item class="slider-wrap">
<el-slider
:modelValue="formConfig.value"
@input="changeData"
@input="handleSliderChange"
:format-tooltip="formatTooltip"
></el-slider>
<!-- <span>{{ formConfig.value + '%' }}</span> -->
</el-form-item>
</template>
<script>
<script setup lang="ts">
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
export default {
name: 'SliderSetter',
props: {
formConfig: {
type: Object,
required: true
}
},
methods: {
formatTooltip(val) {
return val + '%'
},
changeData(value) {
const key = this.formConfig.key
this.$emit(FORM_CHANGE_EVENT_KEY, {
key,
value
})
interface Props {
formConfig: any
}
interface Emit {
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: number }): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emit>()
const formatTooltip = (val: string) => val + '%'
const handleSliderChange = (value: number) => {
const key = props.formConfig.key
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}
</script>
<style>
.slider-wrap {
flex: 1;
/* display: flex; */
padding: 0 20px;
}
</style>