|
- <template>
- <view>
- <view
- :key="item.id"
- v-for="(item, index) of scheme"
- :style="{ marginTop: index !== 0 && item.type === 'label' ? '15px' : '0' }"
- >
- <!-- 标题文字 label -->
- <l-title v-if="item.type === 'label'" border>{{ item.title }}</l-title>
-
- <!-- 文字输入框 text -->
- <l-input
- v-else-if="item.type === 'text'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :disabled="!isEdit(item)"
- :required="Boolean(item.verify)"
- :title="item.title"
- />
-
- <!-- 单选和选择 radio和select -->
- <l-select
- v-else-if="item.type === 'radio' || item.type === 'select'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :disabled="!isEdit(item)"
- :required="Boolean(item.verify)"
- :range="item.__sourceData__"
- :title="item.title"
- />
-
- <!-- 多选 checkbox -->
- <l-checkbox-picker
- v-else-if="item.type === 'checkbox'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :readonly="!isEdit(item)"
- :required="Boolean(item.verify)"
- :range="item.__sourceData__"
- :title="item.title"
- />
-
- <!-- 多行文本 textarea -->
- <l-textarea
- v-else-if="item.type === 'textarea' || item.type === 'texteditor'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :readonly="!isEdit(item)"
- :required="Boolean(item.verify)"
- :title="item.title"
- />
-
- <!-- 时间日期 datetime -->
- <l-datetime-picker
- v-else-if="item.type === 'datetime' && Number(item.dateformat) === 1"
- @input="setValue(item.__valuePath__, $event)"
- @change="relChange(item.id, $event)"
- :value="getValue(item.__valuePath__)"
- :disabled="!isEdit(item)"
- :required="Boolean(item.verify)"
- :title="item.title"
- />
-
- <!-- 日期 date -->
- <l-date-picker
- v-else-if="item.type === 'datetime' && Number(item.dateformat) !== 1"
- @input="setValue(item.__valuePath__, $event)"
- @change="relChange(item.id, $event)"
- :value="getValue(item.__valuePath__)"
- :required="Boolean(item.verify)"
- :disabled="!isEdit(item)"
- :title="item.title"
- />
-
- <!-- 日期区间 datetimerange -->
- <l-input
- v-else-if="item.type === 'datetimerange'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :disabled="!isEdit(item)"
- :required="Boolean(item.verify)"
- :title="item.title"
- placeholder=""
- />
-
- <!-- 当前状态 currentInfo:组织结构 organize -->
- <l-organize-picker
- v-else-if="item.type === 'currentInfo' && item.dataType !== 'time'"
- :value="getValue(item.__valuePath__)"
- :type="item.dataType"
- :required="Boolean(item.verify)"
- :title="item.title"
- readonly
- />
-
- <!-- 当前状态 currentInfo:时间 time -->
- <l-input
- v-else-if="item.type === 'currentInfo' && item.dataType === 'time'"
- :value="getValue(item.__valuePath__)"
- :disabled="!isEdit(item)"
- :required="Boolean(item.verify)"
- :title="item.title"
- disabled
- />
-
- <!-- 编码 encode -->
- <l-input
- v-else-if="item.type === 'encode'"
- :value="getValue(item.__valuePath__)"
- :required="Boolean(item.verify)"
- :title="item.title"
- disabled
- />
-
- <!-- 公司人员结构选单 organize -->
- <l-organize-picker
- v-else-if="item.type === 'organize'"
- @input="setValue(item.__valuePath__, $event)"
- @change="relChange(item.id, $event)"
- :value="getValue(item.__valuePath__)"
- :rootId="getValue(item.__relationPath__)"
- :type="item.dataType"
- :required="Boolean(item.verify)"
- :readonly="item.__relationPath__ ? !isEdit(item) || !getValue(item.__relationPath__) : !isEdit(item)"
- :title="item.title"
- :placeholder="displayPlaceHolder(item)"
- />
-
- <!-- 文件上传 upload -->
- <l-upload-file
- v-else-if="item.type === 'upload'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :required="Boolean(item.verify)"
- :readonly="!isEdit(item)"
- :title="item.title"
- :number="9"
- />
-
- <!-- HTML内容 html -->
- <view v-else-if="item.type === 'html'" class="cu-form-group">
- <view class="bg-white">
- <u-parse :imageProp="{ domain: apiRoot }" :content="CONVERT_HTML(item.title)"></u-parse>
- </view>
- </view>
-
- <!-- 表格 girdtable -->
- <l-customform-table
- v-else-if="item.type === 'girdtable'"
- @input="setValue(item.__valuePath__, $event)"
- :value="getValue(item.__valuePath__)"
- :item="item"
- :edit="isEdit(item)"
- />
- </view>
- </view>
- </template>
-
- <script>
- import get from 'lodash/get'
- import set from 'lodash/set'
- import moment from 'moment'
-
- export default {
- name: 'l-customform',
-
- props: {
- scheme: { default: () => [] },
- editMode: { default: true },
- initFormValue: { default: () => ({}) },
- rel: { default: () => ({}) }
- },
-
- data() {
- return {
- formValue: this.initFormValue
- }
- },
-
- methods: {
- // 本方法由调用方使用 $refs 的方式调用
- // 给表单设置值
- setFormValue(formValue) {
- this.formValue = formValue
- },
-
- // 本方法由调用方使用 $refs 的方式调用
- // 获取表单值
- getFormValue() {
- return this.formValue
- },
-
- // 本方法由调用方使用 $refs 的方式调用
- // 依次验证表单项,返回一个所有错误提示的数组,如果为空数组则表示无错误
- verifyValue() {
- const errorList = []
- console.log(this.scheme)
- this.scheme
- .filter(t => t.verify)
- .forEach(schemeItem => {
- if (schemeItem.table && schemeItem.field) {
- console.log(schemeItem.verify,'hemeItem.verify')
- const verifyFunc = this.verify[schemeItem.verify]
- console.log(schemeItem.verify)
- const verifyResult = verifyFunc(this.getValue(schemeItem.__valuePath__))
- if (verifyResult !== true) {
- errorList.push(`[${schemeItem.title}]: ${verifyResult}`)
- }
- } else if (schemeItem.fieldsData) {
- this.getValue(schemeItem.__valuePath__).forEach((valueItem, valueIndex) => {
- schemeItem.fieldsData.forEach(fieldItem => {
- const verifyFunc = this.verify[fieldItem.verify]
- const verifyResult = verifyFunc(
- this.getValue(`${schemeItem.__valuePath__}.${valueIndex}.${fieldItem.field}`)
- )
- if (verifyResult !== true) {
- errorList.push(`[表格${schemeItem.title}第${tableIndex}行${fieldItem.name}列]: ${verifyResult}`)
- }
- })
- })
- }
- })
-
- return errorList
- },
-
- // 设置表单数据的方法
- setValue(path, value) {
- set(this.formValue, path, value)
- },
-
- // 获取表单数据的方法
- getValue(path) {
- return get(this.formValue, path)
- },
-
- // 处理互相关联的表单项(organize 级联,datetimerange 日期区间)
- relChange(id, val) {
- const relList = this.rel[id] || []
- relList.forEach(relItem => {
- if (relItem.type === 'organize') {
- // 组织结构,重设级联过来的组件
- this.setValue(relItem.path, '')
-
- // 向下递归
- if (this.rel[relItem.id]) {
- this.relChange(relItem.id)
- }
- } else if (relItem.type === 'datetimerange') {
- // 时间日期区间,重新计算
- const startTime = this.getValue(relItem.startPath)
- const endTime = this.getValue(relItem.endPath)
-
- if (!startTime || !endTime || moment(endTime).isBefore(startTime)) {
- return
- }
-
- const newVal = moment
- .duration(moment(endTime).diff(moment(startTime)))
- .asDays()
- .toFixed(0)
-
- this.setValue(relItem.path, newVal)
- }
- })
- },
-
- // 获取表单项的 placeholder ,在无法编辑时隐藏
- displayPlaceHolder(item) {
- if (!this.editMode || item.type !== 'organize') {
- return ' '
- }
-
- if (!item.relation) {
- return `请选择${item.title || item.name}`
- }
-
- const parentType = { user: '部门', department: '公司' }[item.dataType]
- const parentValue = this.getValue(item.__relationPath__)
- return parentValue ? `请选择${item.title || item.name}` : `请先选择上级${parentType}`
- },
-
- // 获取表单项可否编辑
- isEdit(item) {
- return this.editMode && item.edit !== 0
- }
- },
-
- computed: {
- verify() {
- return {
- NotNull: t => (t !== null && t !== undefined && t !== '' && (!Array.isArray(t) || t.length > 0)) || '不能为空',
- Num: t => !isNaN(t) || '须输入数值',
- NumOrNull: t => t.length <= 0 || !isNaN(t) || '须留空或输入数值',
- Email: t => /^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_]+.[a-zA-Z0-9]+$/.test(t) || '须符合Email格式',
- EmailOrNull: t =>
- t.length <= 0 || /^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_]+.[a-zA-Z0-9]+$/.test(t) || '须留空或符合Email格式',
- EnglishStr: t => /^[a-zA-Z]*$/.test(t) || '须由英文字母组成',
- EnglishStrOrNull: t => t.length <= 0 || /^[a-zA-Z]*$/.test(t) || '须留空或由英文字母组成',
- Phone: t => /^[+0-9- ]*$/.test(t) || '须符合电话号码格式',
- PhoneOrNull: t => t.length <= 0 || /^[+0-9- ]*$/.test(t) || '须留空或符合电话号码格式',
- Fax: t => /^[+0-9- ]*$/.test(t) || '须符合传真号码格式',
- Mobile: t => /^1[0-9]{10}$/.test(t) || '须符合手机号码格式',
- MobileOrPhone: t => /^[+0-9- ]*$/.test(t) || /^1[0-9]{10}$/.test(t) || '须符合电话或手机号码格式',
- MobileOrNull: t => t.length <= 0 || /^1[0-9]{10}$/.test(t) || '须留空或符合手机号码格式',
- MobileOrPhoneOrNull: t =>
- t.length <= 0 || /^1[0-9]{10}$/.test(t) || /^[+0-9- ]*$/.test(t) || '须留空或符合手机/电话号码格式',
- Uri: t => /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须符合网址Url格式',
- UriOrNull: t => t.length <= 0 || /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须留空或符合网址Url格式',
- PositiveFloatint:t=> /^([1-9]\d*|(0|[1-9]\d*)\.\d*[1-9])$/.test(t) || '请输入正确的整数或小数(不能为零和负数)'
- }
- }
- }
- }
- </script>
|