You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
8.6 KiB
317 lines
8.6 KiB
<template>
|
|
<div class="app-container">
|
|
<el-form
|
|
ref="frmFeature"
|
|
:model="features"
|
|
label-width="100px"
|
|
>
|
|
<el-tabs v-model="selectTab">
|
|
<el-tab-pane
|
|
v-for="(feature, fi) in features.features"
|
|
:key="feature.name"
|
|
:label="feature.displayName"
|
|
:name="feature.name"
|
|
>
|
|
<el-form-item
|
|
v-for="(featureChildren, fci) in feature.children"
|
|
:key="featureChildren.name"
|
|
:label="featureChildren.displayName"
|
|
:prop="'features.' + fi + '.children.' + fci + '.value'"
|
|
:rules="featureChildren.valueType.validator | inputRuleFilter(localizer)"
|
|
>
|
|
<div
|
|
v-if="featureChildren.valueType.name === 'ToggleStringValueType'"
|
|
>
|
|
<el-switch
|
|
v-if="featureChildren.valueType.validator.name === 'BOOLEAN'"
|
|
v-model="featureChildren.value"
|
|
/>
|
|
<el-input
|
|
v-else-if="featureChildren.valueType.validator.name === 'NUMERIC'"
|
|
v-model.number="featureChildren.value"
|
|
type="number"
|
|
/>
|
|
<el-input
|
|
v-else-if="featureChildren.valueType.validator.name === 'STRING'"
|
|
v-model="featureChildren.value"
|
|
type="text"
|
|
/>
|
|
</div>
|
|
<div
|
|
v-else-if="featureChildren.valueType.name === 'SELECTION'"
|
|
>
|
|
<el-select
|
|
v-model="featureChildren.value"
|
|
>
|
|
<el-option
|
|
v-for="valueItem in featureChildren.valueType.itemSource.items"
|
|
:key="valueItem.value"
|
|
:label="valueItem.displayText"
|
|
:value="valueItem.value"
|
|
/>
|
|
</el-select>
|
|
</div>
|
|
</el-form-item>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
<el-button
|
|
type="primary"
|
|
class="confirm"
|
|
@click="onSave"
|
|
>
|
|
{{ $t('AbpFeatureManagement.Submit') }}
|
|
</el-button>
|
|
<el-button
|
|
class="cancel"
|
|
@click="onClosed"
|
|
>
|
|
{{ $t('AbpFeatureManagement.Cancel') }}
|
|
</el-button>
|
|
</el-form>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
|
|
import FeatureManagementService, { ValueType, Feature, Features } from '@/api/feature-management'
|
|
|
|
/**
|
|
* 适用于动态表单的功能节点列表
|
|
*/
|
|
class FeatureItems {
|
|
features = new Array<FeatureItem>()
|
|
}
|
|
|
|
/**
|
|
* 适用于动态表单的功能节点
|
|
*/
|
|
class FeatureItem {
|
|
/** 功能名称 */
|
|
name!: string
|
|
/** 显示名称 */
|
|
displayName?: string
|
|
/** 当前值 */
|
|
value!: any
|
|
/** 说明 */
|
|
description?: string
|
|
/** 值类型 */
|
|
valueType?: ValueType
|
|
/** 深度 */
|
|
depth?: number
|
|
/** 子节点 */
|
|
children!: FeatureItem[]
|
|
|
|
/** 构造器 */
|
|
constructor(
|
|
name: string,
|
|
value: any,
|
|
displayName?: string,
|
|
description?: string,
|
|
valueType?: ValueType,
|
|
depth?: number
|
|
) {
|
|
this.name = name
|
|
this.depth = depth
|
|
this.valueType = valueType
|
|
this.displayName = displayName
|
|
this.description = description
|
|
this.children = new Array<FeatureItem>()
|
|
if (value !== null) {
|
|
this.value = value.toLowerCase() === 'true' ? true // boolean类型
|
|
: !isNaN(Number(value)) ? Number(value) // number类型
|
|
: value
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 创建子节点
|
|
* @feature 子节点
|
|
*/
|
|
public appendChildren(feature: FeatureItem) {
|
|
this.children.push(feature)
|
|
}
|
|
|
|
/**
|
|
* 获取子节点
|
|
* @name 节点名称
|
|
*/
|
|
public getChildren(name: string) {
|
|
const childrenIndex = this.children.findIndex(feature => feature.name === name)
|
|
if (childrenIndex >= 0) {
|
|
return this.children[childrenIndex]
|
|
}
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
@Component({
|
|
name: 'FeatureManagement',
|
|
filters: {
|
|
/**
|
|
* 动态处理功能表单验证
|
|
* @validator 后端传递的验证规则
|
|
* @localizer 本地化method
|
|
*/
|
|
inputRuleFilter(validator: any, localizer: any) {
|
|
const featureRules: {[key: string]: any}[] = new Array<{[key: string]: any}>()
|
|
if (validator.name === 'NUMERIC') {
|
|
const ruleRang: {[key: string]: any} = {}
|
|
ruleRang.pattern = RegExp('^(' + validator.minValue + '|[1-9]d?|' + validator.maxValue + ')$')
|
|
// ruleRang.pattern = /^(1|[1-9]\d?|10)$/
|
|
// ruleRang.min = validator.minValue
|
|
// ruleRang.max = validator.maxValue
|
|
ruleRang.trigger = 'blur'
|
|
ruleRang.message = localizer('AbpFeatureManagement.ThisFieldMustBeBetween{0}And{1}', { 0: validator.minValue, 1: validator.maxValue })
|
|
featureRules.push(ruleRang)
|
|
} else if (validator.name === 'STRING') {
|
|
if (validator.allowNull && validator.allowNull.toLowerCase() === 'true') {
|
|
const ruleRequired: {[key: string]: any} = {}
|
|
ruleRequired.required = true
|
|
ruleRequired.trigger = 'blur'
|
|
ruleRequired.messahe = localizer('AbpFeatureManagement.ThisFieldIsRequired')
|
|
featureRules.push(ruleRequired)
|
|
}
|
|
const ruleString: {[key: string]: any} = {}
|
|
ruleString.min = validator.minLength
|
|
ruleString.max = validator.maxLength
|
|
ruleString.trigger = 'blur'
|
|
ruleString.message = localizer('AbpFeatureManagement.ThisFieldMustBeBetween{0}And{1}', { 0: validator.minValue, 1: validator.maxValue })
|
|
featureRules.push(ruleString)
|
|
}
|
|
return featureRules
|
|
}
|
|
},
|
|
methods: {
|
|
/**
|
|
* 本地化method
|
|
*/
|
|
localizer(name: string, values?: any[]) {
|
|
return this.$t(name, values)
|
|
}
|
|
}
|
|
})
|
|
export default class extends Vue {
|
|
/**
|
|
* 功能提供者名称
|
|
*/
|
|
@Prop({ default: '' })
|
|
private providerName!: string
|
|
|
|
/**
|
|
* 功能提供者标识
|
|
*/
|
|
@Prop({ default: '' })
|
|
private providerKey!: string
|
|
|
|
/**
|
|
* 默认选择tab选项卡
|
|
* 如果不定义的话,动态组合的表单需要手动点击一次才会显示?
|
|
*/
|
|
private selectTab = ''
|
|
/**
|
|
* 用于拼接动态表单的功能数据,需要把abp返回的数据做一次调整
|
|
*/
|
|
private features = new FeatureItems()
|
|
|
|
@Watch('providerKey', { immediate: true })
|
|
onProviderKeyChanged() {
|
|
if (this.providerKey) {
|
|
this.handleGetFeatures()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 重置表单数据
|
|
*/
|
|
public resetFeature() {
|
|
this.features = new FeatureItems()
|
|
}
|
|
|
|
/**
|
|
* 获取功能列表
|
|
*/
|
|
private handleGetFeatures() {
|
|
FeatureManagementService.getFeatures(this.providerName, this.providerKey).then(res => {
|
|
this.features = new FeatureItems()
|
|
res.features.forEach(feature => {
|
|
const featureTrue = new FeatureItem(
|
|
feature.name,
|
|
feature.value,
|
|
feature.displayName,
|
|
feature.description,
|
|
feature.valueType,
|
|
feature.depth
|
|
)
|
|
if (feature.parentName) {
|
|
const children = this.features.features.find(f => f.name === feature.parentName)
|
|
if (children) {
|
|
children.appendChildren(featureTrue)
|
|
} else {
|
|
this.features.features.push(featureTrue)
|
|
}
|
|
} else {
|
|
this.features.features.push(featureTrue)
|
|
}
|
|
})
|
|
// 需要手动选择一下?
|
|
if (this.features.features.length > 0) {
|
|
this.selectTab = this.features.features[0].name
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 保存变更
|
|
*/
|
|
private onSave() {
|
|
if (this.features.features.length > 0) {
|
|
const frmFeature = this.$refs.frmFeature as any
|
|
frmFeature.validate((valid: boolean) => {
|
|
if (valid) {
|
|
const updateFeatures = new Features()
|
|
this.features.features.forEach(feature => {
|
|
this.getChangedFeatures(feature, updateFeatures)
|
|
})
|
|
FeatureManagementService
|
|
.updateFeatures(this.providerName, this.providerKey, updateFeatures)
|
|
.then(() => {
|
|
this.$message.success(this.$t('global.successful').toString())
|
|
this.onClosed()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 递归获取abp的功能接口格式数据
|
|
*/
|
|
private getChangedFeatures(feature: FeatureItem, features: Features) {
|
|
const updateFeature = new Feature(feature.name, feature.value)
|
|
features.features.push(updateFeature)
|
|
feature.children.forEach(children => {
|
|
this.getChangedFeatures(children, features)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 关闭模态窗口
|
|
*/
|
|
private onClosed() {
|
|
this.$emit('closed')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.confirm {
|
|
width: 120px;
|
|
position: absolute;
|
|
right: 180px;
|
|
}
|
|
.cancel {
|
|
width: 120px;
|
|
position: absolute;
|
|
right: 40px;
|
|
}
|
|
</style>
|
|
|