301 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | ||
| 	<div class="attr-form">
 | ||
| 		<h3>
 | ||
| 			<!-- <el-button style="margin-left: 8px" type="text" v-if="!isDetail && !showAddAttr" @click="showAddAttr = true">{{ $t('add') }}</el-button>  跟在{{ title }} 同行后面 -->
 | ||
| 			{{ title }}
 | ||
| 		</h3>
 | ||
| 		<div v-if="!showAddAttr">
 | ||
| 			<component
 | ||
| 				:top-btn-config="topBtnConfig"
 | ||
| 				key="sub-table"
 | ||
| 				:is="require('../../base-table/index.vue').default"
 | ||
| 				:table-head-configs="filterTableConfigs()"
 | ||
| 				:data="dataList"
 | ||
| 				:page="pageIndex"
 | ||
| 				:size="pageSize"
 | ||
| 				:max-height="calcMaxHeight(8)"
 | ||
| 				@clickTopBtn="clickTopBtn"
 | ||
| 				@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'
 | ||
| import { calcMaxHeight } from '@/utils'
 | ||
| const topBtnConfig = [
 | ||
| 	{
 | ||
| 		type: 'add',
 | ||
| 		btnName: i18n.t('add')
 | ||
| 	}
 | ||
| ]
 | ||
| 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,
 | ||
| 			topBtnConfig,
 | ||
| 			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)
 | ||
| 			}
 | ||
| 		}
 | ||
| 	},
 | ||
| 	// 加个created,来实现不能在topBtnConfig组件直接使用的? : 判别
 | ||
| 	created() {
 | ||
| 		// if(!(!this.isDetail && !this.showAddAttr)) {
 | ||
| 		// 	this.topBtnConfig = []
 | ||
| 		// }
 | ||
| 	},
 | ||
| 	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()
 | ||
| 		},
 | ||
| 		clickTopBtn() {
 | ||
| 			this.showAddAttr = true
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped>
 | ||
| .attr-form >>> .el-form .el-form-item__label {
 | ||
| 	padding: 0;
 | ||
| }
 | ||
| </style>
 |