middleground_code_v2/src/views/masterDataOptions/compoments/baseNewForm.vue

925 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @name: 自定义表单组件
* @author: zhangpengcheng
* @date: 2022-08-24
-->
<template>
<el-form
validate-on-rule-change
:model="ruleForm"
:rules="rules"
:label-position="labelPosition"
:ref="refName"
:label-width="labelWidth"
>
<el-row
:gutter="0"
v-for="(item, index) in formRow"
:key="index"
style="margin-bottom: 10px"
>
<el-col
v-for="(row, indexRow) in item.elCol"
:span="row.row ? row.row * 1 : spanNumber"
:key="row.id"
>
<el-form-item
:prop="row.id"
:style="`display: flex;margin-bottom: ${marginBottom}px;padding:0 20px`"
v-if="row.show != false"
:class="rules[row.id] ? 'ruleFormClass ' : ''"
:rules="
formRule
? [
{
required: row.required,
message: `${row.title}不能为空`,
trigger: row.type === 'input' ? 'change' : 'blur',
},
...(row.pattern && row.message
? [
{
pattern: row.pattern,
message: row.message,
trigger: 'blur',
},
]
: []),
]
: []
"
>
<div
class="single label"
v-if="row.label || row.title"
slot="label"
:style="`` + `justify-content: ${justifyContent};`"
flex
>
<span
class="label"
:style="`font-size:${
row.fontSize ? row.fontSize + 'px' : '13px'
}`"
>
<span v-if="row.required" style="color: red">*</span>
{{ row.title }}:
</span>
</div>
<template v-if="!lookFlag">
<el-checkbox
v-model="ruleForm[row.id]"
v-if="row.type == 'onecheck'"
:disabled="disabled"
>是
</el-checkbox>
<el-input
v-model="ruleForm[row.id]"
clearable
:disabled="disabled || (row.disabledOfId?Boolean(ruleForm.id):row.disabled) "
:rows="row.rows ? row.rows : 2"
:type="row.type ? row.type : 'text'"
:maxlength="row.maxlength ? row.maxlength * 1 : '99'"
:placeholder="!row.placeholder ? '请输入' : row.placeholder"
v-if="
row.tag === 'elInput' || (row.type === 'input' && !lookFlag)
"
@blur="searchByStationName(row.id,ruleForm)"
min="1"
@input="row.rules ? integerNumber(row) : ''"
@dblclick.native="row.double?dblclick(ruleForm[row.id]):''"
@change="$emit('onInput')"
>
</el-input>
<el-input
type="number"
v-if="row.type === 'num'"
v-model="ruleForm[row.id]"
style="width: 100%"
:disabled="(row.disabled && !newFlag ? row.disabled : false) || disabled"
:precision="row.precisionNum ? row.precisionNum : 0"
:placeholder="!row.placeholder ? '请输入' : row.placeholder"
:step="row.stepNum ? row.stepNum : 1"
@change="handleChange"
@input="(val) => limitPhoneNum(val, ruleForm, row.id)"
:maxlength="row.maxlength ? row.maxlength * 1 : 50"
:min="1"
:max="row.max ? row.max : 255"
:label="!row.placeholder ? '描述文字' : row.placeholder"
>
<template slot="append" v-if="row.message">{{ row.message }}</template>
</el-input
>
<el-switch
v-if="row.type === 'switch' && !lookFlag"
v-model="ruleForm[row.id]"
:active-text="row.activeText"
@change="switchChange($event, index, indexRow, row)"
:inactive-text="row.inactiveText"
:active-value="row.activeValue ? row.activeValue : true"
:inactive-value="
row.inactiveValue || row.inactiveValue == 0
? row.inactiveValue
: false
"
>
</el-switch>
<baseDatePicker
class="w-100"
v-model="ruleForm[row.id]"
v-if="
row.tag === 'elDatePicker' ||
(row.type === 'datepick' && !lookFlag)
"
:disabled="row.disabled && !newFlag"
:datePickerType="formRule ? 'date' : 'daterange'"
>
</baseDatePicker>
<baseDatePicker
class="w-100"
v-model="ruleForm[row.id]"
v-if="row.type === 'datetiempick' && !lookFlag"
:disabled="row.disabled && !newFlag"
datePickerType="datetime"
>
</baseDatePicker>
<el-radio-group
v-model="ruleForm[row.id]"
v-if="
row.tag === 'elRadio' || (row.type === 'radio' && !lookFlag)
"
@input="changeRadio($event, index, indexRow, row)"
:disabled="row.disabled && !newFlag ? row.disabled : false"
>
<el-radio v-for="el in row.options" :label="el.id" :key="el.id">{{
el.label
}}
</el-radio>
</el-radio-group>
<el-input
type="textarea"
v-if="row.type === 'textrea' && !lookFlag"
resize="none"
:rows="4"
placeholder="请输入内容"
show-word-limi
v-model="ruleForm[row.id]"
:disabled="row.disabled && !newFlag"
>
</el-input>
<el-select
class="w-100"
v-model="ruleForm[row.id]"
filterable
:multiple="row.multiple"
@change="selectChange($event, index, indexRow, row)"
:disabled="row.disabled || disabled"
:clearable="row.clearable ? row.clearable : true"
:placeholder="!row.placeholder ? '请选择' : row.placeholder"
v-if="
row.tag === 'select' || (row.type === 'select' && !lookFlag)
"
>
<el-option
v-for="(el, index) in row.options"
:key="!row.optionValue ? el['id'] : el[row.optionValue]"
:label="!row.optionLabel ? el['label'] : el[row.optionLabel]"
:value="!row.optionValue ? el['id'] : el[row.optionValue]"
>
</el-option>
</el-select>
<baseNewSelect
:ref="row.refName"
:apiInfo="row.apiInfo"
:searchApiInfo="row.searchApiInfo"
v-if="row.type === 'newSelect'"
v-model="ruleForm[row.id]"
:itemObj="row"
@showValue="showValueHandle"
:idKey="row.id"
:journalingType="row.journalingType"
:prop="row.prop"
:foucus="row.foucus"
:apiBody="row.apiBody"
:searchKey="row.searchKey"
@selectChange="selectChangeHanlde"
>
</baseNewSelect>
<slot
:name="row.slotName"
v-if="row.type === 'elSlot'"
:row="{row,ruleForm}"
></slot>
</template>
<template v-else>
<div
v-if="
row.type !== 'radio' &&
row.type !== 'newSelect' &&
row.type !== 'select' &&
lookFlag
"
>
{{ ruleForm[row.id] }}
</div>
<baseNewSelect
:disabled="true"
:ref="row.refName"
:apiInfo="row.apiInfo"
:searchApiInfo="row.searchApiInfo"
v-if="row.type === 'newSelect'"
v-model="ruleForm[row.id]"
:itemObj="row"
@showValue="showValueHandle"
:idKey="row.id"
:journalingType="row.journalingType"
:prop="row.prop"
:foucus="row.foucus"
:apiBody="row.apiBody"
:searchKey="row.searchKey"
>
</baseNewSelect>
<el-radio-group
v-model="ruleForm[row.id]"
v-if="row.type === 'radio'"
@input="changeRadio($event, index, indexRow, row)"
:disabled="true"
>
<el-radio v-for="el in row.options" :label="el.id" :key="el.id">{{
el.label
}}
</el-radio>
</el-radio-group>
<el-checkbox-group
class="w-100"
v-if="row.type === 'checkbox'"
v-model="ruleForm[row.id]"
>
{{ 123 }}
<el-checkbox
v-for="(el, index) in row.options"
:key="el.id"
:label="el.id"
>{{ el.label }}
</el-checkbox
>
</el-checkbox-group>
<baseCascader
v-if="row.type === 'treeselect'"
v-model="ruleForm[row.id]"
:disabled="row.disabled && !newFlag"
:itemObj="row"
:ruleForm="ruleForm"
:lookflag="lookFlag"
class="w-100"
></baseCascader>
<el-select
class="w-100"
v-model="ruleForm[row.id]"
filterable
@change="selectChange($event, index, indexRow, row)"
:disabled="true"
:clearable="row.clearable ? row.clearable : true"
:placeholder="!row.placeholder ? '请选择' : row.placeholder"
v-if="row.type === 'select' && lookFlag"
>
<el-option
v-for="(el, index) in row.options"
:key="!row.optionValue ? el['id'] : el[row.optionValue]"
:label="!row.optionLabel ? el['label'] : el[row.optionLabel]"
:value="!row.optionValue ? el['id'] : el[row.optionValue]"
>
</el-option>
</el-select>
</template>
<slot :name="row.slotName" v-if="row.tag === 'elSlot'"></slot>
</el-form-item>
</el-col>
</el-row>
<slot name="main"></slot>
<el-form-item v-if="false" style="margin-top: 20px; padding: 0 20px">
<!-- flex="cross:center main:center" -->
<div flex="main:right">
<el-button
v-if="isFunBtn"
class="saveBtn"
type="primary"
:loading="loading"
@click="submitForm(refName)"
>提交
</el-button
>
<el-button v-if="!lookFlag" @click="resetForm(refName)">重置</el-button>
<el-button v-if="isFunBtn" @click="close()">取消</el-button>
</div>
</el-form-item>
</el-form>
</template>
<script>
import baseCascader from './baseCascader/index.vue'
import { deepClone } from '@/utils/index.js'
import baseDatePicker from './baseDatePicker.vue'
import baseNewSelect from './baseNewSelect'
import { checkMobile } from '@/utils/util'
import { BaseSelect } from './baseSelect.vue'
export default {
components: {
// uploadFile,
// customCascader
baseNewSelect,
baseDatePicker,
baseCascader,
BaseSelect
},
props: {
labelWidth: {
type: String,
default: '80px'
},
labelPosition: {
type: String,
default: 'top'
},
// 提交按钮loading
loading: {
type: Boolean,
default: false
},
// 是否校验正则(搜索模式)
formRule: {
type: Boolean,
default: true
},
refName: {
type: String,
default: 'ruleForm'
},
// 表单新建模式
newFlag: {
type: Boolean,
default: false
},
// 表单查看模式
lookFlag: {
type: [Boolean, String],
default: false
},
// 表单显示格式
spanNumber: {
type: Number,
default: 12
},
spanWidth: {
type: String,
default: '200px'
},
// 表单验证规则
rules: {
type: Object,
default: () => {
return {}
}
},
// 表单页面结构数据
formRow: {
type: Array,
default: () => {
return []
}
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否显示操作按钮
isFunBtn: {
type: Boolean,
default: true
},
formdata: {
type: Object
},
justifyContent: {
type: String,
default: 'flex-end'
},
marginBottom: {
type: String,
default: '0'
},
ruleForm: {
type: Object,
default: () => {
return {}
}
},
tableColumn: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
pickerOptionsSearch: {
shortcuts: [
{
text: '本月',
onClick(picker) {
picker.$emit('pick', [new Date(), new Date()])
}
},
{
text: '今年至今',
onClick(picker) {
const end = new Date()
const start = new Date(new Date().getFullYear(), 0)
picker.$emit('pick', [start, end])
}
},
{
text: '最近六个月',
onClick(picker) {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 6)
picker.$emit('pick', [start, end])
}
}
]
},
// 表单数据
// ruleForm: {},
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now()
},
shortcuts: [
{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date())
}
},
{
text: '昨天',
onClick(picker) {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24)
picker.$emit('pick', date)
}
},
{
text: '一周前',
onClick(picker) {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', date)
}
}
]
},
tempFormData: {}
}
},
watch: {
ruleForm: {
immediate: true, // 立即执行
deep: true, // 深度监听复杂类型内变化
handler(newVal, oldVal) {
this.$emit('dataChanges')
}
}
},
created() {
this.tempFormData = deepClone(this.ruleForm)
},
mounted() {
// this.ruleForm = this.formdata
},
computed: {},
methods: {
dblclick(val) {
this.$emit('dblclick', val)
},
selectChangeHanlde(val, row) {
console.log(val, row, 111)
this.$emit('selectChange', val, row)
},
showValueHandle() {
},
limitPhoneNum(value, data, id) {
if (value.toString().length > 11) {
data[id] = value.toString().slice(0, 11)
}
},
selectShow(row) {
try {
this.$emit('selectFormSearch', row)
} catch (error) {
console.log(this.ruleForm, row, '23232出错了')
}
},
close() {
this.$emit('closeDialog')
},
integerNumber(row) {
// row.rules?(v)=>()):''
// @input="(v)=>(row.row.number=v.replace(/[^\d]/g,''))"
// if(this.ruleForm[row.prop].replace(/[^\d]/g,'')){
// return this.ruleForm[row.prop].replace(/[^\d]/g,'')
//
// integer整数
if (row.rulesName == 'integer') {
this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(/[^\d]/g, '')
}
// decimal小数
if (row.rulesName == 'decimal') {
this.ruleForm[row.id] = this.ruleForm[row.id]
.replace(/[^\d.]/g, '')
.replace(/\.{2,}/g, '.')
.replace('.', '$#$')
.replace(/\./g, '')
.replace('$#$', '.')
.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
.replace(/^\./g, '')
}
// 身份证
if (row.rulesName == 'identity') {
this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(
/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
''
)
}
// 手机号
if (row.rulesName == 'phone') {
this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(
/^1(3|4|5|7|8|9)\\d{9}$/,
''
)
// this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(/^1[3,4,5,6,7,8,9][0-9]{9}$/, '')
// this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(/1(\d{2})\d{4}(\d{4})/g,'').replace(/[^\d]/g, '')
// this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(/\.{11,}/g, '')
// /^1[3|4|5|6|7|8|9][0-9]\d{8}$/
}
// 邮箱
if (row.rulesName == 'eMail') {
this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(
/^([0-9a-zA-Z_\.\-\])+\@([0-9a-zA-Z_\.\-\])+\.([a-zA-Z]+)$/,
''
)
}
// this.ruleForm[row.prop] = this.ruleForm[row.prop].replace(/[^\d]/g,'')
},
//根据地址获取经纬度
searchByStationName(type, form) {
this.$emit('inputBlur', type, form)
if (type == 'address') {
let address = this.ruleForm[type]
let that = this
var map = new BMap.Map('container')
map.centerAndZoom(address, 18)
map.enableScrollWheelZoom() //启用滚轮放大缩小,默认禁用
map.enableContinuousZoom() //启用地图惯性拖拽,默认禁用
map.addControl(new BMap.NavigationControl()) //添加默认缩放平移控件
map.addControl(new BMap.OverviewMapControl()) //添加默认缩略地图控件
map.addControl(
new BMap.OverviewMapControl({
isOpen: true,
anchor: BMAP_ANCHOR_BOTTOM_RIGHT
})
) //右下角,打开
var localSearch = new BMap.LocalSearch(map)
localSearch.enableAutoViewport() //允许自动调节窗体大小
map.clearOverlays() //清空原来的标注
var keyword = address
localSearch.setSearchCompleteCallback(function(searchResult) {
var poi = searchResult.getPoi(0)
map.centerAndZoom(poi.point, 13)
var marker = new BMap.Marker(
new BMap.Point(poi.point.lng, poi.point.lat)
) // 创建标注,为要查询的地方对应的经纬度
map.addOverlay(marker)
var content =
keyword +
'<br/><br/>经度:' +
poi.point.lng +
'<br/>纬度:' +
poi.point.lat
that.ruleForm['lng'] = poi.point.lng
that.ruleForm['lat'] = poi.point.lat
var infoWindow = new BMap.InfoWindow(
'<p style=\'font-size:14px;\'>' + content + '</p>'
)
marker.addEventListener('click', function() {
this.openInfoWindow(infoWindow)
})
// marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
})
localSearch.search(keyword)
}
},
//计步器
handleChange(val) {
this.$emit('handleChange', val)
},
// 获取图片
getImage(imagePath) {
let licenseImg = imagePath.join(',')
},
// 处置前照片
getbeforeImgList(imagePath) {
let licenseImg = imagePath.join(',')
this.$set(this.ruleForm, 'beforeImgList', licenseImg)
},
// 处置材料
getmaterialsList(imagePath) {
let licenseImg = imagePath.join(',')
this.$set(this.ruleForm, 'materialsList', licenseImg)
},
// 处置后材料
getmaterialsListAfter(imagePath) {
let licenseImg = imagePath.join(',')
this.$set(this.ruleForm, 'materialsListAfter', licenseImg)
},
revealPhoto(licenseImg) {
this.$refs.imgFile.revealImg(licenseImg)
},
// 回显数据
echoFromData(echoData, otherField) {
let jsonData = []
this.formRow.forEach((item) => {
jsonData.push(item.elCol)
})
let newJson = [].concat.apply([], jsonData)
newJson.forEach((item) => {
if (this.ruleForm.factoryInFlag == 1) {
for (let i = 0; i < this.formRow[8].elCol.length; i++) {
}
}
if (this.ruleForm.factoryInFlag == 0) {
for (let i = 0; i < this.formRow[8].elCol.length; i++) {
}
}
this.$set(this.ruleForm, item.prop, echoData[item.prop])
})
// 回显自定义多级选择组件
if (typeof otherField == 'object') {
this.$refs[otherField.props][0].setEchoData(echoData[otherField.field])
}
},
// 获取指定字段参数
//参数propLabel 值value
getField(propLabel, value) {
this.$set(this.ruleForm, propLabel, value)
},
//弹窗赋值
choiceAssignment(value) {
this.ruleForm = Object.assign({}, value)
// this.$forceUpdate()
},
incomingParameters(vale) {
let ruleLength = 0
let valeLength = 0
for (let i in vale) {
valeLength = valeLength + 1
}
for (let i in this.ruleForm) {
ruleLength = ruleLength + 1
}
// if(ruleLength == valeLength){
// this.choiceAssignment(vale)
// }else{
// for(let i in vale){
// this.getField(i,vale[i])
// }
// }
for (let i in vale) {
this.getField(i, vale[i])
}
},
resetFormPlus(formName) {
for (let i in this.$refs[formName]) {
this.getField(i, '')
}
},
// 重置表单字段
resetField(field) {
if (this.ruleForm[field]) {
this.$set(this.ruleForm, field, '')
this.$refs['ruleForm'].clearValidate(field) // 清除表单特定属性
}
},
resetForm() {
this.$refs[this.rulesName].clearValidate() // 清除表单特定属性
},
resetFields() {
// this.choiceAssignment({});
this.$refs.ruleForm.resetFields()
},
// 下拉框更改,可根据 index 与 indexRow 定位具体位置
selectChange(val, index, indexRow, row) {
this.$emit('onSelect', val, index, indexRow, row)
this.$forceUpdate()
},
switchChange(val, index, indexRow, row) {
this.$emit('switchChange', val, index, indexRow, row)
},
// 自定义级联选择器返回值
getCascader(value, field) {
this.$set(this.ruleForm, field, value)
},
// 表单提交
submitForm() {
this.$refs[this.refName].validate((valid) => {
if (valid) {
this.$emit('onSubmit', this.ruleForm)
} else {
console.log('error submit!!')
return false
}
})
},
// 表单重置
resetForm() {
// let tempObj = deepClone(this.tempFormData);
// this.tableColumn
// .filter((item) => item.disabled)
// .forEach((item) => {
// tempObj[item.id] = this.ruleForm[item.id];
// });
// this.choiceAssignment({});
// this.$emit("resetForm", tempObj);
this.$refs[this.refName].resetFields()
},
clearCheck(propName) {
this.ruleForm[propName] = ''
},
elDialogClick(row, index, indexRow) {
if (row.disabled) {
return
}
// row.prop
this.$emit('elDialogClick', row, index)
},
elDialogHover(row) {
row.elDialogHoverType = true
},
elDialogLeave(row) {
// row.elDialogHoverType = false
},
// 单选按钮组input事件
changeRadio(val, index, indexRow, row) {
this.$emit('onChangeRadio', val, index, indexRow, row)
},
normalizer(node, row) {
//去掉children=null的属性
if (node.children == null || node.children == 'null') {
delete node.children
}
// return{
// ...node,
// label:nodeLabel
// }
},
selectTree(row) {
this.$emit('selectTree')
if (this.$refs.ruleForm) {
this.$nextTick(() => {
this.$refs.ruleForm.validateField(row.id)
})
}
},
treeSelectClear() {
this.$refs.selectTree.clear()
}
},
mounted() {
// this.$refs.ruleForm.resetFields();
}
}
</script>
<style>
.el-form-item__label {
/* width: 25%; */
line-height: 1.2;
}
.el-form-item--medium .el-form-item__content {
/* line-height: 36px; */
flex: 1;
}
.el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before {
margin-right: 0;
content: "";
}
</style>
<style scoped lang="scss">
::v-deep .el-form-item__label {
padding: 0 0 5px !important;
}
.label {
/* @include fontBase(16px, #333333) ; */
color: #999;
font-size: 13px;
display: block;
width: 180px;
// text-align: left;
}
> > > .el-form-item__label {
width: 100px;
text-align: right !important;
margin-right: 10px !important;
padding: 0 !important;
}
::v-deep .el-form-item__label:before {
display: none;
}
::v-deep .el-form-item__content {
margin-left: 10px;
// width: calc(100% - 100px);
}
.w-100 {
width: 100%;
}
.saveBtn {
/* width: 410px; */
}
.one {
width: calc(100% - 15px) !important;
}
.elDialog {
display: flex;
width: 100%;
/* width: calc(100% - 14px);1 */
align-items: center;
justify-content: space-between;
border: 1px solid #dcdfe6;
border-radius: 8px;
padding: 0 15px;
cursor: pointer;
i {
color: #c0c4cc;
}
}
.showText {
/* width: 100%; */
/* width: calc(100% - 110px); */
/*让长段文本不换行*/
white-space: nowrap;
/*设置文本超出元素宽度部分隐藏*/
overflow-x: hidden;
/*设置文本超出部分用省略号显示*/
text-overflow: ellipsis;
}
.ruleFormClass {
::v-deep .el-input__inner {
border-color: #e6a23c !important;
}
.elDialog {
border-color: #e6a23c !important;
}
::v-deep .el-radio__inner {
border-color: #e6a23c !important;
}
.el-radio.is-bordered {
border-color: #e6a23c !important;
}
::v-deep .vue-treeselect__control {
border-color: #e6a23c !important;
}
::v-deep .el-textarea__inner {
border-color: #e6a23c !important;
}
}
::v-deep.stretchNone {
.el-textarea__inner {
resize: none;
}
}
</style>