302 lines
7.6 KiB
Vue
302 lines
7.6 KiB
Vue
<template>
|
|
<div class="attr-form">
|
|
<h3>
|
|
{{ title }} <el-button style="margin-left: 8px;" type="text" v-if="!isDetail && !showAddAttr" @click="showAddAttr = true">{{ $t('add') }}</el-button>
|
|
</h3>
|
|
<div v-if="!showAddAttr">
|
|
<component
|
|
key="sub-table"
|
|
:is="require('./BaseTable.vue').default"
|
|
:table-head-configs="filterTableConfigs()"
|
|
:data="dataList"
|
|
:page="pageIndex"
|
|
:size="pageSize"
|
|
:max-height="calcMaxHeight(8)"
|
|
@operate-event="handleOperations"
|
|
/>
|
|
<el-pagination
|
|
@size-change="sizeChangeHandle"
|
|
@current-change="currentChangeHandle"
|
|
:current-page="pageIndex"
|
|
:page-sizes="[5, 10, 20, 50]"
|
|
:page-size="pageSize"
|
|
:total="totalPage"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
>
|
|
</el-pagination>
|
|
</div>
|
|
<div v-else style="background: #eee; border-radius: 8px; padding: 12px;">
|
|
<el-row>
|
|
<el-col>
|
|
<el-form ref="AttrForm" :model="AttrForm" :rules="AttrFormRules" :inline="true" label-position="top">
|
|
<el-row :gutter="20" style="padding: 0 24px;">
|
|
<el-col :span="attrFormFields.length > 6 ? 6 : 12" v-for="field in attrFormFields" :key="field.prop + 'col'">
|
|
<el-form-item :key="field.prop" :prop="field.prop" :label="field.name" style="width: 100%">
|
|
<el-input v-if="field.formType === 'input' || !field.formType" v-model="AttrForm[field.prop]" :placeholder="$t('hints.input')" clearable />
|
|
<el-select v-if="field.formType === 'select'" v-model="AttrForm[field.prop]" clearable>
|
|
<el-option v-for="opt in field.formOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
|
</el-select>
|
|
<!-- add more... -->
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row style="text-align: right;">
|
|
<el-button size="small" @click="handleCloseAttrForm">{{ $t('cancel') }}</el-button>
|
|
<el-button type="success" size="small" @click="handleSaveAttrForm">{{ $t('save') }}</el-button>
|
|
</el-row>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import i18n from '@/i18n'
|
|
import BaseTable from '@/components/base-table'
|
|
import { pick } from 'lodash/object'
|
|
|
|
|
|
/** 计算表格的最大高 */
|
|
function calcMaxHeight(num) {
|
|
const FIXED_HEIGHT = 220
|
|
let clientHeight = 0
|
|
const bodyHeight = document.body.clientHeight || null
|
|
const documentHeight = document.documentElement.clientHeight || null
|
|
if (bodyHeight && documentHeight) {
|
|
clientHeight = Math.max(bodyHeight, documentHeight)
|
|
} else {
|
|
clientHeight = documentHeight ? documentHeight : bodyHeight
|
|
}
|
|
|
|
const finalHeight = clientHeight - num - FIXED_HEIGHT
|
|
return finalHeight > 0 ? finalHeight : -finalHeight
|
|
}
|
|
|
|
|
|
export default {
|
|
name: 'AttrForm',
|
|
components: { BaseTable },
|
|
props: {
|
|
isDetail: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
visible: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
/** subtable 需要设置的属性 */
|
|
title: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
url: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
tableConfigs: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
/** 表单提交需要的属性 */
|
|
relatedId: {
|
|
type: String,
|
|
required: true,
|
|
default: null
|
|
},
|
|
relatedField: {
|
|
type: String,
|
|
required: true,
|
|
default: null
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
calcMaxHeight,
|
|
showAddAttr: false,
|
|
dataList: [],
|
|
pageIndex: 1,
|
|
pageSize: 10,
|
|
totalPage: 0,
|
|
AttrForm: {}, // 需动态设置
|
|
AttrFormRules: {} // 需动态设置
|
|
}
|
|
},
|
|
computed: {
|
|
attrFormFields() {
|
|
const _ = this.tableConfigs.filter(item => item.formField)
|
|
/** 顺带配置 AttrForm */
|
|
_.forEach(item => {
|
|
this.$set(this.AttrForm, [item.prop], '')
|
|
})
|
|
|
|
this.$set(this.AttrForm, 'id', null)
|
|
return _
|
|
}
|
|
},
|
|
mounted() {
|
|
this.getDataList()
|
|
/** 设置 AttrForm 的 rules */
|
|
for (const config of this.tableConfigs) {
|
|
if (config.rules) {
|
|
this.$set(this.AttrFormRules, [config.prop], config.rules)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
filterTableConfigs() {
|
|
if (this.isDetail) {
|
|
/** 如果是查看详情,就屏蔽操作列 */
|
|
return this.tableConfigs.filter(opt => opt.prop !== 'operations')
|
|
}
|
|
return this.tableConfigs
|
|
},
|
|
/** init dataform */
|
|
initAttrForm() {
|
|
Object.entries(this.AttrForm).forEach(([key, value]) => {
|
|
if (typeof value === 'object' || typeof value === 'number') {
|
|
this.AttrForm[key] = null
|
|
} else if (Array.isArray(value)) {
|
|
this.AttrForm[key] = []
|
|
} else {
|
|
this.AttrForm[key] = ''
|
|
}
|
|
})
|
|
},
|
|
|
|
/** requests */
|
|
getDataList() {
|
|
this.dataListLoading = true
|
|
// 获取动态属性列表
|
|
this.$http({
|
|
url: this.$http.adornUrl(`${this.url}/page`),
|
|
method: 'get',
|
|
params: this.$http.adornParams({
|
|
page: this.pageIndex,
|
|
limit: this.pageSize,
|
|
[this.relatedField]: this.relatedId
|
|
// order: 'asc/desc',
|
|
// orderField: 'name'
|
|
})
|
|
}).then(({ data: res }) => {
|
|
if (res && res.code === 0) {
|
|
this.dataList = res.data.list
|
|
this.totalPage = res.data.total
|
|
} else {
|
|
this.dataList = []
|
|
this.totalPage = 0
|
|
}
|
|
this.dataListLoading = false
|
|
})
|
|
},
|
|
|
|
/** handlers */
|
|
handleOperations({ type, data: id }) {
|
|
switch (type) {
|
|
case 'edit':
|
|
{
|
|
this.showAddAttr = true
|
|
this.$nextTick(() => {
|
|
this.$http.get(this.$http.adornUrl(`${this.url}/${id}`)).then(({ data: res }) => {
|
|
if (res && res.code === 0 && res.data) {
|
|
const neededFields = [...this.attrFormFields.map(item => item.prop), 'id']
|
|
const filtered = pick(res.data, neededFields)
|
|
for (let field of neededFields) {
|
|
this.AttrForm[field] = filtered[field]
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
break
|
|
case 'delete':
|
|
return this.deleteHandle(id)
|
|
}
|
|
},
|
|
deleteHandle(id) {
|
|
var ids = id ? [id] : []
|
|
|
|
this.$confirm(`${i18n.t('prompt.info', { handle: id ? i18n.t('delete').toLowerCase() : i18n.t('deleteBatch').toLowerCase() })}`, i18n.t('prompt.title'), {
|
|
confirmButtonText: i18n.t('confirm'),
|
|
cancelButtonText: i18n.t('cancel'),
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.$http({
|
|
url: this.$http.adornUrl(this.url),
|
|
method: 'delete',
|
|
data: this.$http.adornData(ids, false, 'raw')
|
|
}).then(({ data }) => {
|
|
if (data && data.code === 0) {
|
|
this.$message({
|
|
message: i18n.t('prompt.success'),
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {
|
|
this.getDataList()
|
|
}
|
|
})
|
|
} else {
|
|
this.$message.error(data.msg)
|
|
}
|
|
})
|
|
})
|
|
},
|
|
|
|
handleCloseAttrForm() {
|
|
this.showAddAttr = false
|
|
this.initAttrForm()
|
|
},
|
|
|
|
handleSaveAttrForm() {
|
|
this.$refs['AttrForm'].validate(valid => {
|
|
if (valid) {
|
|
this.$http({
|
|
// url: this.$http.adornUrl(`${this.url}/${!this.AttrForm.id ? '' : this.AttrForm.id}`),
|
|
url: this.$http.adornUrl(this.url),
|
|
method: this.AttrForm.id ? 'put' : 'post',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
data: JSON.stringify({ ...this.AttrForm, [this.relatedField]: this.relatedId })
|
|
}).then(({ data }) => {
|
|
if (data && data.code === 0) {
|
|
this.$message({
|
|
message: i18n.t('prompt.success'),
|
|
type: 'success',
|
|
duration: 1500,
|
|
onClose: () => {
|
|
this.showAddAttr = false
|
|
this.getDataList()
|
|
this.initAttrForm()
|
|
}
|
|
})
|
|
} else {
|
|
this.$message.error(data.msg)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
},
|
|
|
|
// 每页数
|
|
sizeChangeHandle(val) {
|
|
this.pageSize = val
|
|
this.pageIndex = 1
|
|
this.getDataList()
|
|
},
|
|
// 当前页
|
|
currentChangeHandle(val) {
|
|
this.pageIndex = val
|
|
this.getDataList()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.attr-form >>> .el-form .el-form-item__label {
|
|
padding: 0;
|
|
}
|
|
</style>
|