提交
This commit is contained in:
1 parent
6dc8cfb2c1
commit
d26fb23fcf
181 files changed
+25727
-24557
No files matched your search
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<el-select
|
||||
:model-value="modelValue"
|
||||
:placeholder="placeholder"
|
||||
:clearable="clearable"
|
||||
:filterable="filterable"
|
||||
:allow-create="allowCreate"
|
||||
:default-first-option="allowCreate"
|
||||
:disabled="disabled || loading"
|
||||
:size="size"
|
||||
:style="style"
|
||||
@update:model-value="onSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
>
|
||||
<div class="dict-select-option">
|
||||
<span>{{ opt.label }}</span>
|
||||
<el-button
|
||||
v-if="dictStore.isSessionCreated(dictType, opt.value)"
|
||||
link
|
||||
type="danger"
|
||||
size="small"
|
||||
class="dict-select-option__remove"
|
||||
@click.stop="onRemove(opt.value)"
|
||||
>
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { Delete } from '@element-plus/icons-vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useDictStore } from '@/store/modules/dict'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
dictType: string
|
||||
modelValue?: string | null
|
||||
allowCreate?: boolean
|
||||
clearable?: boolean
|
||||
filterable?: boolean
|
||||
disabled?: boolean
|
||||
placeholder?: string
|
||||
size?: '' | 'default' | 'small' | 'large'
|
||||
style?: string | Record<string, string>
|
||||
}>(),
|
||||
{
|
||||
modelValue: '',
|
||||
allowCreate: true,
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
disabled: false,
|
||||
placeholder: '请选择',
|
||||
size: 'default'
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: string]
|
||||
change: [value: string]
|
||||
}>()
|
||||
|
||||
const dictStore = useDictStore()
|
||||
const loading = ref(false)
|
||||
|
||||
const options = computed(() => dictStore.getOptions(props.dictType))
|
||||
|
||||
function isKnown(value: string) {
|
||||
return options.value.some((o) => o.value === value || o.label === value)
|
||||
}
|
||||
|
||||
async function onSelect(raw: string | null | undefined) {
|
||||
const next = raw == null ? '' : String(raw).trim()
|
||||
if (!next) {
|
||||
emit('update:modelValue', '')
|
||||
emit('change', '')
|
||||
return
|
||||
}
|
||||
if (!props.allowCreate || isKnown(next)) {
|
||||
const known = options.value.find((o) => o.value === next || o.label === next)
|
||||
const value = known?.value ?? next
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(`将「${next}」新增到字典,是否继续?`, '新增字典项', {
|
||||
type: 'warning',
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await dictStore.ensure(props.dictType, next)
|
||||
emit('update:modelValue', data.value)
|
||||
emit('change', data.value)
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.message || '写入字典失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function onRemove(value: string) {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确定从字典中删除「${value}」吗?`, '删除字典项', {
|
||||
type: 'warning',
|
||||
confirmButtonText: '删除',
|
||||
cancelButtonText: '取消'
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
await dictStore.ensureRemove(props.dictType, value)
|
||||
if (props.modelValue === value) {
|
||||
emit('update:modelValue', '')
|
||||
emit('change', '')
|
||||
}
|
||||
ElMessage.success('已删除')
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.message || '删除失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dict-select-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.dict-select-option__remove {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user