2.1.3 大屏版本发布

This commit is contained in:
zhangdaihao
2019-12-25 13:25:10 +08:00
parent ea5ef384f2
commit 9c44ffaa8e
60 changed files with 2970 additions and 806 deletions

View File

@ -76,7 +76,7 @@
<div v-if="rows.length===0" class="tr-nodata">
<span>暂无数据</span>
</div>
<!-- v-model="rows"-->
<!-- v-model="rows"-->
<draggable :value="rows" handle=".td-ds-icons" @end="handleDragMoveEnd">
<!-- 动态生成tr -->
@ -96,10 +96,19 @@
<!-- 左侧固定td -->
<div v-if="dragSort" class="td td-ds" :style="style.tdLeftDs">
<div class="td-ds-icons">
<a-icon type="align-left"/>
<a-icon type="align-right"/>
</div>
<a-dropdown :trigger="['click']" :getPopupContainer="getParentContainer">
<div class="td-ds-icons">
<a-icon type="align-left"/>
<a-icon type="align-right"/>
</div>
<a-menu slot="overlay">
<a-menu-item key="0" :disabled="rowIndex===0" @click="_handleRowMoveUp(rowIndex)">向上移</a-menu-item>
<a-menu-item key="1" :disabled="rowIndex===(rows.length-1)" @click="_handleRowMoveDown(rowIndex)">向下移</a-menu-item>
<a-menu-divider/>
<a-menu-item key="3" @click="_handleRowInsertDown(rowIndex)">插入一行</a-menu-item>
</a-menu>
</a-dropdown>
</div>
<div v-if="rowSelection" class="td td-cb" :style="style.tdLeft">
@ -245,14 +254,24 @@
</a-tooltip>
</template>
<template slot="addonAfter" style="width: 30px">
<a-tooltip title="删除并重新上传">
<a-icon
v-if="file.status!=='uploading'"
type="close-circle"
style="cursor: pointer;"
@click="()=>handleClickDelFile(id)"/>
</a-tooltip>
<template v-if="col.allowDownload!==false || col.allowRemove!==false" slot="addonAfter" style="width: 30px">
<a-dropdown :trigger="['click']" placement="bottomRight" :getPopupContainer="getParentContainer">
<a-tooltip title="操作" :getPopupContainer="getParentContainer">
<a-icon
v-if="file.status!=='uploading'"
type="setting"
style="cursor: pointer;"/>
</a-tooltip>
<a-menu slot="overlay">
<a-menu-item v-if="col.allowDownload!==false" @click="handleClickDownloadFile(id)">
<span><a-icon type="download"/>&nbsp;下载</span>
</a-menu-item>
<a-menu-item v-if="col.allowRemove!==false" @click="handleClickDelFile(id)">
<span><a-icon type="delete"/>&nbsp;删除</span>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
</a-input>
@ -501,17 +520,33 @@
<div v-else-if="col.type === formTypes.slot" :key="i">
<slot
:name="(col.slot || col.slotName) || col.key"
:index="rowIndex"
:text="inputValues[rowIndex][col.key]"
:column="col"
:rowId="removeCaseId(row.id)"
:getValue="()=>_getValueForSlot(row.id)"
:caseId="caseId"
:allValues="_getAllValuesForSlot()"
:target="getVM()"
/>
<a-tooltip
:key="i"
:id="id"
placement="top"
:title="(tooltips[id] || {}).title"
:visible="(tooltips[id] || {}).visible || false"
:autoAdjustOverflow="true">
<span
@mouseover="()=>{handleMouseoverCommono(row,col)}"
@mouseout="()=>{handleMouseoutCommono(row,col)}">
<slot
:name="(col.slot || col.slotName) || col.key"
:index="rowIndex"
:text="slotValues[id]"
:value="slotValues[id]"
:column="col"
:rowId="removeCaseId(row.id)"
:getValue="()=>_getValueForSlot(row.id)"
:caseId="caseId"
:allValues="_getAllValuesForSlot()"
:target="getVM()"
:handleChange="(v)=>handleChangeSlotCommon(v,id,row,col)"
:isNotPass="notPassedIds.includes(col.key+row.id)"
/>
</span>
</a-tooltip>
</div>
<!-- else (normal) -->
@ -636,15 +671,17 @@
checkboxValues: {},
// 绑定 jdate 的值
jdateValues: {},
// 绑定插槽数据
slotValues: {},
// file 信息
uploadValues: {},
//popup信息
popupValues:{},
popupValues: {},
radioValues:{},
metaCheckboxValues:{},
multiSelectValues:{},
searchSelectValues:{},
radioValues: {},
metaCheckboxValues: {},
multiSelectValues: {},
searchSelectValues: {},
// 绑定左侧选择框已选择的id
selectedRowIds: [],
// 存储被删除行的id
@ -717,9 +754,9 @@
},
// 侦听器
watch: {
rows:{
immediate:true,
handler(val,old) {
rows: {
immediate: true,
handler(val, old) {
// val.forEach(item => {
// for (let inputValue of this.inputValues) {
// if (inputValue.id === item.id) {
@ -740,8 +777,9 @@
let checkboxValues = {}
let selectValues = {}
let jdateValues = {}
let slotValues = {}
let uploadValues = {}
let popupValues={}
let popupValues = {}
let radioValues = {}
let multiSelectValues = {}
let searchSelectValues = {}
@ -783,9 +821,9 @@
} else if (column.type === FormTypes.slot) {
if (sourceValue !== 0 && !sourceValue) {
value[column.key] = column.defaultValue
slotValues[inputId] = column.defaultValue
} else {
value[column.key] = sourceValue
slotValues[inputId] = sourceValue
}
} else if (column.type === FormTypes.popup) {
@ -795,18 +833,18 @@
} else if (column.type === FormTypes.sel_search) {
searchSelectValues[inputId] = sourceValue
} else if (column.type === FormTypes.list_multi) {
if(sourceValue.length>0){
multiSelectValues[inputId] = sourceValue.split(",")
}else{
if (sourceValue.length > 0) {
multiSelectValues[inputId] = sourceValue.split(',')
} else {
multiSelectValues[inputId] = []
}
} else if (column.type === FormTypes.file || column.type === FormTypes.image) {
if(sourceValue){
let fileName = sourceValue.substring(sourceValue.lastIndexOf("/")+1)
} else if (column.type === FormTypes.upload || column.type === FormTypes.file || column.type === FormTypes.image) {
if (sourceValue) {
let fileName = sourceValue.substring(sourceValue.lastIndexOf('/') + 1)
uploadValues[inputId] = {
name: fileName,
status: 'done',
path:sourceValue
path: sourceValue
}
}
} else {
@ -839,6 +877,7 @@
this.checkboxValues = checkboxValues
this.selectValues = selectValues
this.jdateValues = jdateValues
this.slotValues = slotValues
this.rows = rows
this.uploadValues = uploadValues
this.popupValues = popupValues
@ -935,12 +974,13 @@
this.selectValues = {}
this.checkboxValues = {}
this.jdateValues = {}
this.slotValues = {}
this.selectedRowIds = []
this.tooltips = {}
this.notPassedIds = []
this.uploadValues=[]
this.popupValues=[]
this.radioValues=[]
this.uploadValues = []
this.popupValues = []
this.radioValues = []
this.multiSelectValues = []
this.searchSelectValues = []
this.scrollTop = 0
@ -987,7 +1027,7 @@
return `${this.caseId}${timestamp}${rows.length}`
},
/** push 一条数据 */
push(record, update = true, rows) {
push(record, update = true, rows, insertIndex = null) {
if (!(rows instanceof Array)) {
rows = cloneObject(this.rows) || []
}
@ -1005,6 +1045,7 @@
let checkboxValues = Object.assign({}, this.checkboxValues)
let selectValues = Object.assign({}, this.selectValues)
let jdateValues = Object.assign({}, this.jdateValues)
let slotValues = Object.assign({}, this.slotValues)
this.columns.forEach(column => {
let key = column.key
let inputId = key + row.id
@ -1039,17 +1080,23 @@
jdateValues[inputId] = recordHasValue ? record[key] : column.defaultValue
} else if (column.type === FormTypes.slot) {
value[key] = recordHasValue ? record[key] : (column.defaultValue || '')
slotValues[inputId] = recordHasValue ? record[key] : (column.defaultValue || '')
} else {
value[key] = recordHasValue ? record[key] : ''
}
})
rows.push(row)
this.inputValues.push(value)
if (typeof insertIndex === 'number') {
rows.splice(insertIndex, 0, row)
this.inputValues.splice(insertIndex, 0, value)
} else {
rows.push(row)
this.inputValues.push(value)
}
this.checkboxValues = checkboxValues
this.selectValues = selectValues
this.jdateValues = jdateValues
this.slotValues = slotValues
if (this.dragSort) {
this.inputValues.forEach((item, index) => {
@ -1097,17 +1144,16 @@
}
this.rows = rows
let rowValue = this.getValuesSync({
validate: false,
rowIds: [this.removeCaseId(row.id)]
}).values[0]
this.$nextTick(() => {
this.updateFormValues()
})
// 触发add事件
this.$emit('added', {
row: rowValue,
row: (() => {
let r = Object.assign({}, row)
r.id = this.removeCaseId(r.id)
return r
})(),
target: this
})
// 设置滚动条位置
@ -1124,6 +1170,36 @@
tbody.scrollTop = tbody.scrollHeight
})
},
/**
* 在指定位置添加一行
* @param insertIndex 添加位置下标
* @param num 添加的行数默认1
*/
insert(insertIndex, num = 1) {
if (!insertIndex && num < 1) return
let rows = this.rows
let newRows = []
for (let i = 0; i < num; i++) {
let row = { id: this.generateId(rows) }
rows = this.push(row, false, rows, insertIndex)
newRows.push(row)
}
// 同步更改
this.rows = rows
this.$nextTick(() => {
this.updateFormValues()
})
// 触发 insert 事件
this.$emit('inserted', {
rows: newRows.map(row => {
let r = cloneObject(row)
r.id = this.removeCaseId(r.id)
return r
}),
num, insertIndex,
target: this
})
},
/** 删除被选中的行 */
removeSelectedRows() {
this.removeRows(this.selectedRowIds)
@ -1161,7 +1237,7 @@
}
})
this.rows = rows
this.$emit('deleted', this.getDeleteIds())
this.$emit('deleted', this.getDeleteIds(), this)
this.$nextTick(() => {
// 更新formValues
this.updateFormValues()
@ -1225,24 +1301,26 @@
} else if (column.type === FormTypes.image || column.type === FormTypes.file) {
let currUploadObj = cloneObject(this.uploadValues[inputId] || null)
if(currUploadObj){
if (currUploadObj) {
value[column.key] = currUploadObj['path'] || null
}
} else if (column.type === FormTypes.popup) {
if(!value[column.key]){
if (!value[column.key]) {
value[column.key] = this.popupValues[inputId] || null
}
} else if (column.type === FormTypes.radio) {
value[column.key] = this.radioValues[inputId]
}else if (column.type === FormTypes.sel_search) {
} else if (column.type === FormTypes.sel_search) {
value[column.key] = this.searchSelectValues[inputId]
}else if (column.type === FormTypes.list_multi) {
if(!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length==0){
} else if (column.type === FormTypes.list_multi) {
if (!this.multiSelectValues[inputId] || this.multiSelectValues[inputId].length == 0) {
value[column.key] = ''
}else{
value[column.key] = this.multiSelectValues[inputId].join(",")
} else {
value[column.key] = this.multiSelectValues[inputId].join(',')
}
} else if (column.type === FormTypes.slot) {
value[column.key] = this.slotValues[inputId]
}
@ -1326,6 +1404,7 @@
selectValues: this.selectValues,
checkboxValues: this.checkboxValues,
jdateValues: this.jdateValues,
slotValues: this.slotValues,
uploadValues: this.uploadValues,
popupValues: this.popupValues,
radioValues: this.radioValues,
@ -1371,6 +1450,11 @@
this.jdateValues[modelKey] = newValue
edited = true
}
// 在 slotValues 中寻找值
if (!edited && this.slotValues.hasOwnProperty(modelKey)) {
this.slotValues[modelKey] = newValue
edited = true
}
}
}
})
@ -1397,7 +1481,7 @@
let inputId = column.key + row.id
tooltips[inputId] = tooltips[inputId] ? tooltips[inputId] : {}
let [passed, message] = this.validateValue(column.validateRules, value)
let [passed, message] = this.validateValue(column, value)
const nextThen = res => {
let [passed, message] = res
@ -1433,6 +1517,9 @@
}
element.style.borderColor = borderColor
element.style.boxShadow = boxShadow
if (element.tagName === 'SPAN') {
element.style.display = 'block'
}
}
// 是否更新到data
if (update) {
@ -1450,23 +1537,22 @@
if (typeof msg === 'string') {
message = msg
}
if (flag == null) {
nextThen([null, message])
}else if (typeof flag === 'boolean' && flag) {
if (flag == null || flag === true) {
nextThen([true, message])
} else {
nextThen([false, message])
}
}, this)
} else {
nextThen([passed, message])
}
return [tooltips[inputId], notPassedIds]
},
/** 通过规则验证值是否正确 */
validateValue(rules, value) {
validateValue(column, value) {
let rules = column.validateRules
let passed = true, message = ''
// 判断有没有验证规则或验证规则格式正不正确,若条件不符合则默认通过
if (rules instanceof Array) {
@ -1477,12 +1563,24 @@
if (rule.required === true && isNull) {
passed = false
} else // 使用 else-if 是为了防止一个 rule 中出现两个规则
// 验证规则:唯一校验
if (rule.unique === true || rule.pattern === 'only') {
let { values } = this.getValuesSync({ validate: false })
let findCount = 0
for (let val of values) {
if (val[column.key] === value) {
if (++findCount >= 2) {
passed = false
break
}
}
}
} else
// 验证规则:正则表达式
if (!!rule.pattern && !isNull) {
// 兼容 online 的规则
let foo = [
{ title: '唯一校验', value: 'only', pattern: null },
{ title: '6到16位数字', value: 'n6-16', pattern: /\d{6,18}/ },
{ title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/ },
{ title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/ },
@ -1491,7 +1589,7 @@
{ title: '邮政编码', value: 'p', pattern: /^[1-9]\d{5}$/ },
{ title: '字母', value: 's', pattern: /^[A-Z|a-z]+$/ },
{ title: '数字', value: 'n', pattern: /^-?\d+\.?\d*$/ },
{ title: '整数', value: 'z', pattern: /^[1-9]\d*$/ },
{ title: '整数', value: 'z', pattern: /^-?\d+$/ },
{ title: '非空', value: '*', pattern: /^.+$/ },
{ title: '6到18位字符串', value: 's6-18', pattern: /^.{6,18}$/ },
{ title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/ },
@ -1505,7 +1603,9 @@
}
}
if (!flag) passed = new RegExp(rule.pattern).test(value)
} else if (typeof rule.handler === 'function') {
} else
// 校验规则:自定义函数校验
if (typeof rule.handler === 'function') {
return [rule.handler, rule.message]
}
// 如果没有通过验证,则跳出循环。如果通过了验证,则继续验证下一条规则
@ -1652,6 +1752,11 @@
}
},
/** 触发已拖动事件 */
emitDragged(oldIndex, newIndex) {
this.$emit('dragged', { oldIndex, newIndex, target: this })
},
/** 拖动结束交换inputValue中的值 */
handleDragMoveEnd(event) {
let { oldIndex, newIndex, item: { dataset: { idx: dataIdx } } } = event
@ -1662,13 +1767,7 @@
newIndex += diff
this.rowResort(oldIndex, newIndex)
// 触发已拖动事件
this.$emit('dragged', {
oldIndex,
newIndex,
target: this
})
this.emitDragged(oldIndex, newIndex)
},
/** 行重新排序 */
@ -1690,6 +1789,30 @@
this.forceUpdateFormValues()
},
/** 当前行向上移一位 */
_handleRowMoveUp(rowIndex) {
if (rowIndex > 0) {
let newIndex = rowIndex - 1
this.rowResort(rowIndex, newIndex)
this.emitDragged(rowIndex, newIndex)
}
},
/** 当前行向下移一位 */
_handleRowMoveDown(rowIndex) {
if (rowIndex < (this.rows.length - 1)) {
let newIndex = rowIndex + 1
this.rowResort(rowIndex, newIndex)
this.emitDragged(rowIndex, newIndex)
}
},
/** 在当前行下面插入一行 */
_handleRowInsertDown(rowIndex) {
let insertIndex = (rowIndex + 1)
this.insert(insertIndex)
},
/* --- common function begin --- */
/** 鼠标移入 */
@ -1732,6 +1855,14 @@
this.elemValueChange(type, row, column, value)
}
},
/** slot Change */
handleChangeSlotCommon(value, id, row, column) {
this.slotValues = this.bindValuesChange(value, id, 'slotValues')
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange(FormTypes.slot, row, column, value)
},
handleBlurCommono(target, index, row, column) {
let { value } = target
// 做单个表单验证
@ -1775,16 +1906,18 @@
if (column.responseName && file.response) {
value['responseName'] = file.response[column.responseName]
}
if(file.status =='done'){
if (file.status == 'done') {
value['path'] = file.response[column.responseName]
}
this.uploadValues = this.bindValuesChange(value, id, 'uploadValues')
},
/** 记录用到数据绑定的组件的值 */
bindValuesChange(value, id, key) {
let values = Object.assign({}, this[key])
values[id] = value
return values
// let values = Object.assign({}, this[key])
// values[id] = value
// return values
this.$set(this[key], id, value)
return this[key]
},
/** 显示或隐藏tooltip */
@ -1823,7 +1956,13 @@
handleClickDelFile(id) {
this.uploadValues[id] = null
},
handleClickDownloadFile(id) {
let { path } = this.uploadValues[id] || {}
if (path) {
let url = window._CONFIG['downloadUrl'] + '/' + path
window.open(url)
}
},
/** 加载数据字典并合并到 options */
_loadDictConcatToOptions(column) {
initDictOptions(column.dictCode).then((res) => {
@ -1980,42 +2119,42 @@
return headers
},
/** 上传请求地址 */
getUploadAction(value){
if(!value){
return window._CONFIG['domianURL']+"/sys/common/upload"
}else{
getUploadAction(value) {
if (!value) {
return window._CONFIG['domianURL'] + '/sys/common/upload'
} else {
return value
}
},
/** 预览图片地址 */
getCellImageView(id){
getCellImageView(id) {
let currUploadObj = this.uploadValues[id] || null
if(currUploadObj && currUploadObj['path']){
return window._CONFIG['domianURL']+"/sys/common/view/"+currUploadObj['path']
}else{
if (currUploadObj && currUploadObj['path']) {
return window._CONFIG['domianURL'] + '/sys/common/view/' + currUploadObj['path']
} else {
return ''
}
},
/** popup回调 */
popupCallback(value,others,id,row,column,index){
popupCallback(value, others, id, row, column, index) {
// 存储输入的值
this.popupValues[id]=value
if(others){
Object.keys(others).map((key)=>{
this.popupValues[id] = value
if (others) {
Object.keys(others).map((key) => {
this.inputValues[index][key] = others[key]
})
}
// 做单个表单验证
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
// 触发valueChange 事件
this.elemValueChange("input", row, column, value)
this.elemValueChange('input', row, column, value)
// 更新form表单的值
this.$nextTick(() => {
this.forceUpdateFormValues()
})
},
/** popup输入框回显 */
getPopupValue(id){
getPopupValue(id) {
return this.popupValues[id]
},
handleRadioChange(value, id, row, column) {