说明:
本示例中的代码和截图可能和您现在手中的版本不同,但操作思路一样。
一、概述
参照PC端数据模板列表中的自定义列,将移动端的显示字段通过配置保存至后端。注意,本示例中的后端请求参照自定义列的请求方法,需要根据自身需求再判断是否需要重新编写。
二、操作及示例
2.1、涉及的代码文件
1、template-list
目录:src\views\platform\data\template-list.vue
以下代码是在3.4.4的版本的基础上进行补充的,可根据自身代码还有下列示例有选择的进行补充
<template>
<div
:class="{
'ibps-fixed-toolbar':checkMode
}"
class="data-template-list"
>
<van-sticky>
<van-nav-bar
v-if="!hiddenAppTitle"
:title="generateTitle(title)"
:left-text="$t('common.button.back')"
:right-text="hasToolbar?rightText:''"
left-arrow
@click-left="onClickLeft"
@click-right="toCheckMode()"
/>
<!-- <van-search
v-show="$utils.isNotEmpty(queryKey)"
v-model="search"
:placeholder="$utils.isNotEmpty(queryName)?'请输入'+queryName:''"
show-action
@search="onSearch"
>
<template v-if="$utils.isNotEmpty(queryColumns) && queryColumns.length >1" #left>
<div style="width:100px;">
<ibps-select
v-model="queryKey"
:label="queryName"
:options="queryColumns"
:clearable="false"
value-key="prop"
@change="changeQuery"
/>
</div>
</template>
<template #action>
<van-icon name="filter-o" :class="stateActive?'active':'disactive'" @click="clickMoreSarch" />
</template>
</van-search> -->
<div v-show="$utils.isNotEmpty(queryKey)" class="data-template-list-search-wrapper">
<div class="data-template-list-search">
<div class="data-template-list-search__select">
<ibps-select
v-model="queryKey"
:label="queryName"
label-width="0px"
input-align="left"
:readonly="$utils.isEmpty(queryColumns) || queryColumns.length === 1"
:options="queryColumns"
:clearable="false"
value-key="prop"
@change="changeQuery"
/>
</div>
<div class="data-template-list-search__content">
<van-search
v-model="search"
:type="fieldType === 'number'?fieldType:'text'"
:placeholder="$utils.isNotEmpty(queryName)?'请输入'+queryName:''"
@search="onSearch"
/>
</div>
<van-icon class="data-template-list-search__icon" name="filter-o" :class="stateActive?'active':'disactive'" @click="clickMoreSarch" />
</div>
</div>
<!-- 设置过滤条件 -->
<van-row>
<van-col :span="hiddenAppTitle?'20':'24'">
<van-dropdown-menu class="menus" active-color="#3388FF">
<van-dropdown-item
v-if="$utils.isNotEmpty(rangeData[rootIndex].options)"
v-model="checkFilter"
:options="rangeData[rootIndex].options"
/>
<van-dropdown-item disabled title-class="menu-slot-text" class="menu-left">
<template #title>
<label
:class="$utils.isNotEmpty(rangeData[rootIndex].options)?null:'options-null'"
>共{{ pagination?pagination.totalCount||rootIndex :0 }}条</label>
</template>
</van-dropdown-item>
<van-dropdown-item
class="menu-right"
@open="onShowFieldsList('fields')"
>
<template #title>
<span
class="menu-slot-right"
size="small"
>
<van-icon name="password-view" class="custom-icon" /> 显示字段
</span>
</template>
</van-dropdown-item>
</van-dropdown-menu>
</van-col>
<van-col v-if="hiddenAppTitle" span="4">
<van-button style="height:40px;width:100%;" plain type="primary" size="small" @click="toCheckMode()">
<template #default>
<i class="ibps-icon ibps-icon-user">
管理
</i></template>
</van-button>
</van-col>
</van-row>
<!-- <drop-menu
ref="dropMenu"
:async="async"
:data="rangeData"
:default-value="defaultValue"
@change="changeFilterCondition"
>
<template v-slot:checks="scope">
<div v-if="$utils.isNotEmpty(rangeData[rootIndex].options)" class="menu-slot-checks" :style="{'color':scope.color}">{{ scope.text||filterCondition }}</div>
</template>
<template v-slot:icon="scope">
<span v-if="$utils.isNotEmpty(rangeData[rootIndex].options)" class="menu-slot-icon" :style="{'color':scope.color}">
<van-icon :name="scope.icon" />
</span>
</template>
<template slot="text">
<label class="menu-slot-text" :class="$utils.isNotEmpty(rangeData[rootIndex].options)?null:'options-null'"> 共 {{ pagination?pagination.totalCount||rootIndex :0 }} 条</label>
</template>
设置显示字段 -->
<!-- <template slot="right">
<span class="menu-slot-right" size="small" @click="onShowFieldsList('fields')">
<van-icon name="password-view" class="custom-icon" /> 显示字段
</span>
</template>
</drop-menu> -->
</van-sticky>
<!-- 列 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list v-model="loading" :finished="finished" @load="onLoad">
<van-cell
v-for="(item,index) in listData"
:key="item[idKey]+index"
class="ibps-p-0"
>
<van-swipe-cell
:right-width="manages.length>0?(manages.length>3?3*55:manages.length*55):0"
:on-close="onClose"
class="template-cell"
>
<van-checkbox-group v-model="checkedIds">
<van-cell
border
style="padding:15px 16px"
@click="onClick(item,index)"
>
<template slot="icon">
<van-checkbox
v-if="checkMode"
ref="checkboxes"
:name="item"
class="ibps-mr-10"
/>
</template>
<!--标题-->
<template #title>
<field-formatter
class="titles"
:is-text="true"
:label-key="labelField['name']"
:data="item"
:params="dataTemplate"
:template-fields="templateFields"
/>
</template>
<!--描述展示-->
<template #label>
<template v-if="$utils.isNotEmpty(descFields)">
<!-- v-if="descField&&descField['name']&&item[descField['name']]" -->
<div
v-for="descField in descFields"
:key="descField['name']"
class="van-card-list__desc"
>
<span class="van-card-list__desc__title desc">{{ descField['label'] }}:</span>
<field-formatter
:label-key="descField['name']"
:data="item"
:template-fields="templateFields"
:params="dataTemplate"
class="desc"
default-value
/>
</div>
</template>
</template>
</van-cell>
</van-checkbox-group>
<!--管理列-->
<template #right>
<template-toolbar
:buttons="manages"
@action-event="button => handleAction(button,item)"
/>
</template>
</van-swipe-cell>
<div v-if="listData.length-1 > index" class="ibps-blank-bar" />
</van-cell>
</van-list>
<ibps-list-result-page
:result-type="resultType"
:error-type="errorType"
:result-message="resultMessage"
/>
</van-pull-refresh>
<!--添加按钮-->
<div v-if="$utils.isNotEmpty(addButton)" v-show="!checkMode" class="palette-button">
<van-button
round
type="info"
icon="plus"
size="large"
style="border-radius: 100%; width: 50px;"
@click="handleAction(addButton)"
/>
</div>
<!--工具栏 -->
<ibps-toolbar
v-show="checkMode"
icon-prefix="ibps-icon"
:actions="toolbarButtons"
:more-actions="moreToolbarButtons"
@action-event="(button)=>handleAction(button)"
/>
<!--更多查询 -->
<ibps-more-search
ref="ibpsMoreSearch"
:show="popupShow"
:search-forms="searchForms"
@callback="onSearch"
@close="callback => popupShow = callback"
@resetForm="resetForm"
>
<template
v-for="(slotForm,index) in searchForms.forms"
:slot="slotForm.slotName"
>
<search-field
ref="moreSearchField"
:key="index"
input-align="left"
:forms="searchForms.forms"
:item="slotForm"
:data="searchFormData"
/>
</template>
</ibps-more-search>
<!--显示字段 -->
<van-popup
v-model="display"
position="bottom"
:overlay="true"
>
<ibps-picker-toolbar
:cancel-button-text="$t('cancel') "
:confirm-button-text=" $t('confirm')"
@cancel="onDisplayCancel"
@confirm="onDisplayConfirm"
/>
<div class="ibps-popup-wrapper">
<van-checkbox-group v-model="chooseResult">
<van-cell-group>
<van-cell
v-for="(item, index) in fieldsList"
:key="item['name']+index"
:title="item.name"
size="large"
>
<template #right-icon>
<van-checkbox :name="item.prop" />
</template>
<!-- <van-checkbox :name="item.name">{{ item.name }}</van-checkbox> -->
</van-cell>
</van-cell-group>
</van-checkbox-group>
</div>
</van-popup>
<data-template-formrender-dialog
ref="formrender"
:visible="formrenderVisible"
:params="formrenderParams"
:button-priority="buttonPriority"
@callback="onRefreshCallback"
@close="visible => formrenderVisible = visible"
/>
<!-- 流程定义选择器 -->
<bpm-def-dialog
v-model="sefStartFlowDialogValue"
:visible="sefStartFlowDialogVisible"
:form-key="formKey"
:multiple="false"
:is-data-template-use="true"
@close="visible => sefStartFlowDialogVisible = visible"
@action-event="handleStartFlowDialogActionEvent"
/>
</div>
</template>
<script>
import { queryDataByKey, removeFormData } from '@/api/platform/data/dataTemplate'
import { loadDataTemplateById, getDataTemplateListTemplate, buildDataTemplateFields } from '@/business/platform/data/utils'
import ButtonsConstants, { hasButton } from '@/business/platform/data/constants/buttons'
import { startFlowFromList } from '@/api/platform/bpmn/bpmInst'
import TreeUtils from '@/utils/tree'
import ActionUtils from '@/utils/action'
import i18n from '@/utils/i18n'
import storage from '@/utils/storage'
import IbpsMoreSearch from '@/components/ibps-more-search'
import IbpsListResultPage from '@/components/ibps-list-result-page'
import IbpsToolbar from '@/components/ibps-toolbar'
import FieldFormatter from '@/business/platform/data/data-template/field-formatter'
import FormUtils from '@/business/platform/form/utils/formUtil'
// import JTemplate from '@/business/platform/data/utils/JTemplate' // 自定义脚本
import eventsUtil from '@/utils/eventsUtil'// 自定义脚本
import TemplateToolbar from './template-toolbar'
// import DropMenu from './components/dropMenu'
import DateFormatUtil from '@/business/platform/form/utils/dateFormatUtil'
import SearchField from './components/search-field'
import { queryConditionOptions } from './constants'
import DataTemplateFormrenderDialog from '@/business/platform/data/form/dialog'
import IbpsPickerToolbar from '@/components/ibps-picker-toolbar'
import OptionMixin from '@/mixins/fieldOption'
import FormOptions from '@/business/platform/form/constants/formOptions'
import BpmDefDialog from '@/business/platform/bpmn/definition/dialog'
import CustomDataDisplayMixin from '@/business/platform/system/mixins/customDataDisplay'
export default {
name: 'TemplateList',
components: {
TemplateToolbar,
// DropMenu,
SearchField,
IbpsListResultPage,
// IbpsPaletteButton,
IbpsToolbar,
IbpsMoreSearch,
FieldFormatter,
DataTemplateFormrenderDialog,
IbpsPickerToolbar,
BpmDefDialog
},
mixins: [OptionMixin, CustomDataDisplayMixin],
props: {
value: {
type: [String, Number, Boolean, Array, Object, Date]
}
},
data() {
return {
stateActive: false,
popupShow: false,
resetFields: false,
dateFormat: 'yyyy-MM-dd',
searchForms: {},
firsthand: [],
params: {},
slotForms: [],
paramsForm: {},
searchParams: {},
async: false,
rootIndex: 0,
filterCondition: '',
action: '',
position: '',
actionData: {},
fieldsList: [],
display: false,
chooseResult: [],
checkFilter: '',
configKey: '',
defaultValue: [],
rangeData: [{ options: [] }],
search: '',
title: '',
listData: [],
pagination: {},
sorts: {},
loading: false,
finished: false,
refreshing: false,
resultType: 'init',
buttonPriority: 'outside',
errorType: null,
resultMessage: null,
idKey: '',
labelField: '',
descFields: [],
dataTemplate: '',
queryColumns: [],
queryKey: '',
queryName: '',
queryLabel: '',
fieldType: '',
isTree: false,
templateId: '',
templateKey: '',
formKey: '',
detailFormKey: '',
templateFields: {}, // 模版字段
editButtons: '', // 编辑按钮
cacheEditButtons: '', // 缓存编辑按钮
functionButtons: [], // 功能按钮
checkMode: false,
checkedIds: [],
toolbars: [],
manages: [],
defaultToolbars: [],
defaultManages: [],
isInitialization: false,
// 表单
formrenderVisible: false,
formrenderParams: {},
searchFormData: {},
queryData: {},
queryConditionOptions,
combinationQueryFileds: {},
eventsUtil: {},
sefStartFlowDialogVisible: false,
sefStartFlowDialogValue: {},
sefStartFlowId: ''
}
},
computed: {
listIdentity() {
return 'ibps_data_template_tpl' + '_' + this.dataTemplate.key
},
hasMessage() {
return true
},
hiddenAppTitle() {
return this.dataTemplate ? this.dataTemplate.default_list.attrs.hiddenAppTitle || false : false
},
toolbarButtons() {
return this.toolbars.length > 4 ? this.toolbars.slice(0, 4) : this.toolbars
},
moreToolbarButtons() {
return this.toolbars.length > 4 ? this.toolbars.slice(4, this.toolbars.length) : null
},
hasToolbar() {
return this.toolbars.length > 0 && this.$utils.isNotEmpty(this.listData)
},
addButton() {
for (let i = 0; i < this.defaultToolbars.length; i++) {
const button = this.defaultToolbars[i]
if (button.button_type === 'add') {
return button
}
}
return null
},
editButton() {
return this.includesFunctionButton('edit')
},
rightText() {
return this.checkMode
? this.$t('common.button.cancel')
: this.$t('common.button.manage')
},
hasScript() {
const tmpDef = this.dataTemplate
return !!(tmpDef && tmpDef.attrs && tmpDef.attrs.mobile_script)
}
},
created() {
const params = this.$route.params
this.templateId = params.id
this.loadDataTemplate(this.templateId)
},
mounted() {
// if (this.isInitialization && this.hasScript) {
// JTemplate._onLoad(this)
// }
},
beforeDestroy() {
eventsUtil.cleanEventsByName(this.eventsUtil._eventsUtilsID)
this.eventsUtil = null
},
methods: {
onLoadActions() {
return false
},
onDisplayCancel() {
this.display = false
},
onDisplayConfirm() {
if (this.$utils.isEmpty(this.chooseResult) || this.chooseResult.length === 0) {
this.$toast('显示字段至少选择一项!')
return
}
ActionUtils.initListData(this)
this.checkedIds = []
this.loadDataTemplate(this.templateId)
// storage.set('chooseFields', this.chooseResult)
const _data = []
this.fieldsList.forEach(el => {
if (this.chooseResult.includes(el.prop)) {
_data.push(el)
}
})
this.saveCustomDataDisplay(_data, this.listIdentity).then((response) => {
if (this.hasMessage) ActionUtils.success(response.message)
this.display = false
}).catch(() => {
this.display = false
})
},
onShowFieldsList(keys) {
this.async = !this.async
this.configKey = keys
this.display = true
},
changeFilterCondition(barItem, listItem) {
this.checkFilter = listItem.name
storage.set('filterCondition', listItem)
this.onSearch()
},
initFilterText() {
const listItem = storage.get('filterCondition')
if (this.$utils.isNotEmpty(listItem)) {
this.checkFilter = listItem.value
} else {
this.checkFilter = this.$utils.isNotEmpty(this.rangeData[this.rootIndex].options) ? this.rangeData[this.rootIndex].options[this.rootIndex].value : ''
}
},
loadDataTemplate(id) {
const params = {}
loadDataTemplateById(id, params)
.then(data => {
this.initFormData(data)
})
.catch(e => {
console.error(e)
})
},
initFormData(data) {
this.title = data['name']
this.dataTemplate = data
// 初始化脚本
if (!this.isInitialization) {
// this.initJTemplate()
if (this.dataTemplate.attrs && this.dataTemplate.attrs.mobile_script) {
this.eventsUtil = eventsUtil._initEvents(this.dataTemplate.attrs.mobile_script, 'list_' + this.dataTemplate.key, true)
}
this.isInitialization = true
}
if (this.isInitialization && this.hasScript) {
// JTemplate._onLoad(this)
eventsUtil._eventCall(this.eventsUtil, 'onLoad', this)
}
i18n.setTitle(this.title)
const template = getDataTemplateListTemplate(data)
this.templateFields = buildDataTemplateFields(data.fields)
this.setOptionsByFields(this.templateFields)
this.buildKey(data, template)
this.loadData()
this.initFilterText()
},
async buildKey(dataTemplate, template) {
this.idKey = dataTemplate['unique']
this.templateKey = dataTemplate['key']
this.formKey = dataTemplate.attrs ? dataTemplate.attrs.form_key || '' : ''
this.detailFormKey = dataTemplate.attrs ? dataTemplate.attrs.detail_form_key || '' : ''
this.buildQuerycolumns(template['query_columns'])
const fieldsList = template['display_columns'] ? template['display_columns'] : []
if (this.$utils.isNotEmpty(fieldsList)) {
const displayFields = fieldsList.filter(i => i.field_type !== 'hidden')
this.fieldsList = displayFields.map(i => {
return {
name: i.label,
prop: i.name
}
})
} else {
this.$toast('显示字段不能为空!请在PC端中配置。')
}
this.initOptions(fieldsList)
const colums = []
// const chooseResult = storage.get('chooseFields')
// if (chooseResult !== undefined) {
// this.chooseResult = chooseResult
// }
await this.getCustomDataDisplay(
this.listIdentity
).then((data) => {
if (this.$utils.isNotEmpty(data)) {
this.chooseResult = data.map(el => {
return el.prop
})
}
})
for (let i = 0; i < this.chooseResult.length; i++) {
for (let l = 0; l < fieldsList.length; l++) {
if (this.chooseResult[i] === fieldsList[l].name) {
colums.push(fieldsList[l])
}
}
}
const displayColumns = colums
const filterActions = this.$utils.isNotEmpty(template['filter_conditions']) ? template['filter_conditions'] : []
if (this.$utils.isNotEmpty(filterActions)) {
this.rangeData[this.rootIndex].options = filterActions.map(i => {
return { text: i.label, value: i.key }
})
}
this.initFilter(filterActions, this.rootIndex)
if (dataTemplate.showType === 'tree') {
this.isTree = true
if (this.$utils.isNotEmpty(displayColumns)) {
this.labelField = displayColumns['name_key']
this.idKey = displayColumns['id_key']
this.parentIdKey = displayColumns['pid_key']
}
} else if (dataTemplate.showType === 'list') {
this.isTree = false
if (this.$utils.isNotEmpty(displayColumns)) {
// 显示字段顺序预处理
const arr = []
for (var i = 0; i < displayColumns.length; i++) {
for (var l = 0; l < fieldsList.length; l++) {
if (displayColumns[i].label === fieldsList[l].label) {
arr[l] = fieldsList[l]
}
}
}
const columns = arr.filter(e => {
if (e !== '' && e !== undefined) {
return e
}
})
this.labelField = columns[0] || {}
this.descFields = columns.filter((e, i) => {
return i > 0
})
}
const button = template['buttons'] || {}
const editButtons = button['edit_buttons'] || []
this.cacheEditButtons = this.editButtons = editButtons
let functionButtons = button['function_buttons'] || []
// TODO:目前版本不支持按钮 ,'print', 'import', 'export', 'sefStartFlow',
const allowButtons = ['add', 'remove', 'edit', 'detail', 'custom', 'sefStartFlow']
functionButtons = functionButtons.filter((b) => {
if (allowButtons.includes(b.button_type)) {
return b
}
})
this.functionButtons = functionButtons
this.initToolbarAction()
}
},
onSearch(data) {
this.stateActive = false
ActionUtils.initListData(this)
this.checkedIds = []
this.paramsForm = {}
const moreSearchField = this.$refs.moreSearchField
if (moreSearchField) {
for (var i = 0; i < moreSearchField.length; i++) {
const obj = moreSearchField[i].getParams()
for (var j in obj) {
if (moreSearchField[i].item.prop === j) {
this.paramsForm[j] = obj[j]
}
}
}
}
if (this.$utils.isNotEmpty(data)) {
for (var d in data) {
if (this.$utils.isNotEmpty(data[d])) {
this.paramsForm[d] = data[d]
}
}
}
// 处理参数
if (this.$utils.isNotEmpty(this.paramsForm)) {
// const superParams = ['ISN', 'ISNN', 'SIE', 'SNE']
for (var key in this.paramsForm) {
const value = this.paramsForm[key]
if (this.$utils.isEmpty(value)) {
delete this.paramsForm[key]
continue
}
// // 第三方参数
// const upArrowsSymbolIndex = key.lastIndexOf('^')
// const threeParams = key.slice(upArrowsSymbolIndex + 1)
// if (this.$utils.isEmpty(value) && !superParams.includes(threeParams)) {
// delete this.paramsForm[key]
// continue
// }
// 多选的处理
if (Array.isArray(value)) {
this.paramsForm[key] = this.getMultiSelectParams(key, value)
}
// 组合字段处理
if (this.combinationQueryFileds[key]) {
this.paramsForm[key] = this.getCombinationQueryParams(this.combinationQueryFileds[key], value)
}
}
}
this.searchParams = Object.assign({}, this.paramsForm)
this.loadData()
},
// 多值处理
getMultiSelectParams(key, value) {
const queryColumns = {
relation: 'AND', // 组合条件类型
parameters: [] // 拼接的字段集合
}
const relation = 'OR'
const parameters = []
for (let i = 0; i < value.length; i++) {
const val = value[i]
parameters.push({
key: key,
value: val,
param: this.$utils.guid(),
relation: relation
})
}
queryColumns.parameters.push({
relation: relation,
parameters: parameters
})
return queryColumns
},
// 组合字段处理
getCombinationQueryParams(combination, value) {
const queryFileds = combination.queryFileds
const conditionType = combination.conditionType || 'OR'
const queryColumns = {
relation: 'AND', // 组合条件类型
parameters: [] // 拼接的字段集合
}
const parameters = []
queryFileds.forEach(q => {
parameters.push({
relation: conditionType,
key: q.queryfields,
value: value,
param: this.$utils.guid()
})
})
queryColumns.parameters.push({
relation: conditionType,
parameters: parameters
})
return queryColumns
},
resetForm() {
const moreSearchField = this.$refs.moreSearchField
if (!moreSearchField) return
for (var i = 0; i < moreSearchField.length; i++) {
const def = moreSearchField[i].resetForm()
for (var j in def) {
this.paramsForm[j] = def[j]
}
}
},
clickMoreSarch() {
this.popupShow = true
this.stateActive = false
},
onLoad() {
this.loadData()
},
loadData() {
if (this.$utils.isEmpty(this.templateKey)) {
return
}
if (this.checkFilter === '') {
const listItem = storage.get('filterCondition')
if (listItem !== undefined) {
this.checkFilter = listItem.name
}
}
const params = {
key: this.templateKey,
dynamicParams: '', // 动态参数,获取页面的值
filterConditionKey: this.checkFilter || '' // 多个过滤条件
}
if (this.$utils.isNotEmpty(this.search) && this.queryKey) {
params[this.queryKey] = this.search
} else {
Object.assign(params, this.searchParams)
}
// 加载数据
queryDataByKey(ActionUtils.formatParams(params, this.pagination))
.then(response => {
const responseData = response.data
if (this.isTree) {
const dataResult = responseData.dataResult
this.pagination = responseData.pageResult || {}
this.listData = TreeUtils.transformToTreeFormat(dataResult, {
idKey: this.idKey,
parentIdKey: this.parentIdKey,
childrenKey: this.childrenKey
})
// 初始化最顶级数据
this.initRootTreeData(response.vars)
this.finished = true
} else {
if (!this.finished) {
// 处理数据
ActionUtils.handleListData(this, responseData)
}
}
})
.catch(e => {
ActionUtils.handleErrorData(this, e)
})
},
// 默认显示字段列表
initOptions(list) {
list.forEach((val, index) => {
if (this.configKey === '') {
if (index < 4) {
this.chooseResult.push(val.name)
}
}
})
},
initFilter(list, index) {
if (this.$utils.isNotEmpty(list)) {
if (!this.$utils.isNotEmpty(this.defaultValue)) {
const listItem = storage.get('filterCondition')
if (this.$utils.isNotEmpty(listItem)) {
const i = list.findIndex(i => i.label === listItem.text)
this.defaultValue = [list[i].key]
} else {
this.defaultValue = [list[index].key]
}
}
}
},
onRefreshCallback() {
this.checkMode = false
this.onRefresh()
},
onRefresh() {
this.refreshing = true
this.finished = false
this.loading = true
this.onSearch()
},
onClick(item, index) {
if (this.checkMode) {
this.$refs.checkboxes[index].toggle()
} else {
return
// this.gotoForm({
// readonly: true,
// pkValue: item[this.idKey]
// })
}
},
generateTitle(name, title) {
// generateTitle by vue-i18n
return i18n.generateTitle(name, title)
},
onClickLeft() {
this.$router.push({ name: 'dashboard' })
storage.remove('filterCondition')
storage.remove('chooseFields')
},
onClose(clickPosition, instance) {
switch (clickPosition) {
case 'left':
case 'cell':
case 'outside':
instance.close()
break
case 'right':
instance.open()
break
}
},
handleAction(button, data) {
const buttonType = button.button_type || button.key
const key = button.key || button.button_type
const position = button.position
const selection = this.getSelection(position, data)
// 前置事件
this.beforeScript(key, position, selection, data, () => {
this.readonly = false
this.action = buttonType
this.position = position
this.actionData = data
switch (buttonType) {
case 'add':// 添加
this.handleEdit('', button, buttonType, position, data)
break
case 'edit':// 编辑
case 'detail':// 明细
ActionUtils.selectedRecord(selection).then((id) => {
this.handleEdit(id, button, buttonType, position, data)
}).catch(() => { })
break
case 'remove':// 删除
ActionUtils.removeRecord(selection).then((ids) => {
this.handleRemove(ids, button, buttonType, position, data)
}).catch(() => { })
break
case 'sefStartFlow':// 启动自定义流程
ActionUtils.selectedMultiRecord(selection).then((ids) => {
if (button.deflow) {
this.$dialog.confirm({
title: '消息',
message: '确定启动流程吗?'
}).then(() => {
this.handleStartFlowFromList(ids, button.deflow, this.getFormKey())
}).catch(() => {})
} else {
this.sefStartFlowDialogVisible = true
this.sefStartFlowDialogValue = {}
this.sefStartFlowId = ids
}
}).catch(() => {})
break
case 'custom':// 自定义按钮
if (this.$utils.isNotEmpty(button['formKey'])) {
ActionUtils.selectedRecord(selection, false).then((id) => {
this.handleEdit(id, button, position, selection, data, button)
}).catch(() => { })
} else {
ActionUtils.selectedMultiRecord(selection).then((ids) => {
this.afterScript(key, position, ids, data, () => {
this.onRefreshCallback()
})
}).catch(() => {})
}
break
default:
break
}
})
},
handleStartFlowDialogActionEvent(key, data) {
if (key === 'confirm') {
this.handleStartFlowFromList(this.sefStartFlowId, data ? data.defKey : '', this.getFormKey(), (rtn) => {
if (rtn) {
this.sefStartFlowDialogVisible = false
}
})
}
},
handleStartFlowFromList(id, defKey, formKey, callback) {
startFlowFromList({
ids: id,
defKey: defKey,
formKey: formKey
}).then(response => {
callback(true)
this.$notify({
message: '流程启动成功!',
type: 'success'
})
this.search()
this.afterScript(this.action, this.position, id, this.actionData, () => {
this.onRefreshCallback()
})
}).catch(() => {
callback(false)
})
},
getFormKey() {
return this.dataTemplate.attrs ? this.dataTemplate.attrs.form_key || '' : ''
},
getSelection(position, data) {
const selection = []
if (position === 'toolbar') {
this.checkedIds.forEach((d) => {
selection.push(d[this.idKey])
})
} else {
selection.push(data[this.idKey])
}
return selection
},
getCustomDetailFormKey(button, key = 'detailFormKey') {
if (button && this.$utils.isNotEmpty(button[key])) {
return button[key]
} else {
return this.detailFormKey
}
},
handleEdit(pkValue, button, code, position, data) {
if (this.$utils.isEmpty(this.formKey)) {
ActionUtils.warning('请绑定表单')
return
}
this.editButtons = JSON.parse(JSON.stringify(this.cacheEditButtons))
let formKey = this.formKey
if (button.key === 'detail' || button.key === 'customDetail') {
this.readonly = true
this.buttonPriority = 'outside'
const detailFormKey = button.key === 'customDetail' ? this.getCustomDetailFormKey(button) : this.detailFormKey
if (this.$utils.isNotEmpty(detailFormKey)) {
formKey = detailFormKey
}
}
const editToolbars = []
const action = this.action
this.editButtons.forEach((rf, i) => {
const buttonType = button.key === 'add' ? 'edit' : action
// 编辑页顶部按钮
if (hasButton(rf.button_type, buttonType, rf.position)) {
editToolbars.push(rf)
}
})
this.editButtons = editToolbars
const buttonType = button.button_type || button.key
// TODO: 左树右列数据处理
// if (this.relatedTreeFields && this.$utils.isNotEmpty(this.defaultData)) {
// const selection = this.defaultData[this.relatedTreeFields]
// this.defaultFormData = action === 'add' ? this.getDefaultFormData(selection) : null
// } else {
// this.defaultFormData = {}
// }
this.buttonPriority = 'outside'
this.gotoForm({
pkValue,
readonly: buttonType === 'detail',
formKey
})
this.afterScript(code, position, pkValue, data, () => {})
},
gotoForm({ pkValue = '', readonly = true, formKey = this.formKey }) {
this.formrenderParams = {
templateKey: this.templateKey,
formKey: formKey,
pkValue: pkValue,
toolbars: this.editButtons,
readonly: readonly
}
this.formrenderVisible = true
},
handleRemove(ids, button, code, position, data) {
this.removeRecord(ids, r => {
this.afterScript(code, position, ids, data, () => {
this.checkMode = false
this.checkedIds = []
this.onRefreshCallback()
})
})
},
removeRecord(ids, callback) {
removeFormData({
ids: ids,
idKey: this.idKey,
formKey: this.formKey
}).then(() => {
this.$notify({
type: 'success',
message: '删除成功'
})
if (callback) {
callback(true)
}
this.onRefresh()
})
},
toCheckMode() {
if (!this.hasToolbar) {
return
}
if (this.checkMode) {
this.show = true
this.checkedIds = []
}
this.checkMode = !this.checkMode
},
/**
* 初始化工具栏
*/
initToolbarAction() {
const functionButtons = this.functionButtons || []
const toolbars = []
const manages = []
// 功能按钮
functionButtons.forEach((rf, i) => {
const btn = this.buildButton(rf, i)
// 顶部按钮
if (hasButton(rf.button_type, 'toolbar', rf.position)) {
btn.position = 'toolbar'
toolbars.push(JSON.parse(JSON.stringify(btn)))
}
// 管理列按钮
if (hasButton(rf.button_type, 'manage', rf.position)) {
btn.position = 'manage'
manages.push(JSON.parse(JSON.stringify(btn)))
}
})
const filterButtons = ['search', 'resetSearch', 'add']
this.defaultToolbars = toolbars
this.toolbars = toolbars.filter((b) => {
if (!filterButtons.includes(b.button_type)) {
return b
}
})
this.defaultManages = manages
this.manages = manages
// this.manages = manages.filter((b) => {
// if (allowButtons.includes(b.button_type)) {
// return b
// }
// })
},
/**
* 构建按钮
*/
buildButton(rf, i) {
const defaultButton = ButtonsConstants[rf.button_type] || {}
let key = rf.button_type
let mode
let rightIcon
let menus
if (key === 'custom' || key === 'sefStartFlow') {
key = rf.code ? rf.code : key + i
}
if (rf.button_type === 'export') {
mode = 'dropdown'
rightIcon = true
menus = ButtonsConstants[rf.button_type].menus
}
let disabled = false
let hidden = false
if (this.hasButtonAction(key, rf)) {
hidden = (row, data) => {
// return JTemplate._onLoadActions(this, key, rf, 'hidden', row, data)
return eventsUtil._eventCall(this.eventsUtil, 'onLoadActions', this, key, rf, 'hidden', row, data)
}
disabled = (row, data) => {
// return JTemplate._onLoadActions(this, key, rf, 'disabled', row, data)
return eventsUtil._eventCall(this.eventsUtil, 'onLoadActions', this, key, rf, 'disabled', row, data)
}
}
return {
'$index': i,
key: key,
button_type: rf.button_type,
code: rf.code,
name: rf.label || defaultButton.label,
icon: rf.icon ? rf.icon : defaultButton.icon,
type: this.converType(rf.style || defaultButton.type),
deflow: rf.deflow || null,
formKey: rf.formKey || null,
detailFormKey: rf.detailFormKey || null,
mode: mode,
confirm: rf.confirm || false,
rightIcon: rightIcon,
menus: menus,
disabled: disabled,
hidden: hidden
}
},
converType(type) {
if (type === 'primary') return 'info'
if (type === 'info') return 'gray'
if (type === 'success') return 'primary'
return type
},
// 自定义格式数据事件
hasButtonAction: function(key, button) {
// const buttonActionResult = JTemplate._onLoadActions(this, key, button)
const buttonActionResult = eventsUtil._eventCall(this.eventsUtil, 'onLoadActions', this, key, button)
if (typeof (buttonActionResult) !== 'undefined' && buttonActionResult) {
return true
}
return false
},
customCallback(item) {
this.beforeSubmit('custom')
// TODO 后面是自定义按钮的事
},
beforeSubmit(alias) {
// 前置事件
if (this.hasScript) {
// const beforSubmitResult = JTemplate._beforeSubmit(
// this,
// alias,
// this.dataTemplate
// )
const beforSubmitResult = eventsUtil._eventCall(this.eventsUtil, 'beforeSubmit', this, alias, this.dataTemplate)
if (typeof beforSubmitResult !== 'undefined' && !beforSubmitResult) {
return
}
}
},
includesFunctionButton(key) {
const btns = this.functionButtons.map(button => {
return button['button_type']
})
return btns.includes(key)
},
convertField(column) {
if (!column.name) return column
const field = this.templateFields[column.name.toLowerCase()] || null
// const same = this.$utils.toBoolean(column['same'], false)
const same = !((column['same'] && column['same'] === 'N'))
let fieldType = same ? (field ? (field['field_type'] || 'text') : 'text') : column['field_type'] || 'text'
const fieldOptions = same ? (field ? (field['field_options'] || {}) : {}) : (column['field_options'] || {})
const dataType = field ? field['type'] || 'varchar' : 'varchar'
// 字段是日期类型
if ((dataType === 'date' || dataType === 'timestamp' ||
dataType === 'datetime' || dataType === 'currentTime' || dataType === 'currentDate') &&
(fieldType !== 'datePicker' && fieldType !== 'dateRange')) {
fieldType = !same ? fieldType : 'datePicker'
}
if (fieldType === 'datePicker' || fieldType === 'dateRange') {
const datefmtType = fieldOptions['datefmt_type']
if (datefmtType !== 'custom') {
fieldOptions['datefmt'] = this.getDatefmt(fieldOptions)
}
}
// 处理当前用户,当前组织控件
if (fieldType === 'currentUser' || fieldType === 'currentOrg') {
fieldType = 'selector'
}
column['field_type'] = fieldType
column['field_options'] = fieldOptions
column['dataType'] = dataType
return column
},
getDatefmt(fieldOptions) {
if (fieldOptions['datefmt_type'] && fieldOptions['datefmt_type'] !== 'custom') {
return FormOptions.t.DATE_FORMATS[fieldOptions['datefmt_type']] || FormOptions.t.DATE_FORMATS['date']
}
return fieldOptions['datefmt'] || FormOptions.t.DATE_FORMATS['date']
},
buildQuerycolumns(queryColumns) {
this.searchForms.forms = []
if (this.$utils.isEmpty(queryColumns)) {
return
}
// TODO:目前第一个字段查询字段只支持 文本,多行文本和自动编号、数字、日期范围
const firstFieldTypes = ['text', 'textarea', 'daterange', 'autonumber', 'number']
//
const arr = [
'text',
'number',
'numberRange',
'hidden',
'select',
'dateRange',
'datePicker',
'autoNumber'
]
const columns = []
const queryColumnsData = []
queryColumns.forEach(column => {
if (column.common === 'N') return
const field = this.convertField(column)
const fd = this.buildSearchForm(field, !!column.same)
columns.push(fd)
const fieldType = field.field_type || ''
if (firstFieldTypes.includes(fieldType.toLowerCase())) {
queryColumnsData.push(fd)
}
if (!arr.includes(fieldType)) {
this.slotForms.push(fd)
}
this.slotForms.forEach(v => {
this.paramsForm[v.prop] = ''
})
})
this.searchForms.forms = columns
// 顶部查询条件
this.queryColumns = queryColumnsData || []
const queryColumn = this.$utils.isNotEmpty(this.queryColumns) ? this.queryColumns[0] : {}
this.queryKey = queryColumn.prop || ''
this.queryName = queryColumn.label || ''
this.fieldType = queryColumn.fieldType || ''
},
buildSearchForm(field, same) {
let querySuffix
const datasetType = this.dataTemplate.datasetType
const dataTypes = ['date', 'varchar', 'number']
if (dataTypes.includes(field.dataType) &&
field.queryCondition && this.$utils.isNotEmpty(field.queryCondition)) {
const dataTypesSuffixs = datasetType === 'thirdparty' ? this.queryConditionOptions[field.fieldsTypes || 'varchar'] : this.queryConditionOptions[field.dataType]
const suffixData = dataTypesSuffixs.filter(d => d.value === field.queryCondition)
querySuffix = this.$utils.isNotEmpty(suffixData) ? suffixData[0].suffix : 'SL'
} else {
if (field.dataType === 'number') {
querySuffix = 'SIN'
}
}
// 1、日期/数字 条件为范围时得特殊处理。
// 2、控件类型不一致时选的控件类型传递后缀是否以数据格式类型得对应条件后缀为准,还是单独保持原样。
// 3、直接添加查询字段时得默认拼接后缀,保留目前写死得后缀将其转化在内部作为直接添加而不进入查询字段时得默认条件后缀。
let searchColumn = {
label: field.label,
placeholder: field.placeholder
}
// 控件类型
const fieldType = field['field_type'] || 'text'
const fieldOptions = field['field_options']
// 组合字段
if (field.addType === 'combination') {
const queryFileds = this.buildJointFileds(field.combinationKeyField).filter(f => f !== '')
const combinationQueryFileds = []
const queryCondition = field.queryCondition || 'include'
queryFileds.forEach(name => {
const column = this.fields[name.toLowerCase()] || { }
const type = column.type || 'varchar'
const dataType = this.dataTypes[type] || {}
if (type === 'date') {
combinationQueryFileds.push({
queryfields: 'Q^' + name + dataType.start
}, {
queryfields: 'Q^' + name + dataType.end
})
} else {
const fieldSuffix = dataType[queryCondition] ? dataType[queryCondition] : 'SL'
combinationQueryFileds.push({ queryfields: 'Q^' + name + fieldSuffix })
}
})
const prop = field.combinationName
this.combinationQueryFileds[prop] = {
prop: prop,
conditionType: this.conditionTypeOptions[queryCondition].conditionType,
queryFileds: combinationQueryFileds
}
// ---------------------------------------------------------
searchColumn = Object.assign(searchColumn, {
prop: prop,
modelValue: prop,
fieldType: fieldType,
fieldOptions: fieldOptions
})
} else {
if (fieldType === 'hidden') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'SL'
}
searchColumn = Object.assign(searchColumn, {
prop: `Q^${field.name}^${querySuffix}`,
modelValue: `Q^${field.name}^${querySuffix}`,
fieldType: fieldType,
fieldOptions: fieldOptions
})
} else if (fieldType === 'numberRange') { // 数字范围
if (this.$utils.isEmpty(querySuffix)) {
if (field.dataType === 'number') {
querySuffix = ['DBL', 'DBG']
} else {
const dataTypesSuffixs = this.queryConditionOptions[field.dataType]
querySuffix = [dataTypesSuffixs[0]['suffix'], dataTypesSuffixs[0]['suffix']]
}
}
searchColumn = Object.assign(searchColumn, {
prop: [`Q^${field.name}^${querySuffix[0]}`, `Q^${field.name}^${querySuffix[1]}`],
modelValue: `Q^${field.name}^${querySuffix[0]}`,
fieldType: 'numberRange',
fieldOptions: fieldOptions
})
} else if (fieldType === 'radio' || fieldType === 'checkbox' || fieldType === 'select') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = fieldType !== 'checkbox' && !fieldOptions.multiple ? 'S' : 'SL'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
modelValue: `Q^${field.name}^${querySuffix}`,
fieldType: fieldType,
fieldOptions: fieldOptions,
multiple: fieldOptions.multiple || fieldType === 'checkbox' || false,
options: this.buildOptions(fieldOptions && fieldOptions.options ? fieldOptions.options : [])
})
this.setOptionsInField(searchColumn, fieldOptions)
} else if (fieldType === 'switch') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'S'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
fieldType: 'select',
fieldOptions: fieldOptions,
options: this.buildSwitchOptions(fieldOptions)
})
} else if (fieldType === 'date') { // 日期
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'D'
}
const datefmt = fieldOptions.datefmt || ''
const prop = `Q^${field.name}^${querySuffix}^${datefmt}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
fieldType: 'date',
fieldOptions: fieldOptions,
dateType: fieldOptions.datefmt_type ? fieldOptions.datefmt_type : 'date'
})
} else if (fieldType === 'datePicker' || fieldType.toLowerCase() === 'daterange') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'D'
}
const suffix = typeof querySuffix === 'object' && this.$utils.isNotEmpty(querySuffix) ? querySuffix : ['DL', 'DG']
// const options = this.filterPickerOptions(field)
// const pickerOptions = options.scopeData
// const value = options.operationScriptDate
const datefmt = fieldOptions.datefmt || ''
const dateDealFmt = DateFormatUtil.dealFmt(fieldOptions.datefmt)
const props = [`Q^${field.name}^${suffix[0]}^${datefmt}`, `Q^${field.name}^${suffix[1]}^${datefmt}`]
searchColumn = Object.assign(searchColumn, {
hasSame: same || false,
datefmt: '^' + datefmt,
prop: props,
modelValue: `Q^${field.name}^${querySuffix}^${datefmt}`,
fieldType: fieldType === 'datePicker' ? dateDealFmt.dateType : dateDealFmt.dateType + 'range',
fieldOptions: fieldOptions
// pickerOptions: pickerOptions || {}
})
} else if (fieldType === 'dictionary') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = fieldOptions.multiple ? 'SL' : 'S'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
slotName: prop + 'searchForm',
fieldType: fieldType,
placeholder: fieldOptions.placeholder,
multiple: fieldOptions.multiple || false,
fieldOptions: fieldOptions
})
} else if (fieldType === 'selector') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'SL'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
slotName: prop + 'searchForm',
fieldType: fieldType,
modelValue: prop,
multiple: fieldOptions.multiple || false,
selectorType: fieldOptions.selector_type || 'user',
fieldOptions: fieldOptions
})
} else if (fieldType === 'customDialog') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'S'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
slotName: prop + 'searchForm',
fieldType: fieldType,
modelValue: prop,
fieldOptions: fieldOptions
})
} else if (fieldType === 'linkdata') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'S'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
slotName: prop + 'searchForm',
fieldType: fieldType,
modelValue: prop,
fieldOptions: fieldOptions
})
} else if (fieldType === 'address') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'SL'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
slotName: prop + 'searchForm',
modelValue: prop,
fieldType: fieldType,
fieldOptions: fieldOptions
})
} else if (fieldType === 'number') {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'SIN'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
modelValue: prop,
fieldType: fieldType,
field_options: fieldOptions,
dateType: field.dataType
})
} else {
if (this.$utils.isEmpty(querySuffix)) {
querySuffix = 'SL'
}
const prop = `Q^${field.name}^${querySuffix}`
searchColumn = Object.assign(searchColumn, {
prop: prop,
modelValue: prop,
slotName: prop + 'searchForm',
fieldOptions: fieldOptions
})
}
}
return searchColumn
},
buildSwitchOptions(fieldOptions) {
return FormUtils.getSwitchOptions(fieldOptions, 'value')
},
changeQuery(val, data) {
this.queryName = data['label']
this.fieldType = data['fieldType']
this.search = ''
},
/**
* 初始化脚本
*/
initJTemplate() {
const id = 'JTemplate'
let el = document.getElementById(id)
if (el) {
el.parentNode.removeChild(el)
}
if (this.dataTemplate.attrs && this.dataTemplate.attrs.mobile_script) {
const code = this.dataTemplate.attrs.mobile_script
el = document.createElement('script')
el.type = 'text/javascript'
el.id = id
document.body.appendChild(el)
try {
el.appendChild(document.createTextNode(code))
} catch (ex) {
el.text = code
}
document.body.appendChild(el)
}
},
// 前置脚本
beforeScript(action, position, selection, data, callback) {
if (!this.hasScript) {
const flag = true
callback(flag)
return
}
// JTemplate._beforeSubmit(this, action, position, selection, data, callback)
eventsUtil._eventCall(this.eventsUtil, 'beforeSubmit', this, action, position, selection, data, callback)
},
// 后置脚本
afterScript(action, position, selection, data, callback) {
if (!this.hasScript) {
const flag = true
callback(flag)
return
}
// JTemplate._afterSubmit(this, action, position, selection, data, callback)
eventsUtil._eventCall(this.eventsUtil, 'afterSubmit', this, action, position, selection, data, callback)
}
}
}
</script>
<style lang="scss">
.data-template-list {
.data-template-list-search-wrapper{
padding:10px 0;
background-color: #fff;
.data-template-list-search{
display: flex;
align-items: center;
height: 34px;
.van-cell{
padding: 5px 8px 5px 0;
background-color: transparent;
}
.data-template-list-search__select{
width: 120px;
.van-cell{
.van-field__label{
padding-left: 10px;
margin-right: 5px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
.data-template-list-search__content{
// padding-left: 12px;
background-color: #f7f8fa;
border-radius: 2px;
flex: 1;
}
.data-template-list-search__icon{
width: 24px;
}
}
}
.options-null{
bottom: -9px !important;
}
.palette-button {
position: fixed;
right: 30px;
bottom: 30px;
z-index: 500;
}
.titles{
font-weight: 600;
font-size: 16px;
display: block;
}
.desc{
font-size: 14px;
line-height: 22px;
}
.active {
color: #4688f9;
}
.disactive {
color: #666;
}
.menus{
.van-dropdown-menu__bar{
height: 40px;
background-color: #f1f4f8;
}
.van-dropdown-menu__item--disabled{
justify-content: end;
margin: 0 7px;
}
.van-dropdown-menu__item--disabled + .van-dropdown-menu__item{
justify-content: flex-end;
margin: 0 20px;
}
.menu-slot-right{
color: #3388FF;
}
}
}
.van-dropdown-menu__item--disabled{
.van-dropdown-menu__title::after{
border:0
}
}
</style>
1、编写配置
1)混入对象的导入
对应代码
import CustomDataDisplayMixin from '@/business/platform/system/mixins/customDataDisplay'
CustomDataDisplayMixin
2)显示字段渲染修改
将多选绑定的name从item.name修改为item.prop
3)listIdentity以及是否显示保存成功提示
listIdentity:用于请求时传递的标识性参数,可根据自身需求重新编写
hasMessage:判断是否显示保存成功的提示
listIdentity() {
return 'ibps_data_template_tpl' + '_' + this.dataTemplate.key
},
hasMessage() {
return true
},
2、默认选择前4个字段进行显示
将之前的val.label换成val.name
// 默认显示字段列表
initOptions(list) {
list.forEach((val, index) => {
if (this.configKey === '') {
if (index < 4) {
this.chooseResult.push(val.name)
}
}
})
},
3、获取显示字段
代码:
async buildKey(dataTemplate, template) {
this.idKey = dataTemplate['unique']
this.templateKey = dataTemplate['key']
this.formKey = dataTemplate.attrs ? dataTemplate.attrs.form_key || '' : ''
this.detailFormKey = dataTemplate.attrs ? dataTemplate.attrs.detail_form_key || '' : ''
this.buildQuerycolumns(template['query_columns'])
const fieldsList = template['display_columns'] ? template['display_columns'] : []
if (this.$utils.isNotEmpty(fieldsList)) {
const displayFields = fieldsList.filter(i => i.field_type !== 'hidden')
this.fieldsList = displayFields.map(i => {
return {
name: i.label,
prop: i.name
}
})
} else {
this.$toast('显示字段不能为空!请在PC端中配置。')
}
this.initOptions(fieldsList)
const colums = []
// const chooseResult = storage.get('chooseFields')
// if (chooseResult !== undefined) {
// this.chooseResult = chooseResult
// }
await this.getCustomDataDisplay(
this.listIdentity
).then((data) => {
if (this.$utils.isNotEmpty(data)) {
this.chooseResult = data.map(el => {
return el.prop
})
}
})
for (let i = 0; i < this.chooseResult.length; i++) {
for (let l = 0; l < fieldsList.length; l++) {
if (this.chooseResult[i] === fieldsList[l].name) {
colums.push(fieldsList[l])
}
}
}
const displayColumns = colums
const filterActions = this.$utils.isNotEmpty(template['filter_conditions']) ? template['filter_conditions'] : []
if (this.$utils.isNotEmpty(filterActions)) {
this.rangeData[this.rootIndex].options = filterActions.map(i => {
return { text: i.label, value: i.key }
})
}
this.initFilter(filterActions, this.rootIndex)
if (dataTemplate.showType === 'tree') {
this.isTree = true
if (this.$utils.isNotEmpty(displayColumns)) {
this.labelField = displayColumns['name_key']
this.idKey = displayColumns['id_key']
this.parentIdKey = displayColumns['pid_key']
}
} else if (dataTemplate.showType === 'list') {
this.isTree = false
if (this.$utils.isNotEmpty(displayColumns)) {
// 显示字段顺序预处理
const arr = []
for (var i = 0; i < displayColumns.length; i++) {
for (var l = 0; l < fieldsList.length; l++) {
if (displayColumns[i].label === fieldsList[l].label) {
arr[l] = fieldsList[l]
}
}
}
const columns = arr.filter(e => {
if (e !== '' && e !== undefined) {
return e
}
})
this.labelField = columns[0] || {}
this.descFields = columns.filter((e, i) => {
return i > 0
})
}
const button = template['buttons'] || {}
const editButtons = button['edit_buttons'] || []
this.cacheEditButtons = this.editButtons = editButtons
let functionButtons = button['function_buttons'] || []
// TODO:目前版本不支持按钮 ,'print', 'import', 'export', 'sefStartFlow',
const allowButtons = ['add', 'remove', 'edit', 'detail', 'custom', 'sefStartFlow']
functionButtons = functionButtons.filter((b) => {
if (allowButtons.includes(b.button_type)) {
return b
}
})
this.functionButtons = functionButtons
this.initToolbarAction()
}
},
4、将选择的字段保存在后端
原先是将显示字段保存在本地:storage.set(‘chooseFields’, this.chooseResult)
现将显示字段通过请求保存在后端:
onDisplayConfirm() {
if (this.$utils.isEmpty(this.chooseResult) || this.chooseResult.length === 0) {
this.$toast('显示字段至少选择一项!')
return
}
ActionUtils.initListData(this)
this.checkedIds = []
this.loadDataTemplate(this.templateId)
// storage.set('chooseFields', this.chooseResult)
const _data = []
this.fieldsList.forEach(el => {
if (this.chooseResult.includes(el.prop)) {
_data.push(el)
}
})
this.saveCustomDataDisplay(_data, this.listIdentity).then((response) => {
if (this.hasMessage) ActionUtils.success(response.message)
this.display = false
}).catch(() => {
this.display = false
})
},
2、customDataDisplay(列表混入对象)
目录:src\business\platform\system\mixins\customDataDisplay.js
注意:需在对应位置保存有以下代码,以下代码是用于在template-list中对应操作调用来对显示字段向后端进行保存或获取,也可保存在其他位置上,但是在template-list中必须对对应代码进行修改。
/**
* 自定义展示数据
*/
import { getIdentityTypeAccount, save, reset } from '@/api/platform/system/customDataDisplay'
export default {
methods: {
getCustomDataDisplay(identity, type = 'display', account) {
if (!account) {
account = this.$store.getters.account
}
return new Promise((resolve, reject) => {
getIdentityTypeAccount({
identity: identity,
account: account,
type: type
}).then(response => {
const data = response.data
if (this.$utils.isNotEmpty(data)) {
resolve(JSON.parse(data.scheme))
} else {
resolve([])
}
}).catch((err) => {
reject(err)
})
})
},
saveCustomDataDisplay(scheme, identity, type = 'display', account) {
if (!account) {
account = this.$store.getters.account
}
const customDataDisplay = {
'account': account,
'identity': identity,
'type': type
}
return new Promise((resolve, reject) => {
if (this.$utils.isNotEmpty(scheme)) {
customDataDisplay['scheme'] = JSON.stringify(scheme)
save(customDataDisplay).then(response => {
resolve(response)
}).catch((err) => {
reject(err)
})
} else {
reset(customDataDisplay).then(response => {
resolve(response)
}).catch((err) => {
reject(err)
})
}
})
}
}
}
在template-list中调用的位置如图:
3、customDataDisplay(显示字段请求Api)
目录:src\api\platform\system\customDataDisplay.js
注意:
1、需在对应位置保存有以下代码,以下代码是用于在第二点customDataDisplay(列表混入对象)中对应操作调用,也可保存在其他位置上,但是在customDataDisplay(列表混入对象)中必须对对应代码进行修改。
2、API是参照PC端自定义列的请求API复制选用的,可根据自身需求另写API后对该文件对应的请求方法进行修改。
import request from '@/utils/request'
import { SYSTEM_URL } from '@/api/baseUrl'
/**
* 根据数据标识、数据类型及用户账号查询
* @param {*} params
*/
export function getIdentityTypeAccount(params) {
return request({
url: SYSTEM_URL() + '/system/custom/data/display/scheme/get/identity/type/account',
method: 'post',
data: params
})
}
/**
* 保存数据
* @param {*} params
*/
export function save(params) {
return request({
url: SYSTEM_URL() + '/system/custom/data/display/scheme/save',
method: 'post',
isLoading: true,
data: params
})
}
/**
* 恢复默认数据
* @param {*} params
*/
export function reset(params) {
return request({
url: SYSTEM_URL() + '/system/custom/data/display/scheme/reset',
method: 'post',
isLoading: true,
data: params
})
}
在customDataDisplay(列表混入对象)中调用的位置如图: