mirror of https://github.com/certd/certd
refactor: input render
parent
2f03e18c59
commit
b4ee3d0dfc
|
@ -1,60 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'HelloWorld',
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="less">
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
import { h, resolveComponent } from 'vue'
|
||||||
|
import _ from 'lodash-es'
|
||||||
|
export default {
|
||||||
|
name: 'component-render',
|
||||||
|
props: {
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: 'a-input'
|
||||||
|
},
|
||||||
|
children: {
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup (props, context) {
|
||||||
|
const attrs = {
|
||||||
|
...context.$attrs
|
||||||
|
}
|
||||||
|
_.forEach(props.on, (value, key) => {
|
||||||
|
attrs[key] = value
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
attrs[key] = eval(value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return () => h(resolveComponent(props.name), context.$attrs, props.children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,16 @@
|
||||||
|
import DContainer from './d-container'
|
||||||
|
import ComponentRender from './component-render'
|
||||||
|
import ProviderSelector from './provider-selector/provider-selector'
|
||||||
|
|
||||||
|
const list = [
|
||||||
|
DContainer,
|
||||||
|
ComponentRender,
|
||||||
|
ProviderSelector
|
||||||
|
]
|
||||||
|
export default {
|
||||||
|
install (app) {
|
||||||
|
for (const item of list) {
|
||||||
|
app.component(item.name, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,9 @@
|
||||||
<a-button type="danger" @click="remove(item,index)"><template #icon ><DeleteOutlined /></template></a-button>
|
<a-button type="danger" @click="remove(item,index)"><template #icon ><DeleteOutlined /></template></a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-radio :checked="item.key===selectedKey" @update:checked="selectedKey = item.key">【{{item.key}}】 {{ item.name }}</a-radio>
|
<a-radio :checked="item.key===selectedKey" @update:checked="selectedKey = item.key">
|
||||||
|
{{ item.name }} ({{item.type}})
|
||||||
|
</a-radio>
|
||||||
|
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
</template>
|
</template>
|
||||||
|
@ -38,7 +40,7 @@
|
||||||
<a-modal v-model:visible="editVisible" dialogClass="d-dialog" width="700px" title="编辑授权" @ok="onSubmit">
|
<a-modal v-model:visible="editVisible" dialogClass="d-dialog" width="700px" title="编辑授权" @ok="onSubmit">
|
||||||
|
|
||||||
<a-form ref="formRef" class="domain-form" :model="formData" labelWidth="150px" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="formRef" class="domain-form" :model="formData" labelWidth="150px" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<a-form-item label="类型" :rules="rules.type">
|
<a-form-item label="类型" name="type" :rules="rules.type">
|
||||||
<a-radio-group :disabled="editIndex!=null" v-model:value="formData.type" @change="onTypeChanged" >
|
<a-radio-group :disabled="editIndex!=null" v-model:value="formData.type" @change="onTypeChanged" >
|
||||||
<a-radio-button v-for="(option) of providerDefineList" :key="option.name" :value="option.name">
|
<a-radio-button v-for="(option) of providerDefineList" :key="option.name" :value="option.name">
|
||||||
{{option.label}}
|
{{option.label}}
|
||||||
|
@ -47,19 +49,15 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<template v-if="formData.type && currentProvider">
|
<template v-if="formData.type && currentProvider">
|
||||||
<a-form-item label="key" name="key" :rules="rules.key">
|
|
||||||
<a-input :disabled="editIndex!=null" v-model:value="formData.key"/>
|
|
||||||
<div class="helper">不重复的key</div>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="名称" name="name" :rules="rules.name">
|
<a-form-item label="名称" name="name" :rules="rules.name">
|
||||||
<a-input v-model:value="formData.name"/>
|
<a-input v-model:value="formData.name"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-for="(item,key) in currentProvider.input"
|
<a-form-item v-for="(item,key,index) in currentProvider.input"
|
||||||
:key="key"
|
:key="index"
|
||||||
|
v-bind="item.component||{}"
|
||||||
:label="item.label || key"
|
:label="item.label || key"
|
||||||
:name="key"
|
:name="key">
|
||||||
:rules="[{ required: true, message: '必填项' }]">
|
<component-render v-model:value="formData[key]" v-bind="item.component || {}"></component-render>
|
||||||
<a-input v-model:value="formData[key]" v-bind="item.attrs" ></a-input>
|
|
||||||
<div class="helper">{{item.desc}}</div>
|
<div class="helper">{{item.desc}}</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
@ -75,42 +73,21 @@ import { ref, reactive, nextTick, watch } from 'vue'
|
||||||
import { useForm } from '@ant-design-vue/use'
|
import { useForm } from '@ant-design-vue/use'
|
||||||
import _ from 'lodash-es'
|
import _ from 'lodash-es'
|
||||||
import providerApi from '@/api/api.providers'
|
import providerApi from '@/api/api.providers'
|
||||||
function useEdit (props, context, providerList, onSave) {
|
function useEdit (props, context, providerList, onEditSave) {
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
key: '',
|
key: '',
|
||||||
name: '',
|
name: '',
|
||||||
type: ''
|
type: undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = reactive({
|
const rules = ref({
|
||||||
type: [{
|
type: [{
|
||||||
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
message: '请选择类型'
|
message: '请选择类型'
|
||||||
}],
|
}],
|
||||||
key: [{
|
|
||||||
required: true,
|
|
||||||
message: '请输入key'
|
|
||||||
}, {
|
|
||||||
validator (rule, value) {
|
|
||||||
const providers = providerList.value
|
|
||||||
if (!providers || providers.length === 0) {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
if (editIndex.value != null) {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
const filter = providers.filter(item => item.key === value)
|
|
||||||
console.log('validate', filter)
|
|
||||||
if (filter.length === 0) {
|
|
||||||
return Promise.resolve()
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line prefer-promise-reject-errors
|
|
||||||
return Promise.reject('key不能重复')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
message: 'key不能与其他授权配置重复'
|
|
||||||
}],
|
|
||||||
name: [{
|
name: [{
|
||||||
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入名称'
|
message: '请输入名称'
|
||||||
}]
|
}]
|
||||||
|
@ -121,9 +98,10 @@ function useEdit (props, context, providerList, onSave) {
|
||||||
// const { resetFields, validate, validateInfos } = useForm(formData, rules)
|
// const { resetFields, validate, validateInfos } = useForm(formData, rules)
|
||||||
const onSubmit = async e => {
|
const onSubmit = async e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
await formRef.value.validate()
|
const res = await formRef.value.validate()
|
||||||
|
console.log('validation:', res)
|
||||||
const newProvider = _.cloneDeep(formData)
|
const newProvider = _.cloneDeep(formData)
|
||||||
onSave(newProvider, editIndex.value)
|
onEditSave(newProvider, editIndex.value)
|
||||||
closeEdit()
|
closeEdit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +117,7 @@ function useEdit (props, context, providerList, onSave) {
|
||||||
changeType(item.type)
|
changeType(item.type)
|
||||||
} else {
|
} else {
|
||||||
editIndex.value = null
|
editIndex.value = null
|
||||||
|
formData.type = null
|
||||||
}
|
}
|
||||||
editVisible.value = true
|
editVisible.value = true
|
||||||
}
|
}
|
||||||
|
@ -192,6 +171,23 @@ function useEdit (props, context, providerList, onSave) {
|
||||||
add
|
add
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let index = 0
|
||||||
|
const keyPrefix = 'provider_'
|
||||||
|
function generateNewKey (list) {
|
||||||
|
index++
|
||||||
|
let exists = false
|
||||||
|
for (const item of list) {
|
||||||
|
if (item.key === keyPrefix + index) {
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists) {
|
||||||
|
return generateNewKey(list)
|
||||||
|
}
|
||||||
|
return keyPrefix + index
|
||||||
|
}
|
||||||
export default {
|
export default {
|
||||||
name: 'provider-manager',
|
name: 'provider-manager',
|
||||||
props: {
|
props: {
|
||||||
|
@ -219,11 +215,13 @@ export default {
|
||||||
selectedKey.value = props.value
|
selectedKey.value = props.value
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
const onEditSave = (newProvier, editIndex) => {
|
const onEditSave = (newProvider, editIndex) => {
|
||||||
if (editIndex == null) {
|
if (editIndex == null) {
|
||||||
providerList.value.push(newProvier)
|
// add 生成一个key
|
||||||
|
newProvider.key = generateNewKey(providerList.value)
|
||||||
|
providerList.value.push(newProvider)
|
||||||
} else {
|
} else {
|
||||||
_.merge(providerList.value[editIndex], newProvier)
|
_.merge(providerList.value[editIndex], newProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
:value="value"
|
:value="value"
|
||||||
@update:value="valueUpdate"
|
@update:value="valueUpdate"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="item of providers" :key="item.key" :value="item.key">
|
<a-select-option v-for="item of providers" :key="item.key" :value="item.key" :disabled="isDisabled(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
@ -35,7 +35,8 @@ export default {
|
||||||
},
|
},
|
||||||
providers: {
|
providers: {
|
||||||
type: Object
|
type: Object
|
||||||
}
|
},
|
||||||
|
filter: {}
|
||||||
},
|
},
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const providerManagerRef = ref(null)
|
const providerManagerRef = ref(null)
|
||||||
|
@ -52,11 +53,19 @@ export default {
|
||||||
const valueUpdate = (val) => {
|
const valueUpdate = (val) => {
|
||||||
context.emit('update:value', val)
|
context.emit('update:value', val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDisabled = (item) => {
|
||||||
|
if (!props.filter) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return item.type === props.filter
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
providersUpdate,
|
providersUpdate,
|
||||||
valueUpdate,
|
valueUpdate,
|
||||||
providerManagerOpen,
|
providerManagerOpen,
|
||||||
providerManagerRef
|
providerManagerRef,
|
||||||
|
isDisabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,11 +6,11 @@ import 'ant-design-vue/dist/antd.css'
|
||||||
import '@/style/common.less'
|
import '@/style/common.less'
|
||||||
import { i18n } from '@/i18n'
|
import { i18n } from '@/i18n'
|
||||||
import icons from './icons'
|
import icons from './icons'
|
||||||
import DContainer from '@/components/d-container'
|
import components from './components'
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.config.productionTip = false
|
app.config.productionTip = false
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
app.use(Antd)
|
app.use(Antd)
|
||||||
icons(app)
|
icons(app)
|
||||||
app.component('d-container', DContainer)
|
app.use(components)
|
||||||
app.use(router).mount('#app')
|
app.use(router).mount('#app')
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
import { reactive, toRaw, ref, watch } from 'vue'
|
import { reactive, toRaw, ref, watch } from 'vue'
|
||||||
import { useForm } from '@ant-design-vue/use'
|
import { useForm } from '@ant-design-vue/use'
|
||||||
import _ from 'lodash-es'
|
import _ from 'lodash-es'
|
||||||
import ProviderSelector from '@/views/detail/components/provider-selector'
|
|
||||||
|
|
||||||
function useDrawer () {
|
function useDrawer () {
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
@ -94,7 +93,6 @@ function useDrawer () {
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'cert-form',
|
name: 'cert-form',
|
||||||
components: { ProviderSelector },
|
|
||||||
emits: ['update:accessProviders', 'update:cert'],
|
emits: ['update:accessProviders', 'update:cert'],
|
||||||
// 属性定义
|
// 属性定义
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
></a-input>
|
></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item v-for="(value,key) in currentPlugin.input" :key="key" :label="value.label">
|
<a-form-item v-for="(item,key) in currentPlugin.input" :key="key" :label="item.label">
|
||||||
<a-input v-model:value="currentTask[key]"></a-input>
|
<component-render v-model:value="currentTask[key]" v-bind="item.component || {}"></component-render>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
</a-form>
|
</a-form>
|
||||||
|
@ -57,12 +57,10 @@
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
<provider-manager ref="providerManager"></provider-manager>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import ProviderManager from '@/views/detail/components/provider-manager'
|
|
||||||
import pluginsApi from '@/api/api.plugins'
|
import pluginsApi from '@/api/api.plugins'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
@ -176,7 +174,6 @@ function useProviderManager () {
|
||||||
}
|
}
|
||||||
export default {
|
export default {
|
||||||
name: 'task-form',
|
name: 'task-form',
|
||||||
components: { ProviderManager },
|
|
||||||
emits: ['update'],
|
emits: ['update'],
|
||||||
props: {
|
props: {
|
||||||
options: {}
|
options: {}
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
<PlusCircleOutlined title="添加部署流程" class="add-icon" @click="deployAdd"/>
|
<PlusCircleOutlined title="添加部署流程" class="add-icon" @click="deployAdd"/>
|
||||||
</h3>
|
</h3>
|
||||||
<a-divider></a-divider>
|
<a-divider></a-divider>
|
||||||
|
|
||||||
<div class="deploy-list">
|
<div class="deploy-list">
|
||||||
|
|
||||||
<a-card class="deploy-item" v-for="(deploy,index) of options.deploy" :key="index">
|
<a-card class="deploy-item" v-for="(deploy,index) of options.deploy" :key="index">
|
||||||
|
|
|
@ -8,7 +8,11 @@ const define = {
|
||||||
input: {
|
input: {
|
||||||
domainName: {
|
domainName: {
|
||||||
label: 'cdn加速域名',
|
label: 'cdn加速域名',
|
||||||
required: true
|
required: true,
|
||||||
|
attrs: {
|
||||||
|
placeholder: 'cdn加速域名',
|
||||||
|
rules: [{ required: true, message: '该项必填' }]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
certName: {
|
certName: {
|
||||||
label: '证书名称'
|
label: '证书名称'
|
||||||
|
@ -34,7 +38,10 @@ const define = {
|
||||||
label: 'Access提供者',
|
label: 'Access提供者',
|
||||||
type: [String, Object],
|
type: [String, Object],
|
||||||
desc: 'AccessProviders的key 或 一个包含accessKeyId与accessKeySecret的对象',
|
desc: 'AccessProviders的key 或 一个包含accessKeyId与accessKeySecret的对象',
|
||||||
options: 'accessProviders[type=aliyun]',
|
component: {
|
||||||
|
name: 'provider-selector',
|
||||||
|
filter: 'aliyun'
|
||||||
|
},
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,6 @@ export class AliyunDnsProvider extends AbstractDnsProvider {
|
||||||
input: {
|
input: {
|
||||||
accessKeyId: {
|
accessKeyId: {
|
||||||
type: String,
|
type: String,
|
||||||
desc: 'accessKeyId',
|
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: 'accessKeyId',
|
placeholder: 'accessKeyId',
|
||||||
rules: [{ required: true, message: '必填项' }]
|
rules: [{ required: true, message: '必填项' }]
|
||||||
|
@ -19,7 +18,6 @@ export class AliyunDnsProvider extends AbstractDnsProvider {
|
||||||
},
|
},
|
||||||
accessKeySecret: {
|
accessKeySecret: {
|
||||||
type: String,
|
type: String,
|
||||||
desc: 'accessKeySecret',
|
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: 'accessKeySecret',
|
placeholder: 'accessKeySecret',
|
||||||
rules: [{ required: true, message: '必填项' }]
|
rules: [{ required: true, message: '必填项' }]
|
||||||
|
|
|
@ -10,12 +10,18 @@ export class DnspodDnsProvider extends AbstractDnsProvider {
|
||||||
input: {
|
input: {
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
desc: 'dnspod的账户id'
|
attrs: {
|
||||||
|
placeholder: 'dnspod接口账户id',
|
||||||
|
rules: [{ required: true, message: '该项必填' }]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
token: {
|
token: {
|
||||||
type: String,
|
type: String,
|
||||||
label: 'token',
|
label: 'token',
|
||||||
desc: 'dnspod的开放接口token'
|
attrs: {
|
||||||
|
placeholder: '开放接口token',
|
||||||
|
rules: [{ required: true, message: '该项必填' }]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue