/* eslint-disable no-unused-vars */
|
<template>
|
<div class="form_main">
|
<el-form
|
:inline="true"
|
label-width="160px"
|
size="small"
|
:rules="formRules"
|
:model="formValues"
|
ref="createForm"
|
>
|
<div :style="{ width: screenWidth }" />
|
<el-form-item
|
v-for="(item, index) in formItems.filter(
|
form => form && form.show !== false
|
)"
|
v-bind:class="[
|
screenWidth > 1660 ? 'for_two_col_width' : 'for_col_width',
|
item.collapse === 2
|
? screenWidth > 1660
|
? 'for_two_col_collapse'
|
: 'for_col_collapse'
|
: '',
|
item.collapse === 3 ? 'for_three_col_collapse' : '',
|
item.addRow ? 'divider_style' : '',
|
item.type === 'file' && !isView && item.showRequired === 'Y'
|
? 'starShow'
|
: '',
|
isView && !isShowBorder ? 'non_boder' : ''
|
]"
|
:key="index"
|
:prop="item.name"
|
:label="isView ? item.label + ':' : item.label"
|
>
|
<div v-if="item.type === 'divider'"></div>
|
<el-input
|
v-if="item.type === 'input' && item.inputType !== 'age'"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
:disabled="item.readonly"
|
@input="handleInputChange(item.name, formValues[item.name])"
|
:type="item.inputType || 'text'"
|
:maxlength="item.maxlength || 1000"
|
></el-input>
|
<el-input
|
v-if="item.type === 'currency'"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
@blur="handleInputBlur(item.name)"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
:disabled="item.readonly"
|
:type="item.inputType || 'text'"
|
:maxlength="item.maxlength || 1000"
|
></el-input>
|
<el-input
|
v-if="item.inputType === 'age'"
|
v-model.number="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
:disabled="item.readonly"
|
:type="item.inputType || 'text'"
|
:maxlength="item.maxlength || 1000"
|
></el-input>
|
<el-input
|
v-if="item.type === 'textarea'"
|
type="textarea"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:rows="1"
|
:autosize="{ minRows: 1, maxRows: 6 }"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
:readonly="item.readonly"
|
:disabled="item.readonly"
|
></el-input>
|
<el-input
|
:placeholder="item.placeholder"
|
v-if="item.type === 'inputGet'"
|
v-model="formValues[item.name]"
|
:disabled="true"
|
>
|
<el-button
|
v-if="!item.readonly"
|
slot="suffix"
|
size="small"
|
type="primary"
|
style="margin-right: -5px;height: 32px;"
|
@click="$emit('handleGetValue', item.name)"
|
>{{ item.buttonName }}</el-button>
|
</el-input>
|
<el-select
|
v-if="item.type === 'select'"
|
:filterable="item.filterable || true"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
clearable
|
@focus="$emit('handleSelFocus', item.name, item.options)"
|
@change="
|
$emit(
|
'handleSelOnChange',
|
item.name,
|
formValues[item.name],
|
item.options.filter(
|
option => option.value === formValues[item.name]
|
)[0].label
|
)
|
"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
:disabled="item.readonly"
|
>
|
<el-option
|
v-for="(optionsItem, optionsIndex) in item.options"
|
:key="optionsIndex"
|
:label="optionsItem.label || optionsItem[item.labelKey]"
|
:value="optionsItem.value || optionsItem[item.valueKey]"
|
></el-option>
|
</el-select>
|
<el-input
|
v-if="item.type === 'select-dialog'"
|
:placeholder="item.placeholder"
|
v-model="formValues[item.name]"
|
:disabled="item.readonly"
|
>
|
<el-button
|
v-if="!item.readonly"
|
slot="append"
|
icon="el-icon-search"
|
@click="$emit('handleSelFocus', item.name, formValues[item.name])"
|
></el-button>
|
</el-input>
|
<el-select
|
v-if="item.type === 'select-remote'"
|
v-model="formValues[item.name]"
|
filterable
|
clearable
|
remote
|
reserve-keyword
|
:placeholder="item.placeholder"
|
:remote-method="remoteMethod"
|
>
|
<el-option
|
v-for="(optionsItem, optionsIndex) in item.options"
|
:key="optionsIndex"
|
:label="optionsItem.label || optionsItem[item.labelKey]"
|
:value="optionsItem.value || optionsItem[item.valueKey]"
|
></el-option>
|
</el-select>
|
<el-popover
|
v-if="item.type === 'selectTransfer' && !item.readonly"
|
placement="bottom-start"
|
popper-class="form_popper"
|
v-model="visible"
|
trigger="click"
|
>
|
<el-transfer
|
style="text-align: left; display: inline-block"
|
v-model="transferVal"
|
@right-check-change="rightCheckChange"
|
:left-default-checked="[]"
|
:right-default-checked="[]"
|
:render-content="renderFunc"
|
target-order="push"
|
:titles="['全选', '已选择']"
|
@change="handleChange"
|
:format="{
|
noChecked: '${total}',
|
hasChecked: '${checked}/${total}'
|
}"
|
:props="{
|
key: 'value',
|
label: 'label'
|
}"
|
:data="item.options"
|
>
|
<div slot="left-footer" class="transfer-footer"></div>
|
<el-button
|
class="transfer-footer"
|
slot="right-footer"
|
size="small"
|
@click="handleClearItem"
|
>清空</el-button>
|
<el-button
|
class="transfer-footer"
|
slot="right-footer"
|
size="small"
|
@click="handlePreference"
|
>优先</el-button>
|
<el-button
|
class="transfer-footer"
|
slot="right-footer"
|
size="small"
|
@click="handleNext"
|
>推后</el-button>
|
<el-button
|
class="transfer-footer"
|
slot="right-footer"
|
type="primary"
|
size="small"
|
@click="handleSub(item.options, item.name)"
|
>确定</el-button>
|
</el-transfer>
|
<el-input
|
:placeholder="item.placeholder"
|
slot="reference"
|
readonly
|
:disabled="item.readonly"
|
v-model="formValues[item.name]"
|
>
|
<i slot="suffix" class="el-input__icon el-icon-arrow-down"></i>
|
</el-input>
|
</el-popover>
|
<el-input
|
v-if="item.type === 'selectTransfer' && item.readonly"
|
:placeholder="item.placeholder"
|
:disabled="item.readonly"
|
v-model="formValues[item.name]"
|
></el-input>
|
|
<el-select
|
v-if="item.type === 'multipleSelect'"
|
:filterable="item.filterable || true"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:disabled="item.readonly"
|
clearable
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
multiple
|
>
|
<el-option
|
v-for="(optionsItem, optionsIndex) in item.options"
|
:key="optionsIndex"
|
:label="optionsItem && optionsItem.label"
|
:value="optionsItem && optionsItem.value"
|
></el-option>
|
</el-select>
|
<template v-if="formValues[item.name] !== '--'">
|
<el-date-picker
|
v-if="item.type === 'date'"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
type="date"
|
format="yyyy/MM/dd"
|
value-format="yyyy/MM/dd"
|
:disabled="item.readonly"
|
></el-date-picker>
|
<el-date-picker
|
v-if="item.type === 'dateTime'"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
type="datetime"
|
format="yyyy/MM/dd hh:mm:ss"
|
value-format="yyyy/MM/dd hh:mm:ss"
|
:disabled="item.readonly"
|
></el-date-picker>
|
<el-date-picker
|
v-if="item.type === 'rangeDate'"
|
v-model="formValues[item.name]"
|
:placeholder="item.placeholder"
|
:style="{ minWidth: item.minWidth, width: '100%' }"
|
type="daterange"
|
range-separator="-"
|
format="yyyy/MM/dd"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
:disabled="item.readonly"
|
value-format="yyyy/MM/dd"
|
></el-date-picker>
|
</template>
|
<!-- 处理日期为空转译成'--'的情况,否则日期为空无法显示为'--' -->
|
<template
|
v-if="(item.type === 'date' || item.type === 'dateTime' || item.type === 'rangeDate') && formValues[item.name] === '--'"
|
>{{formValues[item.name]}}</template>
|
<FileUpload
|
v-if="item.type === 'file'"
|
:fileInfo="item.fileInfo"
|
:isUpload="!item.readonly"
|
:multiple="item.multiple"
|
:isShowTitle="item.isShowTitle"
|
:disabled="item.readonly"
|
@beforeAvatarUpload="beforeAvatarUpload"
|
@handleUpload="handleUpload"
|
@handleDelete="handleDelete"
|
/>
|
<div
|
class="el-form-item__error"
|
v-if="isShowOld && oldVal[item.name]"
|
>原值:{{ oldVal[item.name] }}</div>
|
</el-form-item>
|
</el-form>
|
</div>
|
</template>
|
<script>
|
import { currency, rmoney } from "../../utils/currency";
|
import FileUpload from "./FileUpload.vue";
|
export default {
|
components: {
|
FileUpload
|
},
|
props: {
|
/**
|
* formItems 表单数组(type: input, select, multipleSelect, date, rangeDate)
|
* @example
|
* [ { "type": "input", "label": "申请编号:", "value": "", "name": "serialNo" }]
|
*/
|
formItems: {
|
type: [Object, Array],
|
default: () => {
|
return [];
|
}
|
},
|
oldVal: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
isShowOld: {
|
type: Boolean,
|
default: false
|
},
|
isShowBorder: {
|
type: Boolean,
|
default: true
|
},
|
edit: {
|
type: Boolean,
|
default: false
|
},
|
isView: {
|
type: Boolean,
|
default: false
|
},
|
isReset: {
|
type: Boolean,
|
default: false
|
},
|
defValues: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
formRules: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
screenWidth: {
|
type: Number,
|
default: () => {
|
return document.body.offsetWidth;
|
}
|
}
|
},
|
watch: {
|
formItems: {
|
handler(val, oldVal) {
|
this.formItems = val;
|
},
|
deep: true
|
},
|
defValues: {
|
handler(val, oldVal) {
|
const newValue = val;
|
const newFormItems = this.formItems.filter(
|
form => form && form.type === "currency"
|
);
|
const formatterItems = newFormItems.map(({ name }) => name);
|
if (formatterItems.length > 0 && this.formatOnce) {
|
formatterItems.forEach(name => {
|
const filedsVal = rmoney(newValue[name]);
|
if (filedsVal) {
|
newValue[name] = currency(filedsVal);
|
}
|
});
|
this.formatOnce = false;
|
}
|
this.formValues = this.defValues = newValue;
|
},
|
deep: true
|
},
|
oldVal: {
|
handler(val, oldVal) {
|
this.oldVal = val;
|
},
|
deep: true
|
},
|
formRules: {
|
handler(val, oldVal) {
|
this.formRules = val;
|
},
|
deep: true
|
},
|
isReset: {
|
handler(val, oldVal) {
|
this.isReset = val;
|
},
|
deep: true
|
}
|
},
|
data() {
|
return {
|
formValues: this.defValues,
|
visible: false,
|
formatOnce: true,
|
selValue: [],
|
transferVal: []
|
};
|
},
|
mounted() {
|
const ref = this.$refs["createForm"];
|
this.isReset && ref.resetFields();
|
},
|
methods: {
|
// 格式化金额处理默认值
|
formatCurr(defValues) {
|
const forms = [...this.formItems];
|
const newDefValue = {};
|
Object.getOwnPropertyNames(defValues).forEach(key => {
|
const isCurrKey = forms.some(
|
form => form.name === key && form.type === "currency"
|
);
|
newDefValue[key] = isCurrKey
|
? defValues[key]
|
? currency(defValues[key])
|
: " "
|
: defValues[key];
|
});
|
return newDefValue;
|
},
|
// input值变化时候触发
|
handleInputChange(name, value) {
|
this.$emit("handleInputChange", name, value);
|
},
|
// 金额类型input失去焦点处理事件
|
handleInputBlur(name) {
|
const inputVal = rmoney(this.formValues[name]);
|
const patten = /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g;
|
if (!patten.test(inputVal)) {
|
this.$message.warning("请输入正确的金额!");
|
this.formValues[name] = "";
|
return;
|
}
|
this.formValues[name] = currency(inputVal);
|
},
|
defRightChecked(options, value) {
|
const checkeds = value && value.split(";");
|
return options.map(op => {
|
if (checkeds.includes(op.label)) {
|
return op.value;
|
}
|
});
|
},
|
remoteMethod(query, name) {
|
this.$emit("remoteMethod", query, name);
|
},
|
renderFunc(h, option) {
|
return <span>{option && option.label}</span>;
|
},
|
update() {
|
this.$forceUpdate();
|
},
|
rightCheckChange(selected) {
|
const { transferVal } = this;
|
this.selValue = transferVal.filter(
|
item => item && selected.includes(item)
|
);
|
},
|
handleChange() {
|
// const { transferVal } = this
|
},
|
handleClearItem() {
|
this.transferVal = [];
|
},
|
handlePreference() {
|
const { transferVal, selValue } = this;
|
const transFerVal = transferVal.filter(item => item);
|
if (!selValue || selValue.length < 0) {
|
this.$message.warning("请至少选择需要优先的一项");
|
return false;
|
}
|
const reselIndex = transFerVal.findIndex(item => {
|
return item === selValue[0];
|
});
|
if (reselIndex === -1) {
|
this.$message.warning("请选择需要优先的一项");
|
return false;
|
}
|
if (selValue[0] === transFerVal[0]) {
|
this.$message.warning("已经最优先了");
|
return false;
|
}
|
const newTransferVal = transFerVal.filter(val => !selValue.includes(val));
|
newTransferVal.splice(reselIndex - 1, 0, ...selValue); // 在索引为reselIndex-1的位置插入
|
this.$set(this, "transferVal", newTransferVal);
|
},
|
handleNext() {
|
const { transferVal, selValue } = this;
|
const transFerVal = transferVal.filter(item => item);
|
if (!selValue || selValue.length < 0) {
|
this.$message.warning("请至少选择需要推后的一项");
|
return false;
|
}
|
const reselIndex = transFerVal.findIndex(item => {
|
return item === selValue[selValue.length - 1];
|
});
|
if (reselIndex === -1) {
|
this.$message.warning("请至少选择需要推后的一项");
|
return false;
|
}
|
if (
|
selValue[selValue.length - 1] === transFerVal[transferVal.length - 1]
|
) {
|
this.$message.warning("已经推到最后面了");
|
return false;
|
}
|
const newTransferVal = transFerVal.filter(val => !selValue.includes(val));
|
newTransferVal.splice(reselIndex + (2 - selValue.length), 0, ...selValue);
|
this.$set(this, "transferVal", newTransferVal);
|
},
|
beforeAvatarUpload(file, key) {
|
this.$emit("beforeFormAvatarUpload", file, key);
|
},
|
handleUpload(file, key) {
|
this.$emit("handleFormUpload", file, key);
|
},
|
handleDelete(attachmentno) {
|
this.$emit("handleFormDelete", attachmentno);
|
},
|
handleSub(options, name) {
|
const { transferVal } = this;
|
const transFerVal = transferVal.filter(item => item);
|
this.visible = false;
|
const val = [];
|
transFerVal.forEach(item => {
|
const selOptions = options.filter(sel => sel.value === item);
|
val.push(selOptions[0].label);
|
});
|
this.formValues[name] = val.toString().replace(/,/g, ";");
|
this.$emit("handleElmentChange", transFerVal);
|
}
|
}
|
};
|
</script>
|
<style lang="less">
|
.form_main {
|
width: 100%;
|
margin-bottom: -18px;
|
}
|
/* .form_main .el-select >>> .el-select__caret::before {
|
content: "\E6E1";
|
} */
|
.for_col_width {
|
width: calc(100% / 2 - 60px);
|
margin-right: 60px !important;
|
& .el-form-item__content {
|
width: calc(100% - 160px);
|
min-width: 200px;
|
& .el-select {
|
width: 100%;
|
}
|
}
|
.el-form-item__label {
|
color: #888;
|
line-height: 16px;
|
}
|
}
|
|
.for_two_col_width {
|
width: calc(100% / 3 - 60px);
|
margin-right: 60px !important;
|
& .el-form-item__content {
|
width: calc(100% - 160px);
|
min-width: 140px;
|
& .el-select {
|
width: 100%;
|
& .el-select__caret::before {
|
content: "\E6E1";
|
}
|
}
|
}
|
.el-form-item__label {
|
color: #888;
|
line-height: 16px;
|
}
|
}
|
.for_col_collapse {
|
width: calc(100% - 60px);
|
|
& .el-form-item__content {
|
width: calc(100% - 160px);
|
min-width: 140px;
|
}
|
& .el-form-item__label {
|
color: #888;
|
line-height: 16px;
|
}
|
& .images {
|
margin-bottom: 0px !important;
|
}
|
& .el-card__body {
|
padding: 0px !important;
|
}
|
& .imagesList {
|
min-height: 20px !important;
|
background-color: transparent !important;
|
padding: 0px !important;
|
margin-top: 10px;
|
}
|
& .imagesList > div {
|
margin-top: 0px !important;
|
}
|
}
|
.starShow {
|
& .el-form-item__label:before {
|
content: "*";
|
color: #f56c6c;
|
margin-right: 4px;
|
}
|
}
|
.divider_style {
|
width: calc(100% + 160px);
|
}
|
.non_boder {
|
& .el-form-item__content {
|
color: #000;
|
font-size: 14px;
|
}
|
& .el-form-item__label {
|
line-height: 18px !important;
|
}
|
.el-form-item__label:before {
|
content: "" !important;
|
color: #fff !important;
|
margin-right: 4px !important;
|
}
|
& input,
|
textarea {
|
border: none;
|
padding: 0px;
|
background: none;
|
background-color: transparent !important;
|
display: inline-table !important;
|
color: #000 !important;
|
cursor: text !important;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
|
"Microsoft YaHei", SimSun, sans-serif;
|
}
|
.el-form-item__label {
|
padding: 6px;
|
}
|
.el-input__suffix {
|
display: none;
|
}
|
.el-input__prefix {
|
display: none;
|
}
|
.el-input--prefix .el-input__inner {
|
// padding-left: 15px;
|
padding-left: 0px;
|
}
|
.el-tag--info {
|
color: #000 !important;
|
background: none;
|
border: none;
|
}
|
}
|
|
.for_two_col_collapse {
|
width: calc(100% * 2 / 3 - 60px);
|
|
.el-form-item__content {
|
width: calc(100% - 160px);
|
min-width: 140px;
|
}
|
.el-card__body {
|
padding: 0px !important;
|
}
|
.images {
|
margin-bottom: 0px !important;
|
}
|
.imagesList {
|
min-height: 20px !important;
|
background-color: transparent !important;
|
padding: 0px !important;
|
margin-top: 10px;
|
}
|
.imagesList > div {
|
margin-top: 0px !important;
|
}
|
}
|
.for_three_col_collapse {
|
width: calc(100% - 60px);
|
.el-form-item__content {
|
width: calc(100% - 160px);
|
min-width: 140px;
|
}
|
.el-card__body {
|
padding: 0px !important;
|
}
|
.images {
|
margin-bottom: 0px !important;
|
}
|
.imagesList {
|
min-height: 20px !important;
|
background-color: transparent !important;
|
padding: 0px !important;
|
margin-top: 10px;
|
}
|
.imagesList > div {
|
margin-top: 0px !important;
|
}
|
}
|
</style>
|