You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

744 lines
21 KiB

<template>
<view class="dynamicModel-list-v">
<view class="head-warp com-dropdown">
<u-dropdown class="u-dropdown" ref="uDropdown">
<u-dropdown-item title="排序" :options="sortOptions">
<view class="dropdown-slot-content">
<view class="dropdown-slot-content-main">
<scroll-view scroll-y="true" style="height: 1000rpx;">
<view class="u-p-l-20 u-p-r-20" v-if="sortOptions.length">
<u-cell-group :border="false">
<u-cell-item @click="cellClick(item)" :arrow="false" :title="item.label"
v-for="(item, index) in sortOptions" :key="index" :title-style="{
color: sortValue == item.value ? '#2979ff' : '#606266' }">
<u-icon v-if="sortValue == item.value" name="checkbox-mark" color="#2979ff"
size="32"></u-icon>
</u-cell-item>
</u-cell-group>
</view>
<view v-else class="notData-box u-flex-col">
<view class="u-flex-col notData-inner">
<image :src="icon" class="iconImg"></image>
<text class="notData-inner-text">暂无数据</text>
</view>
</view>
</scroll-view>
</view>
<view class="dropdown-slot-bg" @click="$refs.uDropdown.close()"></view>
</view>
</u-dropdown-item>
<u-dropdown-item title="筛选">
<view class="screen-box">
<view class="screen-list" v-if="showParser && searchFormConf.length">
<view class="u-p-l-20 u-p-r-20 list">
<Parser :formConf="searchFormConf" :searchFormData="searchFormData" ref="searchForm"
@submit="sumbitSearchForm" :webType="config.webType" />
</view>
</view>
<view v-else class="notData-box u-flex-col">
<view class="u-flex-col notData-inner">
<image :src="icon" class="iconImg"></image>
<text class="notData-inner-text">暂无数据</text>
</view>
</view>
<view class="buttom-actions" v-if="showParser && searchFormConf.length" style="z-index: 1;">
<u-button class="buttom-btn" @click="reset">重置</u-button>
<u-button class="buttom-btn" type="primary" @click="closeDropdown">检索</u-button>
</view>
</view>
</u-dropdown-item>
</u-dropdown>
</view>
<view class="list-warp">
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption"
top="80">
<view class="list u-p-b-20 u-p-l-20 u-p-r-20" ref="tableRef">
<view class="list-box">
<uni-swipe-action ref="swipeAction">
<uni-swipe-action-item v-for="(item, index) in list" :key="item.id" :threshold="0"
:right-options="options">
<view class="item" @click="goDetail(item)">
<view class="u-line-1 item-cell" v-for="(column,i) in columnList" :key="i">
<view v-if="column.jnpfKey != 'table'">
<view class="" v-if="column.jnpfKey == 'relationForm'">
<text class="listTit u-line-1">{{column.label}}:</text>
<text class="listContent" @click.stop="relationFormClick(item,column)"
style="color: blue;">{{item[column.prop]}}</text>
</view>
<view v-else class="u-line-1">
<text class="listTit u-line-1">{{column.label}}:</text>
<text class="listContent"
v-if="['calculate','inputNumber'].includes(column.jnpfKey)">{{toThousands(item[column.prop],column)}}</text>
<text class="listContent" v-else>{{item[column.prop]}}</text>
</view>
</view>
<view class="collapse-box u-flex" v-else>
<tableCell :label="column.label" :childList="item[column.prop]||[]"
:children="column.children" ref="tableCell" :pageLen="3"
@cRelationForm="relationFormClick"></tableCell>
</view>
</view>
<view class="item-cell" v-if="config.enableFlow==1">
<text class="listTit">审批状态:</text>
<text :class="getFlowStatus(item.flowState).statusCss">
{{getFlowStatus(item.flowState).text}}
</text>
</view>
</view>
<template v-slot:right>
<view class="right-option-box">
<view class="right-option more-option"
v-if="columnData.customBtnsList&&columnData.customBtnsList.length"
@click="handleMoreClick(index)">
<text>更多</text>
<uni-icons type="arrowdown" color="#fff" size="16" />
</view>
<view class="right-option" v-for="(it,i) in options" @click="handleClick(index)"
:key="i" v-if="config.webType != 4">
<text>{{it.text}}</text>
</view>
</view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</view>
</mescroll-uni>
</view>
<view class="" v-if="config.webType !=4">
<view class="com-addBtn"
v-if="isPreview||(jurisdictionObj.btnAllow && jurisdictionObj.btnAllow.includes('btn_add'))"
@click="addPage()">
<u-icon name="plus" size="60" color="#fff" />
</view>
</view>
<u-select :list="columnData.customBtnsList" v-model="showMoreBtn" @confirm="selectBtnconfirm" />
<u-picker mode="selector" v-model="show" :default-selector="[0]" title="请选择流程" :range="selector"
range-key="fullName" @confirm="confirm"></u-picker>
</view>
</template>
<script>
import tableCell from '../tableCell.vue'
import resources from '@/libs/resources.js'
import handleJurisdiction from '@/libs/permission.js'
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
import Parser from '../parser/index.vue'
import {
getModelList,
deteleModel,
getModelInfo
} from '@/api/apply/visualDev'
import {
FlowJsonList
} from '@/api/workFlow/flowEngine'
import {
getDataInterfaceRes
} from '@/api/common'
const useDateList = ['datePicker', 'createTime', 'modifyTime']
const useArrList = ['cascader', 'areaSelect', 'inputNumber', 'calculate', ...useDateList]
export default {
mixins: [MescrollMixin],
props: ['config', 'modelId', 'isPreview', 'title', 'menuId'],
components: {
Parser,
tableCell
},
data() {
return {
selector: [],
show: false,
activeFlow: {},
templateList: [],
sortValue: '',
icon: resources.message.nodata,
upOption: {
page: {
num: 0,
size: 10,
time: null
},
empty: {
icon: resources.message.nodata,
tip: "暂无数据",
top: "300rpx"
},
textNoMore: '没有更多数据',
toTop: {
bottom: 250
}
},
list: [],
listQuery: {
sort: 'desc',
sidx: '',
keyword: '',
queryJson: ''
},
options: [{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}],
showParser: false,
columnData: {},
columnList: [],
sortOptions: [],
searchList: [],
searchFormConf: [],
jurisdictionObj: {},
selectListIndex: 0,
showMoreBtn: false,
properties: {},
flowId: '',
key: +new Date(),
userInfo: {},
searchFormData: {},
}
},
created() {
this.init()
if (this.config.enableFlow == 1) {
this.getJsonList()
}
},
updated() {
uni.$once('refresh', () => {
this.list = [];
this.mescroll.resetUpScroll();
})
},
methods: {
toThousands(val, column) {
if (val || val == 0) {
let valList = val.toString().split('.')
let num = Number(valList[0])
let newVal = column.thousands ? num.toLocaleString() : num
return valList[1] ? newVal + '.' + valList[1] : newVal
}
},
getJsonList() {
FlowJsonList(this.config.flowId, '1').then(res => {
this.templateList = res.data;
this.selector = this.templateList
})
},
relationFormClick(item, column) {
let vModel = column.vModel ? column.vModel : column.__vModel__
let model_id = column.modelId
const idText = '&id=' + item[vModel + '_id']
let config = {
modelId: model_id,
isPreview: true,
id: item[vModel + '_id'],
isRelationForm: 1
}
const url =
'/pages/apply/dynamicModel/detail?config=' + this.base64.encode(JSON.stringify(
config),
"UTF-8")
uni.navigateTo({
url: url
})
},
init() {
this.userInfo = uni.getStorageSync('userInfo') || {}
this.properties = JSON.parse(this.config.flowTemplateJson) ? JSON.parse(this.config.flowTemplateJson)
.properties : {}
this.permissionList = uni.getStorageSync('permissionList')
let columnData = this.config.appColumnData && this.config.appColumnData != null ? this.config
.appColumnData : this.config.columnData && this.config.columnData != null ? this.config.columnData : []
this.columnData = JSON.parse(columnData)
this.jurisdictionObj = handleJurisdiction.inserted(this.columnData, this.permissionList, this.menuId)
this.upOption.page.size = this.columnData.hasPage ? this.columnData.pageSize : 1000000
this.setDefaultQuery()
this.columnList = this.jurisdictionObj.columnAllow || []
this.columnData.customBtnsList = this.jurisdictionObj.customBtnsList || []
if (!this.columnList.length) { //app无配置列表字段默认使用pc配置
let pcColumnData = this.config.columnData || []
let data = handleJurisdiction.inserted(JSON.parse(pcColumnData), this.permissionList, this
.menuId)
this.columnList = data.columnAllow || []
}
this.columnList = this.transformColumnList(this.columnList)
this.columnList.map((o) => {
if (o.jnpfKey != 'table' && o.label.length > 4) {
o.label = o.label.substring(0, 4)
}
})
this.searchList = this.columnData.searchList || []
for (const item of this.searchList) {
const {
__config__,
id,
value,
label
} = item;
if (value != null && value != '' && value != []) {
this.searchFormData[id] = value;
}
if (this.config.webType === 4) {
__config__.label = label;
}
}
if (Object.keys(this.searchFormData).length > 0) {
this.listQuery.queryJson = JSON.stringify(this.searchFormData)
}
this.searchFormConf = JSON.parse(JSON.stringify(this.searchList))
const sortList = this.columnData.sortList || []
let sortOptions = [];
this.sortOptions = sortList.flatMap(item => [{
label: `${item.label}升序`,
value: `${item.prop}asc`,
sidx: item.prop,
sort: 'asc'
},
{
label: `${item.label}降序`,
value: `${item.prop}desc`,
sidx: item.prop,
sort: 'desc'
}
]);
this.key = +new Date()
},
transformColumnList(columnList) {
let list = []
for (let i = 0; i < columnList.length; i++) {
const e = columnList[i];
if (!e.prop.includes('-')) {
e.option = null
list.push(e)
} else {
let prop = e.prop.split('-')[0]
let vModel = e.prop.split('-')[1]
let label = e.label.split('-')[0]
let childLabel = e.label.replace(label + '-', '');
let newItem = {
align: "center",
jnpfKey: "table",
prop,
label,
children: []
}
e.vModel = vModel
e.childLabel = childLabel
if (!list.some(o => o.prop === prop)) list.push(newItem)
for (let i = 0; i < list.length; i++) {
if (list[i].prop === prop) {
e.option = null
list[i].children.push(e)
break
}
}
}
}
return list
},
setDefaultQuery() {
this.listQuery.sort = this.columnData.sort
this.listQuery.sidx = this.columnData.defaultSidx
},
upCallback(page) {
if (this.isPreview == '1' || !this.columnList.length) return this.mescroll.endSuccess(0, false);
const query = {
currentPage: page.num,
pageSize: page.size,
menuId: this.menuId,
...this.listQuery
}
getModelList(this.modelId, query, {
load: page.num == 1
}).then(res => {
this.showParser = true
if (page.num == 1) this.list = [];
this.mescroll.endSuccess(res.data.list.length);
const list = res.data.list.map((o, i) => ({
show: false,
index: i,
...o
}));
this.list = this.list.concat(list);
this.$nextTick(() => {
if (this.columnData.funcs && this.columnData.funcs.afterOnload) this
.setTableLoadFunc()
})
uni.$off('refresh')
}).catch((err) => {
this.mescroll.endByPage(0, 0);
this.mescroll.endErr();
uni.$off('refresh')
})
},
setTableLoadFunc() {
const JNPFTable = this.$refs.tableRef
const parameter = {
data: this.list,
tableRef: JNPFTable,
onlineUtils: this.jnpf.onlineUtils,
}
const func = this.jnpf.getScriptFunc.call(this, this.columnData.funcs.afterOnload)
if (!func) return
func.call(this, parameter)
},
handleClick(index) {
const item = this.list[index]
let txt = item.flowState == 2 ? '通过' : item.flowState == 3 ? '退回' : item.flowState == 5 ? '终止' : '提交'
if (this.config.enableFlow == 1 && [1, 2, 3, 5].includes(item.flowState)) {
this.$u.toast(`该流程已${txt},无法删除`)
this.list[index].show = false
return
}
if (!this.jurisdictionObj.btnAllow.includes('btn_remove')) return this.$u.toast("未开启删除权限")
deteleModel(this.modelId, item.id).then(res => {
this.$u.toast(res.msg)
this.list.splice(index, 1)
this.mescroll.resetUpScroll()
})
},
handleMoreClick(index) {
this.selectListIndex = index
this.showMoreBtn = true
},
selectBtnconfirm(e) {
var i = this.columnData.customBtnsList.findIndex((item) => {
return item.value == e[0].value
})
const item = this.columnData.customBtnsList[i]
const row = this.list[this.selectListIndex]
const index = this.selectListIndex
if (item.event.btnType == 1) this.handlePopup(item.event, row, index)
if (item.event.btnType == 2) this.handleScriptFunc(item.event, row, index)
if (item.event.btnType == 3) this.handleInterface(item.event, row, index)
},
handlePopup(item, row, index) {
let data = {
config: item,
modelId: this.modelId,
id: this.config.webType == 4 ? '' : row.id,
isPreview: this.isPreview,
row: this.config.webType == 4 ? row : '',
}
data = encodeURIComponent(JSON.stringify(data))
uni.navigateTo({
url: '/pages/apply/JNPFCustom/index?data=' + data
})
},
handleScriptFunc(item, row, index) {
const parameter = {
data: row,
index,
refresh: this.initData,
onlineUtils: this.jnpf.onlineUtils,
}
const func = this.jnpf.getScriptFunc.call(this, item.func)
if (!func) return
func.call(this, parameter)
},
handleInterface(item, row) {
const handlerData = () => {
getModelInfo(this.modelId, row.id).then(res => {
const dataForm = res.data || {};
if (!dataForm.data) return;
const data = {
...JSON.parse(dataForm.data),
id: row.id
};
handlerInterface(data);
})
}
const handlerInterface = data => {
if (item.templateJson && item.templateJson.length) {
item.templateJson.forEach(e => {
e.defaultValue = e.sourceType == 1 ? data[e.relationField] || '' : e
.relationField;
});
}
const query = {
paramList: item.templateJson || []
};
getDataInterfaceRes(item.interfaceId, query).then(res => {
uni.showToast({
title: res.msg,
icon: 'none'
})
});
};
const handleFun = () => {
this.config.webType == '4' ? handlerInterface(row) : handlerData();
};
if (!item.useConfirm) return handleFun();
uni.showModal({
title: '提示',
content: item.confirmTitle || '确认执行此操作',
success: (res) => {
if (res.cancel) return
handleFun()
}
})
},
initData() {
this.list = [];
this.mescroll.resetUpScroll();
},
open(index) {
this.list[index].show = true;
this.list.map((val, idx) => {
if (index != idx) this.list[idx].show = false;
})
},
search() {
if (this.isPreview == '1') return
this.searchTimer && clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.list = [];
this.mescroll.resetUpScroll();
}, 300)
},
addPage() {
if (this.config.enableFlow != 1) return this.jumPage({}, '')
if (!this.templateList.length) return this.$u.toast('流程不存在')
if (this.templateList.length > 1) {
this.show = true
} else {
this.activeFlow = this.templateList[0]
this.jumPage({}, '')
}
},
confirm(e) {
this.activeFlow = this.templateList[e[0]]
this.jumPage({}, '')
},
jumPage(item, btnType) {
if (!item.id && !item.flowState) btnType = 'btn_add'
let formTitle = ''
if (this.config.enableFlow == 1) {
let flowBtnType = btnType === 'btn_detail' ? 'btn_add' : btnType
let opType = '-1'
if ([1, 2, 4, 5].includes(item.flowState)) opType = 0
const rowFlowId = item.flowId || this.templateList[0].id
const config = {
id: item.id || '',
enCode: this.config.flowEnCode,
flowId: item.id ? rowFlowId : this.activeFlow.id,
formType: 2,
type: 1,
opType,
status: item.flowState || '',
isPreview: this.isPreview,
fullName: item.id ? '编辑' : '新增',
jurisdictionType: flowBtnType || '',
properties: this.properties,
enableFlow: this.config.enableFlow
}
uni.navigateTo({
url: '/pages/workFlow/flowBefore/index?config=' + this.base64.encode(
JSON.stringify(config), "UTF-8")
})
} else {
const type = btnType == 'btn_detail' ? 'detail' : 'form'
const currentMenu = encodeURIComponent(JSON.stringify(this.jurisdictionObj.formAllow))
let hasEdit = this.jurisdictionObj.btnAllow.includes('btn_edit') ? 'btn_edit' : 'btn_add'
const config = {
currentMenu,
jurisdictionType: hasEdit,
list: this.list,
modelId: this.modelId,
isPreview: this.isPreview,
id: item.id ? item.id : '',
index: item.index
}
const url = '/pages/apply/dynamicModel/' + type + '?config=' + this.base64.encode(JSON.stringify(
config), "UTF-8")
uni.navigateTo({
url: url
})
}
},
goDetail(item) {
if (this.config.webType == 4) return
let hasDetail = this.jurisdictionObj.btnAllow.includes('btn_detail')
let hasEdit = this.jurisdictionObj.btnAllow.includes('btn_edit')
if (!hasDetail && !hasEdit) return
let btnType = hasDetail ? 'btn_detail' : 'btn_edit'
this.jumPage(item, btnType)
},
getFlowStatus(val) {
let status
switch (val) {
case 0:
status = {
text: '等待提交',
statusCss: 'u-type-info'
}
break;
case 1:
status = {
text: '等待审核',
statusCss: 'u-type-primary'
}
break;
case 2:
status = {
text: '审核通过',
statusCss: 'u-type-success'
}
break;
case 3:
status = {
text: '审核退回',
statusCss: 'u-type-error'
}
break;
case 4:
status = {
text: '流程撤回',
statusCss: 'u-type-warning'
}
break;
case 5:
status = {
text: '审核终止',
statusCss: 'u-type-info'
}
break;
default:
status = {
text: '等待提交',
statusCss: 'u-type-info'
}
break;
}
return status
},
cellClick(item) {
if (this.sortValue === item.value) return
this.listQuery.sort = item.sort
this.listQuery.sidx = item.sidx
this.sortValue = item.value
this.$refs.uDropdown.close();
if (this.isPreview == '1') return
this.$nextTick(() => {
this.list = [];
this.mescroll.resetUpScroll();
})
},
reset() {
this.showParser = false
this.searchFormData = {}
this.searchFormConf = JSON.parse(JSON.stringify(this.searchList))
this.$nextTick(() => {
this.showParser = true
})
},
closeDropdown() {
if (this.isPreview == '1') {
uni.showToast({
title: '功能预览不支持检索',
icon: 'none'
})
return
}
this.$refs.searchForm && this.$refs.searchForm.submitForm()
},
fillFormData(list, data) {
for (let i = 0; i < list.length; i++) {
let item = list[i]
}
},
sumbitSearchForm(data) {
const queryJson = data || {}
this.searchFormData = data
this.fillFormData(this.searchFormConf, data)
this.listQuery.queryJson = JSON.stringify(queryJson) !== '{}' ? JSON.stringify(queryJson) : ''
this.$refs.uDropdown.close();
this.$nextTick(() => {
this.list = [];
this.mescroll.resetUpScroll();
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #f0f2f6;
height: 100%;
/* #ifdef MP-ALIPAY */
position: absolute;
top: 0;
left: 0;
width: 100%;
/* #endif */
}
/deep/.u-cell {
padding: 0rpx;
height: 112rpx;
}
.screen-box {
background-color: #fff;
height: 100%;
.screen-list {
width: 100%;
height: 100%;
.list {
height: calc(100% - 88rpx);
overflow-y: scroll;
}
}
}
.item {
padding: 0 !important;
}
.notData-box {
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
padding-bottom: 200rpx;
.notData-inner {
width: 280rpx;
height: 308rpx;
align-items: center;
.iconImg {
width: 100%;
height: 100%;
}
.notData-inner-text {
padding: 30rpx 0;
color: #909399;
}
}
}
.right-option-box {
display: flex;
width: max-content;
.right-option {
width: 144rpx;
height: 100%;
font-size: 16px;
color: #fff;
background-color: #dd524d;
display: flex;
align-items: center;
justify-content: center;
}
.more-option {
background-color: #1890ff;
}
}
</style>