Files
jnpf_app/pages/apply/dynamicModelList/components/list/index.vue

1053 lines
33 KiB
Vue
Raw Normal View History

2026-01-19 17:34:15 +08:00
<template>
<view class="dynamicModel-list-v">
<!-- 批量删除顶部弹窗 -->
<view class="u-flex top-btn" :class="slide2" v-show="selectItems.length">
<view class="button-left" @click.stop="cancel">
<p class="u-m-t-10 u-font-28">{{$t('common.cancelText')}}</p>
</view>
<view class="button-center">
<p class="u-m-t-10 u-font-28">{{$t('component.jnpf.common.selected')}}({{selectItems.length}})</p>
</view>
<view class="button-right u-m-t-12" @click.stop="checkAll">
<p class="icon-ym icon-ym-app-checkAll " :style="{'color':this.checkedAll ? '#0293fc' : '#303133'}">
</p>
</view>
</view>
<!-- 排序 -->
<view class="head-warp com-dropdown">
<u-dropdown class="u-dropdown" ref="uDropdown" @open="showTop = true" @close="showTop = false">
<u-dropdown-item :title="$t('app.apply.sort')" :options="sortOptions">
<view class="screen-box">
<view class="screen-list" v-if="sortOptions.length">
<view class="u-p-l-20 u-p-r-20 list">
<scroll-view scroll-y="true" style="height: 100%;">
<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.includes(item.value) ? '#2979ff' : '#606266' }">
<u-icon v-if="sortValue.includes(item.value)" name="checkbox-mark"
color="#2979ff" size="32" />
</u-cell-item>
</u-cell-group>
</scroll-view>
</view>
</view>
<JnpfEmpty v-else></JnpfEmpty>
<view class="buttom-actions" v-if="sortOptions.length">
<u-button class="buttom-btn" @click="handleSortReset">{{$t('common.cleanText')}}</u-button>
<u-button class="buttom-btn" type="primary" @click="handleSortSearch">
{{$t('common.okText')}}
</u-button>
</view>
</view>
</u-dropdown-item>
<!-- 筛选 -->
<u-dropdown-item :title="$t('app.apply.screen')">
<view class="screen-box u-flex-col">
<view class="screen-list" v-if="showParser && searchFormConf.length">
<view class="u-p-l-20 u-p-r-20 list">
<scroll-view scroll-y="true" style="height: 100%;">
<Parser :formConf="searchFormConf" :searchFormData="searchFormData"
:webType="config.webType" ref="searchForm" @submit="sumbitSearchForm" />
</scroll-view>
</view>
<view class="u-flex screen-btn" v-if="showParser && searchFormConf.length">
<text @click="handleReset" class="btn btn1">{{$t('common.resetText')}}</text>
<text @click="handleSearch" class="btn btn2">{{$t('common.searchText')}}</text>
</view>
</view>
<JnpfEmpty v-else></JnpfEmpty>
</view>
</u-dropdown-item>
</u-dropdown>
</view>
<view class="u-m-b-20">
<u-tabs :list="tabList" v-model="tabActiveKey" font-size="28" @change="onTabChange" height="80"
name="fullName" v-show="showTabs">
</u-tabs>
</view>
<!-- 列表 -->
<view class="list-warp">
<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
:down="downOption" :up="upOption" :bottombar="false"
:top="(columnData.tabConfig && columnData.tabConfig.on && tabList.length) ? 190 : 100">
<list ref="list" :list="list" :columnList="columnList" :config="config" :actionOptions="actionOptions"
@relationFormClick="relationFormClick" @goDetail="goDetail" @handleMoreClick="handleMoreClick"
@handleClick="handleClick" :showSelect="isShowBatch.length" :checkedAll="checkedAll"
@selectCheckbox="selectCheckbox" :isMoreBtn="isMoreBtn" :customBtnsList="columnData.customBtnsList">
</list>
</mescroll-uni>
</view>
<view v-if="!showTop">
<!-- 新增按钮 -->
<view>
<view class="com-addBtn" @click="addPage()">
<u-icon name="plus" size="48" color="#fff" />
</view>
</view>
</view>
<u-select :list="listInnerBtn" v-model="showMoreBtn" @confirm="selectBtnconfirm" />
<u-select :list="bottomCustomBtnsList[1]" v-model="showBottomMoreBtn" @confirm="bottomBtnConfirm" />
<!-- 批量操作底部弹窗 -->
<view class="u-flex bottom-btn" :class="isShowBatch?.length==1? 'bottom-btn-one ':'bottom-btn-multiple'"
v-if="(isShowBatch.length && list.length) || (bottomCustomBtnsList && bottomCustomBtnsList[0].length)">
<view class="button-preIcon" @click.stop="handleBottomMoreClick('down')"
v-if="bottomCustomBtnsList[1].length">
<u-icon name="more-dot-fill" class="u-m-b-8" size="34"></u-icon>
<p class="u-font-24">{{$t('common.moreText')}}</p>
</view>
<!-- 自定义按钮 -->
<view class="button-preIcon" v-for="(item,i) in bottomCustomBtnsList[0]" :key="i"
@click="bottomBtnConfirm(item)">
<p class="btn-icon u-m-b-8" :class="item.event.btnIcon">
</p>
<p class="u-m-t-8 u-font-22 u-line-1">{{item.label}}</p>
</view>
<!-- 批量删除 -->
<view class="button-preIcon" @click.stop="batchDelete" v-if="isBatchRemove && list.length">
<p class="icon-ym icon-ym-app-delete u-m-b-8"></p>
<p class="u-m-t-10 u-font-22">{{$t('common.batchDelText')}}</p>
</view>
</view>
</view>
</template>
<script>
import { useBaseStore } from '@/store/modules/base'
const baseStore = useBaseStore()
import list from './list.vue'
import resources from '@/libs/resources.js'
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
import bulkOperationMixin from "../../bulkOperationMixin.js";
import jnpf from "@/utils/jnpf";
import Parser from '../parser/index.vue'
import {
getModelDataList,
getDbfromList,
deteleModel,
getModelInfo,
launchFlow
} from '@/api/apply/visualDev'
import { getDataInterfaceRes } from '@/api/common'
import deepClone from '../../../../../uni_modules/vk-uview-ui/libs/function/deepClone';
import { useDefineSetting } from '@/utils/useDefineSetting';
export default {
mixins: [MescrollMixin, bulkOperationMixin],
props: ['config', 'modelId', 'isPreview', 'title', 'menuId'],
components: {
Parser,
list
},
data() {
return {
selectedSort: {},
tabActiveKey: 0,
tabList: [],
tabQueryJson: {},
sortValue: [],
downOption: {
use: true,
auto: false
},
upOption: {
page: {
num: 0,
size: 10,
time: null
},
empty: {
use: true,
icon: resources.message.nodata,
tip: this.$t('common.noData'),
fixed: true
},
textNoMore: this.$t('app.apply.noMoreData'),
},
list: [],
listQuery: {
sidx: '',
asc: '', // 升序
desc: '', // 降序
queryJson: {}
},
actionOptions: [],
showParser: true, // 强制显示筛选面板
columnData: {},
columnList: [],
sortList: [],
sortOptions: [],
searchList: [], // 初始化空数组
searchFormConf: [],
permission: {},
selectListIndex: 0,
showBottomMoreBtn: false,
showMoreBtn: false,
properties: {},
flowId: '',
key: +new Date(),
userInfo: {},
searchFormData: {},
enableFunc: {},
selectItems: [],
listInnerBtn: [],
listTopBtn: [],
useDefine: useDefineSetting(),
departmentList: [] // 新增:存储接口返回的部门列表
}
},
async created() {
// 1. 先加载部门数据await 确保接口完成后再执行init
await this.loadDepartmentList()
// 2. 强制执行初始化
this.init()
// 3. 强制触发列表加载,确保页面初始化完成
this.$nextTick(() => {
this.mescrollInit()
this.mescroll.resetUpScroll()
})
},
mounted() {
// 兜底mounted阶段再次强制设置mock数据
this.forceSetMockData()
},
computed: {
showTabs() {
return this.columnData?.tabConfig?.on && this.tabList.length
},
bottomCustomBtnsList() {
if (this.listTopBtn.length <= 3) return [this.listTopBtn, []];
const firstArray = this.listTopBtn.slice(0, 3);
const secondArray = this.listTopBtn.slice(3);
return [firstArray, secondArray];
},
getRowKey() {
return this.config.webType == 4 && this.columnData.viewKey ? this.columnData.viewKey : 'id'
},
isMoreBtn() {
return this.columnData?.customBtnsList?.some(item => item.event?.btnType === 2);
},
isShowBatch() {
const list = this.filterEmpty([this.isBatchRemove, ...this.bottomCustomBtnsList])
return list.filter(i => i !== undefined)
},
customBtnsList() {
return this.columnData?.customBtnsList?.some(item => item.event?.btnType === 1);
},
isBatchRemove() {
return this.columnData?.btnsList?.find(item => item.value === "batchRemove" && item.show)
}
},
methods: {
/**
* 加载部门列表改为async/await确保异步逻辑等待完成
*/
async loadDepartmentList() {
console.log(this.modelId,'modelId------')
try {
// 用await等待接口返回解决异步时序问题
const res = await getDbfromList('1964207990401785857');
console.log(res,'res---------111')
if(res.code == 0 && res.data?.records?.length){
this.departmentList = res.data.records.map(item => ({
label: item.full_name,
value: item.id // 如需用名称作为value可改为 item.full_name
}));
}
console.log(this.departmentList,'departmentList----')
// 关键:接口返回后更新筛选配置的部门选项
this.mockSearchListForDepartment();
this.handleSearchList();
} catch (error) {
console.error('加载部门列表失败:', error);
// 接口失败时的兜底数据
this.departmentList = [
{ label: '技术部', value: '技术部' },
{ label: '财务部', value: '财务部' },
{ label: '行政部', value: '行政部' },
{ label: '销售部', value: '销售部' }
];
// 兜底数据也要更新筛选配置
this.mockSearchListForDepartment();
this.handleSearchList();
}
},
/**
* 专门生成带部门列表的筛选配置只更新申请单位项不影响其他筛选项
*/
mockSearchListForDepartment() {
// 先检查是否已有申请单位的筛选项有则更新options无则新增
const depItemIndex = this.searchList.findIndex(item => item.id === 'applyDepId');
if (depItemIndex > -1) {
// 已有则更新options
this.searchList[depItemIndex].options = this.departmentList;
} else {
// 没有则新增申请单位筛选项
this.searchList.push({
id: 'applyDepId',
prop: '$applyDepId',
label: '申请单位',
placeholder: '请选择申请单位',
jnpfKey: 'select',
value: '',
options: this.departmentList,
__config__: {
jnpfKey: 'select',
label: '申请单位',
isFromParam: false
},
noShow: false
});
}
// 同时更新forceSetMockData里的申请单位options兜底
this.forceSetMockData();
},
filterEmpty(arr) {
return arr.filter(item => {
if (Array.isArray(item)) return item.length > 0;
if (typeof item === 'object' && item !== null) return Object.keys(item).length > 0;
return true;
});
},
selectCheckbox(data) {
this.selectItems = data
},
// 新增强制设置mock数据兜底逻辑
forceSetMockData() {
// 强制设置排序选项
if (!this.sortOptions.length) {
this.sortOptions = [
{ label: '创建时间 升序', value: 'create_time_asc', field: 'create_time', type: 'asc' },
{ label: '创建时间 降序', value: 'create_time_desc', field: 'create_time', type: 'desc' },
];
}
// 强制设置筛选配置(只在无数据时初始化,避免覆盖接口返回的配置)
if (!this.searchFormConf.length) {
this.searchFormConf = [
{
id: 'applyDepId',
prop: '$applyDepId',
label: '申请单位',
placeholder: '请选择申请单位',
jnpfKey: 'select',
value: '',
options: this.departmentList, // 动态绑定最新部门列表
__config__: {
jnpfKey: 'select',
label: '申请单位',
isFromParam: false
},
noShow: false
},
{
id: 'applyUser',
prop: 'applyUser',
label: '申请人',
placeholder: '请输入申请人员',
jnpfKey: 'input',
clearable: true,
isKeyword: true,
value: '',
__config__: {
jnpfKey: 'input',
label: '申请人',
isFromParam: false
},
noShow: false
},
{
id: 'operationDepName',
prop: 'operationDepName',
label: '作业单位',
placeholder: '请输入作业单位',
jnpfKey: 'input',
clearable: true,
isKeyword: true,
value: '',
__config__: {
jnpfKey: 'input',
label: '作业单位',
isFromParam: false
},
noShow: false
},
];
this.searchList = [...this.searchFormConf]
} else {
// 如果已有筛选配置只更新申请单位的options
const depConfIndex = this.searchFormConf.findIndex(item => item.id === 'applyDepId');
if (depConfIndex > -1) {
this.searchFormConf[depConfIndex].options = this.departmentList;
}
}
},
init() {
this.userInfo = uni.getStorageSync('userInfo') || {};
this.properties = this.config.flowTemplateJson ? JSON.parse(this.config.flowTemplateJson).properties : {};
let columnDataStr = this.config?.appColumnData || '{}'; // 改为空对象,避免解析报错
try {
this.columnData = JSON.parse(columnDataStr);
} catch (e) {
this.columnData = {};
}
this.permission = this.$permission.getPermission(this.columnData, this.menuId, this.jnpf.getScriptFunc);
this.enableFunc = this.permission.enableFunc;
this.upOption.page.size = this.columnData.hasPage ? this.columnData.pageSize : 1000000;
this.setDefaultQuery();
// ========== 强制设置列数据(优先级最高) ==========
this.columnList = [
{
prop: 'billNo',
label: '单号',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.billNo'
},
{
prop: 'applyDepName',
label: '申请单位',
sortable: false,
jnpfKey: 'table',
labelI18nCode: 'app.apply.applyDepName'
},
{
prop: 'applyUser',
label: '申请人员',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.applyUser'
},
{
prop: 'create_time',
label: '创建时间',
sortable: true,
jnpfKey: 'table',
labelI18nCode: 'app.apply.createTime'
},
{
prop: 'approveStatusName',
label: '审批状态',
sortable: false,
jnpfKey: 'table',
labelI18nCode: 'app.apply.approveStatus'
}
];
this.columnData.customBtnsList = this.permission.customBtnsPermission || [];
this.columnData.customBtnsList.map((o) => {
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode)
})
this.setBtns()
this.columnList = this.transformColumnList(this.columnList)
this.columnList.map((o) => {
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode)
});
// ========== 强制设置排序数据 ==========
this.sortList = this.columnList.filter(o => o.sortable);
// this.handleSortList(); // 立即生成排序选项
// ========== 强制设置筛选数据 ==========
this.handleSearchList(); // 处理筛选配置
this.getTabList();
this.handleDeleteBtn()
this.key = +new Date()
// 兜底强制触发mock数据生效
this.forceSetMockData()
},
setBtns() {
const buttons = {
inner: [],
top: []
};
this.columnData.customBtnsList.forEach(item => {
const key = item.event.position === 2 ? 'top' : 'inner';
buttons[key].push(item);
});
this.listInnerBtn = buttons.inner;
this.listTopBtn = buttons.top;
},
upCallback(page) {
if (this.isPreview == '1') return this.mescroll.endSuccess(0, false);
const { asc, desc, queryJson = {} } = this.listQuery
const query = {
pageNo: page.num,
pageSize: page.size,
menuId: this.menuId,
modelId: this.modelId,
asc,
desc,
...queryJson
}
getDbfromList(this.modelId, query, {
load: page.num == 1
}).then(res => {
this.selectItems = []
this.$nextTick(() => {
this.$refs.list.handleCheckAll()
})
this.showParser = true
if (page.num == 1) this.list = [];
this.mescroll.endSuccess(res.data.records.length);
const list = res.data.records.map((o, i) => ({
checked: false,
index: i,
...o
}));
this.list = this.list.concat(list);
console.log(this.list, 'list----')
this.$nextTick(() => {
if (this.columnData.funcs && this.columnData.funcs.afterOnload) this
.setTableLoadFunc()
})
if (!this.selectItems.length || !this.list.length) this.cancel()
}).catch((err) => {
this.mescroll.endByPage(0, 0);
this.mescroll.endErr();
})
},
async getTabList() {
this.tabList = [];
if (!this.columnData.tabConfig) return;
const list = this.columnData.columnOptions.filter(o => o.__vModel__ == this.columnData.tabConfig
.relationField) || [];
if (list?.length) {
this.columnData.tabConfig?.hasAllTab && this.tabList.push({
fullName: '全部',
id: undefined
});
if (list[0].__config__.dataType == 'dictionary' && list[0].__config__.dictionaryType) {
const data = await baseStore.getDicDataSelector(list[0].__config__.dictionaryType) || [];
const options = list[0].props.value == 'enCode' ? data.map(o => ({
...o,
id: o.enCode
})) : data;
this.tabList = [...this.tabList, ...options];
} else {
this.tabList = [...this.tabList, ...list[0].options];
}
}
this.tabActiveKey = 0;
this.onTabChange(this.tabActiveKey)
},
onTabChange(val) {
const {
hasAllTab,
relationField
} = this.columnData.tabConfig;
const currentTab = this.tabList[val];
const shouldSetRelation = !hasAllTab || val !== 0;
this.tabActiveKey = val;
this.tabQueryJson = shouldSetRelation ? {
[relationField]: currentTab.id
} : {};
const search = this.$refs.searchForm?.allCondition() || {};
this.listQuery.queryJson = JSON.stringify({
...search,
...this.tabQueryJson
});
this.initData();
},
handleSearchForm(data) {
let newData = {};
for (let key in data) {
if (data.hasOwnProperty(key)) {
if (typeof data[key] === 'object' && data[key] !== null) {
for (let innerKey in data[key]) {
if (data[key].hasOwnProperty(innerKey)) {
let newKey = `${key}-${innerKey}`;
newData[newKey] = data[key][innerKey];
}
}
} else {
newData[key] = data[key];
}
}
}
return newData
},
sumbitSearchForm(data) {
this.searchFormData = data
this.listQuery.queryJson = data
this.$refs.uDropdown.close();
this.$nextTick(() => {
this.list = [];
this.mescroll.resetUpScroll();
})
},
customEnableRule(data, funcName) {
// #ifdef MP-WEIXIN
return true
// #endif
// #ifndef MP-WEIXIN
let func = this.enableFunc[funcName]
if (!func) return false
let res = func.call(this, {
row: data,
rowIndex: data.index,
onlineUtils: this.jnpf.onlineUtils,
})
return res
// #endif
},
handleDeleteBtn() {
if (this.config.webType == 4) return
const actionOptions = this.columnData.columnBtnsList.filter(o => o.value == 'remove' && o.show)
this.actionOptions = actionOptions.map(o => ({
...o,
//#ifdef MP-WEIXIN
text: o.labelI18nCode ? this.$t(o.labelI18nCode) : o.label,
//#endif
//#ifndef MP-WEIXIN
text: o.labelI18nCode ? this.$t(o.labelI18nCode, o.label) : o.label,
//#endif
style: {
backgroundColor: '#dd524d'
}
}))
},
handleSearchList() {
// 保留mock数据不被原有逻辑覆盖
this.searchList = this.searchList.filter(o => !o.noShow)
for (let i = 0; i < this.searchList.length; i++) {
const item = this.searchList[i]
if (item.labelI18nCode) {
item.label = this.$t(item.labelI18nCode)
item.placeholder = this.$t(item.labelI18nCode)
}
const config = item.__config__
const now = new Date()
jnpf.setSearchDefaultValue(item, now)
if (item.value != null && item.value != '' && item.value != []) {
this.searchFormData[item.id] = item.value;
}
if (this.config.webType == 4) config.label = item.label
}
if (Object.keys(this.searchFormData).length) this.listQuery.queryJson = JSON.stringify(this.searchFormData)
this.searchFormConf = this.$u.deepClone(this.searchList)
},
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 + '-', '');
if (e.fullNameI18nCode && Array.isArray(e.fullNameI18nCode) && e.fullNameI18nCode[0]) {
label = this.$t(e.fullNameI18nCode[0], label);
}
let newItem = {
align: "center",
jnpfKey: "table",
prop,
label,
children: []
}
e.vModel = vModel
e.childLabel = e.labelI18nCode ? this.$t(e.labelI18nCode) : 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.desc = 'create_time';
this.listQuery.asc = '';
},
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]
if (!this.permission.btnPermission.includes('btn_remove')) return this.$u.toast("未开启删除权限")
if (!this.customEnableRule(item, 'remove')) return this.$u.toast("没有删除权限")
let txt = '流程处于暂停状态,不可操作'
if ([1, 2, 3, 4, 6, 7, 8].includes(item.flowState)) txt = '流程已受理,无法删除'
uni.showModal({
title: '提示',
content: '删除后数据无法恢复',
success: (res) => {
if (res.confirm) {
if (this.config.enableFlow == 1 && ![0, 9].includes(item.flowState)) {
this.$u.toast(txt)
return
}
let data = {
flowId: this.config.flowId,
ids: [item.id]
}
deteleModel(data, this.modelId).then(res => {
this.$u.toast(res.msg)
this.list.splice(index, 1)
this.mescroll.resetUpScroll()
})
}
}
})
},
handleBottomMoreClick(type) {
this.showBottomMoreBtn = true
},
handleMoreClick(index) {
this.selectListIndex = index
this.showMoreBtn = true
},
bottomBtnConfirm(e) {
if (Array.isArray(e) && e.length) {
const index = this.bottomCustomBtnsList[1].findIndex(item => item.value === e[0].value);
const item = this.bottomCustomBtnsList[1][index];
if (!this.selectItems.length && item.event.dataRequired) {
return this.$u.toast('请选择一条数据')
}
if (item.event && item.event.btnType === 3) this.handleBottomBtnInterface(item.event);
if (item.event.btnType == 2) this.handleScriptFunc(item.event, this.selectItems)
if (item.event.btnType == 4) this.handleLaunchFlow(item, this.selectItems)
} else {
if (!this.selectItems.length && e.event.dataRequired) {
return this.$u.toast('请选择一条数据')
}
if (e.event.btnType == 2) this.handleScriptFunc(e.event, this.selectItems)
if (e.event.btnType === 3) this.handleBottomBtnInterface(e.event);
if (e.event.btnType == 4) this.handleLaunchFlow(e, this.selectItems)
}
},
handleBottomBtnInterface(item) {
const selectedItemsCopy = [...this.selectItems];
const webType = this.config.webType;
let data = {
items: selectedItemsCopy,
webType
};
const handlerInterface = (data) => {
let query = {
paramList: this.jnpf.getBatchParamList(item.templateJson, data) || [],
}
getDataInterfaceRes(item.interfaceId, query).then(res => {
uni.showToast({
title: res.msg,
icon: 'none'
})
})
}
if (!item.useConfirm) return handlerInterface(data)
uni.showModal({
title: this.$t('common.tipTitle'),
content: item.confirmTitle || '确认执行此操作?',
showCancel: true,
confirmText: '确定',
success: function (res) {
if (res.confirm) {
handlerInterface(data)
}
}
});
},
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 (!this.customEnableRule(row, item.value)) return this.$u.toast('没有' + item.label + '权限')
if (item.event.btnType == 1) this.handlePopup(item.event, row)
if (item.event.btnType == 2) this.handleScriptFunc(item.event, row, index)
if (item.event.btnType == 3) this.handleInterface(item.event, row)
if (item.event.btnType == 4) this.handleLaunchFlow(item, [row])
},
handleLaunchFlow(item, records) {
const data = deepClone(item.event.launchFlow)
let dataList = [];
for (let i = 0; i < records.length; i++) {
dataList.push(this.jnpf.getLaunchFlowParamList(data.transferList, records[i], this.getRowKey));
}
const query = {
template: data.flowId,
btnCode: item.value,
currentUser: data.currentUser,
customUser: data.customUser,
initiator: data.initiator,
hasPermission: data.hasPermission,
dataList,
};
launchFlow(query, this.modelId).then(res => {
this.$u.toast(res.msg)
});
},
handlePopup(item, row) {
this.handleListen()
let data = {
config: item,
modelId: this.modelId,
id: this.config.webType == 4 ? '' : row[this.getRowKey],
isPreview: this.isPreview,
row: this.config.webType == 4 ? row : '',
}
data = encodeURIComponent(JSON.stringify(data))
uni.navigateTo({
url: '/pages/apply/customBtn/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[this.getModelInfo]).then(res => {
const dataForm = res.data || {};
if (!dataForm.data) return;
const data = {
...JSON.parse(dataForm.data),
id: row[this.getModelInfo]
};
handlerInterface(data);
})
}
const handlerInterface = (data) => {
let query = {
paramList: this.jnpf.getParamList(item.templateJson, {
...data,
id: row[this.getRowKey]
}, this.getRowKey) || [],
}
getDataInterfaceRes(item.interfaceId, query).then(res => {
uni.showToast({
title: res.msg,
icon: 'none'
})
if (item.isRefresh) this.initData();
})
}
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) handleFun()
}
})
},
initData() {
this.list = [];
this.$nextTick(() => {
this.mescroll.resetUpScroll();
})
},
search() {
if (this.isPreview == '1') return
this.searchTimer && clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.list = [];
this.mescroll.resetUpScroll();
}, 300)
},
handleListen() {
uni.$off('refresh')
uni.$on('refresh', () => {
this.list = [];
this.mescroll.resetUpScroll();
})
},
addPage() {
this.handleListen()
this.jumPage({}, 'btn_add')
},
jumPage(item, btnType) {
if (!item.id && !item.flowState) btnType = 'btn_add'
if (this.config.enableFlow == 1) {
if (item.id) {
if (!this.permission.btnPermission.includes('btn_edit') && item.flowState == 3) return
if (!this.permission.btnPermission.includes('btn_detail') && ![0, 8, 9].includes(item
.flowState))
return
}
let opType = '-1'
if (![0, 8, 9].includes(item.flowState) && btnType != 'btn_add') opType = 0
const config = {
id: item.flowTaskId || item.id || '',
flowId: this.config.flowId,
opType,
status: item.flowState || '',
isPreview: this.isPreview,
taskId: item.flowTaskId || item.id,
isFlow: 0,
}
uni.navigateTo({
url: '/pages/workFlow/flowBefore/index?config=' +
this.jnpf.base64.encode(JSON.stringify(config))
})
} else {
const type = btnType == 'btn_detail' ? 'detail' : 'form'
const currentMenu = encodeURIComponent(JSON.stringify(this.permission.formPermission))
let enableEdit = this.customEnableRule(item, 'edit')
let labelS = {}
const config = {
currentMenu,
btnType,
list: this.list,
modelId: this.modelId,
menuId: this.menuId,
isPreview: this.isPreview,
id: item.id || '',
index: item.index,
enableEdit,
labelS,
name: this.config.name,
billNoPrefix: this.config.billNoPrefix
}
2026-01-20 18:07:35 +08:00
console.log(config,'config12233')
2026-01-19 17:34:15 +08:00
const url = '/pages/apply/dynamicModelList/' + type + '?config=' +
this.jnpf.base64.encode(JSON.stringify(config))
uni.navigateTo({
url: url
})
}
},
goDetail(item) {
this.handleListen()
return this.jumPage(item, 'btn_edit')
let hasDetail = this.permission.btnPermission.includes('btn_detail')
let hasEdit = this.permission.btnPermission.includes('btn_edit')
if (!hasDetail && !hasEdit) return
if (hasDetail) {
if (this.customEnableRule(item, 'detail')) {
return this.jumPage(item, 'btn_detail')
}
if (this.customEnableRule(item, 'edit')) {
return this.jumPage(item, 'btn_edit')
}
} else {
if (this.customEnableRule(item, 'edit')) {
return this.jumPage(item, 'btn_edit')
}
}
},
cellClick(item) {
if (this.isPreview == '1') return this.$u.toast('功能预览不支持排序')
this.sortValue = [item.value];
this.selectedSort = {
field: item.field,
type: item.type
};
},
handleReset() {
this.searchFormData = {}
const list = ['datePicker', 'timePicker', 'inputNumber', 'calculate', 'cascader', 'usersSelect']
for (let i = 0; i < this.searchList.length; i++) {
const item = this.searchList[i]
const config = item.__config__
let defaultValue = item.searchMultiple || list.includes(config.jnpfKey) ? [] : undefined
if (config.isFromParam) defaultValue = undefined
config.defaultValue = defaultValue
this.searchFormData[item.id] = item.value || defaultValue
}
this.searchFormConf = JSON.parse(JSON.stringify(this.searchList))
},
handleSearch() {
if (this.isPreview == '1') return this.$u.toast('功能预览不支持检索')
this.$refs.searchForm && this.$refs.searchForm.submitForm()
},
relationFormClick(item, column) {
let vModel = column.vModel ? column.vModel : column.__vModel__
let model_id = column.modelId
let config = {
modelId: model_id,
isPreview: true,
id: item[vModel + '_id'],
sourceRelationForm: true,
noShowBtn: 1,
noDataLog: 1,
propsValue: column.propsValue
}
const url =
'/pages/apply/dynamicModel/detail?config=' + this.jnpf.base64.encode(JSON.stringify(config))
uni.navigateTo({
url: url
})
},
handleSortReset() {
this.sortValue = []
this.selectedSort = {};
this.listQuery.asc = '';
this.listQuery.desc = '';
},
handleSortSearch() {
this.listQuery.asc = '';
this.listQuery.desc = '';
if (Object.keys(this.selectedSort).length > 0) {
const sortItem = this.selectedSort;
if (sortItem.type === 'asc') {
this.listQuery.asc = sortItem.field;
this.listQuery.desc = '';
} else {
this.listQuery.desc = sortItem.field;
this.listQuery.asc = '';
}
} else {
this.setDefaultQuery();
}
console.log(this.listQuery, 'listQuery')
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;
}
</style>