/*
|
* @Author: Pengjiantian
|
* @Date: 2020-07-09 14:28:53
|
* @Last Modified by: Pengjiantian
|
* @Last Modified time: 2020-07-09 14:42:07
|
*/
|
import dayjs from 'dayjs'
|
import CommFetch from '@/utils/core/commFetch'
|
|
/**
|
* ApiModel 接口映射模型
|
*/
|
|
export default class ApiModel {
|
/**
|
* constructor 初始化
|
* @param {Object} options 配置项 @example
|
* {
|
* api: '接口地址', // required
|
* formList: [ // 表单映射信息(通常用来渲染表单)
|
* {
|
* type: 'input',label: '客户名称:',value: '',name: 'customerName'
|
* }
|
* ],
|
* responseMap: [ // 接口响应映射信息(通常用来表格或类似表单展示的数据)
|
* {
|
* label: '车位首付(元)',field: 'downpayparkingamount',isMoney: true,isDesc: true
|
* }
|
* ],
|
* computedResponse: item => {
|
* return {...item}
|
* },
|
* computedItem: item => {
|
* return {...item}
|
* },
|
*
|
*/
|
|
constructor(options = {}) {
|
const { baseConf, fetchConf = {}, ...other } = options
|
// 默认日期格式
|
this.dateFormate = 'YYYY/MM/DD'
|
|
this.ruleAction = (rule, message) => {
|
if (typeof rule === 'string') {
|
if (rule === 'required') {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (value.toString().trim() === '') {
|
callback(new Error(message || '该字段必填'))
|
} else {
|
callback()
|
}
|
callback()
|
}
|
}
|
if (rule === 'phone') {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (!/1\d{10}/.test(value)) {
|
callback(new Error('手机号格式有误'))
|
} else {
|
callback()
|
}
|
}
|
}
|
if (rule === 'number') {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (isNaN(value)) {
|
callback(new Error('必须输入数字'))
|
} else {
|
callback()
|
}
|
}
|
}
|
// 身份证录入校验
|
if (rule === 'idCart') {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
const RegExp = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/
|
if (!RegExp.test(value)) {
|
callback(new Error('身份证输入有误'))
|
} else {
|
callback()
|
}
|
}
|
}
|
}
|
|
if (typeof rule === 'object') {
|
let { required, pattern, maxLength, minLength } = rule
|
if (required) {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (value === '') {
|
callback(new Error('该字段必填'))
|
} else {
|
callback()
|
}
|
}
|
}
|
|
if (maxLength) {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (value.length > maxLength) {
|
callback(new Error(`最多输入${maxLength}个字符`))
|
} else {
|
callback()
|
}
|
}
|
}
|
|
if (minLength) {
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (value.length < minLength) {
|
callback(new Error(`最少输入${minLength}个字符`))
|
} else {
|
callback()
|
}
|
}
|
}
|
|
if (pattern) {
|
if (pattern === 'string') {
|
pattern = new RegExp(pattern)
|
}
|
|
return (rule, value, callback) => {
|
value = this.getItemValue(value)
|
if (!pattern.test(value)) {
|
callback(new Error('输入格式有误'))
|
} else {
|
callback()
|
}
|
}
|
}
|
}
|
return false
|
}
|
|
this.commFetch = new CommFetch(baseConf, fetchConf)
|
this.setOptions(other)
|
}
|
|
getItemValue(value) {
|
if (Array.isArray(value)) {
|
return value.join('')
|
}
|
return (value || '').trim()
|
}
|
|
/**
|
* 获取表单信息
|
* @param {Object} initValues 初始值对象
|
*/
|
getFormList(initValues = {}, list) {
|
const { formList } = this
|
if (typeof list === 'undefined') {
|
list = [...formList]
|
}
|
const keys = Object.keys(initValues)
|
if (keys.length > 0) {
|
return list.reduce((pre, curr) => {
|
let { value, name, descName, descValue, children } = curr
|
if (typeof value === 'undefined' && Array.isArray(children)) {
|
// has children
|
pre.push({
|
...curr,
|
children: this.getFormList(initValues, children)
|
})
|
} else {
|
let result = { ...curr }
|
result.value =
|
typeof initValues[name] === 'undefined' ? value : initValues[name]
|
if (typeof descValue === 'undefined' && descName) {
|
const dValue = initValues[descName]
|
result.descValue = typeof dValue === 'undefined' ? '' : dValue
|
}
|
pre.push(result)
|
}
|
return pre
|
}, [])
|
}
|
return [...list]
|
}
|
|
// 获取表单数据值
|
getFormValues(list) {
|
const { formList } = this
|
if (typeof list === 'undefined') {
|
list = [...formList]
|
}
|
return list.reduce((pre, curr) => {
|
const { name, names, value, children } = curr
|
// 父级不包含value,则取子级
|
if (typeof value === 'undefined' && Array.isArray(children)) {
|
children.forEach(subItem => {
|
const { name: subName, value: subValue } = subItem
|
pre[subName] = this.formatInput(subValue, subName, list)
|
})
|
} else if (Array.isArray(names) && Array.isArray(value)) {
|
// 将数组值传送到names字段对应的key中
|
names.forEach((subName, index) => {
|
pre[subName] = this.formatInput(value[index] || '', subName, list)
|
})
|
pre[name] = this.formatInput(value, name, list)
|
} else {
|
pre[name] = this.formatInput(value, name, list)
|
}
|
return pre
|
}, {})
|
}
|
|
// 获取表单验证规则
|
getFormRules(list) {
|
const { formList } = this
|
if (typeof list === 'undefined') {
|
list = [...formList]
|
}
|
return list.reduce((pre, curr) => {
|
const { rules = [], name, children, attrs = [] } = curr
|
if (Array.isArray(children)) {
|
pre = {
|
...pre,
|
...this.getFormRules(children)
|
}
|
} else {
|
const ruleArray = rules.reduce((rulePre, ruleCurr) => {
|
if (this.getRule(ruleCurr)) {
|
rulePre.push(this.getRule(ruleCurr))
|
}
|
return rulePre
|
}, [])
|
if (ruleArray.length > 0) {
|
const requiredRule = ruleArray.find(({ required }) => required)
|
if (
|
requiredRule &&
|
!ruleArray.some(({ trigger }) => trigger === 'change') &&
|
!attrs.some(attr => attr === 'multiple')
|
) {
|
// change 多选初始会显示错误信息,临时不加change
|
ruleArray.push({ ...requiredRule, trigger: 'change' })
|
}
|
pre[name] = ruleArray
|
}
|
}
|
return pre
|
}, {})
|
}
|
|
getRule(rule) {
|
if (typeof rule === 'string') {
|
// rule: required phone number
|
const temp = rule === 'required' ? { required: true } : {}
|
return {
|
validator: this.ruleAction(rule),
|
...temp,
|
trigger: 'blur'
|
}
|
}
|
if (typeof rule === 'object') {
|
const { validator, trigger = 'blur', message } = rule
|
if (typeof validator === 'function') {
|
return {
|
trigger,
|
...rule
|
}
|
} else {
|
return {
|
trigger,
|
...rule,
|
validator: this.ruleAction(rule, message)
|
}
|
}
|
}
|
return false
|
}
|
|
// 统一输出数据格式,如日期格式化
|
formatInput(val, name, list) {
|
const { dateFormate } = this
|
if (typeof this.computedValue === 'function') {
|
val = this.computedValue(val, name, list)
|
}
|
if (Array.isArray(val) && val.length > 0) {
|
return val.reduce((pre, curr) => {
|
pre.push(this.formatInput(curr, name, list))
|
return pre
|
}, [])
|
}
|
if (val instanceof Date) {
|
val = dayjs(val).format(dateFormate)
|
}
|
return val
|
}
|
|
/**
|
* 获取表格信息
|
*/
|
getTableList() {
|
const { tableList } = this
|
return [...tableList]
|
}
|
|
/**
|
* post 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} body 请求参数
|
*/
|
post(body = {}, conf = {}) {
|
return this.toRequest(body, {
|
method: 'post',
|
...conf
|
})
|
}
|
|
/**
|
* post 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} body 请求参数
|
*/
|
upload(body = {}, conf = { headers: false }) {
|
const formData = this.getFormData(body)
|
return this.toRequest(formData, {
|
method: 'post',
|
...conf
|
})
|
}
|
|
/**
|
* post 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} body 请求参数
|
*/
|
submit(body = {}, conf = {}, method='post') {
|
const { api } = this
|
const tempForm = document.createElement('form')
|
tempForm.method = method
|
tempForm.target = '_blank'
|
tempForm.action = this.commFetch.mixApi(api)
|
|
document.body.appendChild(tempForm)
|
|
Object.keys(body).forEach(key => {
|
const tempInput = document.createElement('input')
|
tempInput.type = 'hidden'
|
tempInput.name = key
|
tempInput.value = body[key]
|
tempForm.appendChild(tempInput)
|
})
|
tempForm.submit()
|
document.body.removeChild(tempForm)
|
}
|
|
getFormData(body) {
|
let formData = null
|
if (typeof body === 'object' && !(body instanceof FormData)) {
|
formData = new FormData()
|
Object.keys(body).forEach(key => {
|
formData.append(key, body[key])
|
})
|
}
|
return formData === null ? body : formData
|
}
|
|
/**
|
* get 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} body 请求参数
|
*/
|
get(body = {}, conf = {}) {
|
return this.toRequest(body, {
|
method: 'get',
|
...conf
|
})
|
}
|
|
// 遍历options内容到实例
|
setOptions(options) {
|
Object.keys(options).forEach(key => {
|
this[key] = options[key]
|
})
|
}
|
|
// 请求统一处理
|
toRequest(body = {}, conf = {}) {
|
const { api } = this
|
return new Promise((resolve, reject) => {
|
this.commFetch
|
.fetch(api, body, conf)
|
.then(res => {
|
resolve(this.formateResponse(res, body))
|
})
|
.catch(reson => {
|
reject(reson)
|
})
|
})
|
}
|
|
// 输出数据统一处理(这里为将列表项转换为list字段值)
|
formateResponse(res, body) {
|
let { result, code, ext, msg, ...other } = res
|
// let list = {}
|
if (Array.isArray(result)) {
|
result = {
|
list: this.computedList(result)
|
}
|
} else {
|
const { records, ...other } = result
|
if (Array.isArray(records)) {
|
result = {
|
list: this.computedList(records),
|
...other
|
}
|
}
|
}
|
const temp = {
|
...other,
|
...result
|
}
|
if (typeof this.computedResponse === 'function') {
|
// 响应数据的进一步处理
|
return this.computedResponse(temp)
|
}
|
|
if ('original' in body) {
|
return res
|
}
|
return temp
|
}
|
|
// 列表数据处理
|
computedList(list = []) {
|
const { computedItem } = this
|
if (typeof computedItem === 'function') {
|
return list.reduce((pre, curr) => {
|
pre.push(this.computedItem(curr))
|
return pre
|
}, [])
|
}
|
return [...list]
|
}
|
}
|