feat: 新增需求
@@ -240,6 +240,7 @@
|
||||
},
|
||||
getConfigData() {
|
||||
this.loading = true;
|
||||
console.log(this.modelId,'modelId-------')
|
||||
getConfigData(this.modelId).then((res) => {
|
||||
if (res.code !== 200 || !res.data) {
|
||||
uni.showToast({
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
return
|
||||
}
|
||||
this.formConf = res.data.formData ? JSON.parse(res.data.formData) : {};
|
||||
console.log(this.formConf,'formConf----')
|
||||
this.showPage = true
|
||||
this.initData()
|
||||
})
|
||||
|
||||
75
pages/apply/dynamicModelList/bulkOperationMixin.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
deteleModel
|
||||
} from '@/api/apply/visualDev'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
slide: '',
|
||||
slide2: '',
|
||||
checkedAll: false,
|
||||
ids: [],
|
||||
showTop: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 批量删除 */
|
||||
batchDelete() {
|
||||
if (!this.selectItems.length) {
|
||||
return this.$u.toast('请选择一条数据')
|
||||
}
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '删除后数据无法恢复',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
const uniqueIds = new Set();
|
||||
this.selectItems.forEach(item => {
|
||||
uniqueIds.add(item.id);
|
||||
});
|
||||
const ids = [...uniqueIds];
|
||||
let data = {
|
||||
flowId: this.config.flowId,
|
||||
ids
|
||||
};
|
||||
deteleModel(data, this.modelId).then(res => {
|
||||
this.selectItems = [];
|
||||
this.$u.toast(res.msg)
|
||||
this.mescroll.resetUpScroll()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
openBatchOperate() {
|
||||
this.showTop = !this.showTop
|
||||
if (this.showTop) {
|
||||
this.slide = 'slide-up'
|
||||
this.slide2 = 'slide-up2'
|
||||
}
|
||||
},
|
||||
checkAll() {
|
||||
this.checkedAll = !this.checkedAll
|
||||
this.list = this.list.map(o => ({
|
||||
...o,
|
||||
checked: false
|
||||
}))
|
||||
if (this.checkedAll) {
|
||||
this.list = this.list.map(o => ({
|
||||
...o,
|
||||
checked: true
|
||||
}))
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
this.list = this.list.map(o => ({
|
||||
...o,
|
||||
checked: false
|
||||
}))
|
||||
this.showTop = false
|
||||
this.checkedAll = false
|
||||
this.$nextTick(() => {
|
||||
this.$refs.list.handleCheckAll()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
596
pages/apply/dynamicModelList/components/detail/Item.vue
Normal file
@@ -0,0 +1,596 @@
|
||||
<template>
|
||||
<view :class="{'item-card':config.jnpfKey==='card'}"
|
||||
v-if="!config.noShow && (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes('app')))">
|
||||
<template v-if="config.layout==='colFormItem'">
|
||||
<JnpfText v-if="config.jnpfKey=='text'" :content="item.content" :textStyle="item.textStyle" />
|
||||
<JnpfDivider v-else-if="config.jnpfKey==='divider'" :content="item.content" />
|
||||
<JnpfGroupTitle v-else-if="config.jnpfKey=='groupTitle'" :content="item.content"
|
||||
:content-position="item.contentPosition" :helpMessage="item.helpMessage" @groupIcon="clickIcon(item)" />
|
||||
<u-form-item v-else-if="config.jnpfKey==='popupSelect' || config.jnpfKey==='relationForm'"
|
||||
:label="realLabel" :prop="item.__vModel__" class="popup-select" :label-width="labelWidth"
|
||||
:left-icon="leftIcon" :left-icon-style="{'color':'#a8aaaf'}" @clickIcon="clickIcon(item)">
|
||||
<view class="detail-text-box" v-if="config.jnpfKey==='popupSelect'">
|
||||
<view class="jnpf-detail-text">
|
||||
{{formData[item.__vModel__]}}
|
||||
</view>
|
||||
<DisplayList v-if="Object.keys(extraObj).length" :extraObj="extraObj"
|
||||
:extraOptions="item.extraOptions">
|
||||
</DisplayList>
|
||||
</view>
|
||||
<view class="detail-text-box" @click.native="toDetail(item)" v-if="config.jnpfKey==='relationForm'">
|
||||
<view class="jnpf-detail-text" style="color:rgb(41, 121, 255)">
|
||||
{{formData[item.__vModel__]}}
|
||||
</view>
|
||||
<DisplayList v-if="Object.keys(extraObj).length" :extraObj="extraObj"
|
||||
:extraOptions="item.extraOptions">
|
||||
</DisplayList>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item v-else :label="realLabel" :prop="item.__vModel__" :label-width="labelWidth"
|
||||
:left-icon="leftIcon" :left-icon-style="{'color':'#a8aaaf'}" @clickIcon="clickIcon(item)">
|
||||
<JnpfUploadImg v-if="config.jnpfKey==='uploadImg'" v-model="config.defaultValue" detailed />
|
||||
<!-- #ifndef APP-HARMONY -->
|
||||
<JnpfUploadFile v-else-if="config.jnpfKey=='uploadFile'" v-model="config.defaultValue" detailed />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-HARMONY -->
|
||||
<JnpfUploadFileH v-else-if="config.jnpfKey=='uploadFile'" v-model="config.defaultValue" detailed />
|
||||
<!-- #endif -->
|
||||
<JnpfColorPicker v-else-if="config.jnpfKey==='colorPicker'" v-model="config.defaultValue"
|
||||
:colorFormat="item.colorFormat" disabled />
|
||||
<JnpfRate v-else-if="config.jnpfKey==='rate'" v-model="config.defaultValue" :max="item.count"
|
||||
:allowHalf="item.allowHalf" disabled />
|
||||
<JnpfEditor v-else-if="config.jnpfKey==='editor'" v-model="config.defaultValue" detailed />
|
||||
<JnpfBarcode v-else-if="config.jnpfKey=='barcode'" :staticText="item.staticText" :width="item.width"
|
||||
:height="item.height" :format="item.format" :dataType="item.dataType" :lineColor="item.lineColor"
|
||||
:background="item.background" :relationField="item.relationField+'_id'" :formData="formData" />
|
||||
<JnpfQrcode v-else-if="config.jnpfKey=='qrcode'" :staticText="item.staticText" :width="item.width"
|
||||
:dataType="item.dataType" :colorDark="item.colorDark" :colorLight="item.colorLight"
|
||||
:relationField="item.relationField+'_id'" :formData="formData" />
|
||||
<JnpfInputNumber v-else-if="config.jnpfKey=='inputNumber'" v-model="config.defaultValue"
|
||||
:step='item.step' :max='item.max||999999999999999' :min='item.min||-999999999999999'
|
||||
:disabled="item.disabled" :placeholder="item.placeholder" :isAmountChinese="item.isAmountChinese"
|
||||
:thousands="item.thousands" :addonAfter="item.addonAfter" :addonBefore="item.addonBefore"
|
||||
:controls="item.controls" :precision="item.precision" detailed />
|
||||
<JnpfCalculate v-else-if="config.jnpfKey==='calculate'" :expression='item.expression'
|
||||
:vModel='item.__vModel__' :config='config' :formData='formData' v-model="config.defaultValue"
|
||||
:precision="item.precision" :isAmountChinese="item.isAmountChinese" :thousands="item.thousands"
|
||||
:roundType="item.roundType" :dateCalConfig="item.dateCalConfig" :type="item.type" />
|
||||
<JnpfDateCalculate v-else-if="config.jnpfKey==='dateCalculate'" :expression='item.expression'
|
||||
:vModel='item.__vModel__' :config='config' :formData='formData' v-model="config.defaultValue"
|
||||
:startRelationField="item.startRelationField" :startTimeType="item.startTimeType"
|
||||
:startTimeValue="item.startTimeValue" :format="item.format" />
|
||||
<JnpfLink v-else-if="config.jnpfKey=='link'" :content="item.content" :href="item.href"
|
||||
:target='item.target' :textStyle="item.textStyle" />
|
||||
<JnpfAlert v-else-if="config.jnpfKey=='alert'" :type="item.type" :title="item.title"
|
||||
:tagIcon='item.tagIcon' :showIcon="item.showIcon" :closable="item.closable"
|
||||
:description="item.description" :closeText="item.closeText" />
|
||||
<JnpfButton v-else-if="config.jnpfKey=='button'" :buttonText="item.buttonText" :align="item.align"
|
||||
:type="item.type" :disabled="item.disabled" />
|
||||
<JnpfSlider v-else-if="config.jnpfKey=='slider'" v-model="config.defaultValue" :step="item.step"
|
||||
:min="item.min||0" :max="item.max||100" disabled />
|
||||
<JnpfSign v-else-if="config.jnpfKey=='sign'" v-model="config.defaultValue" detailed />
|
||||
<JnpfSignature v-else-if="config.jnpfKey=='signature'" v-model="config.defaultValue" detailed />
|
||||
<JnpfLocation v-else-if="config.jnpfKey=='location'" v-model="config.defaultValue"
|
||||
:enableLocationScope="item.enableLocationScope" detailed />
|
||||
<!--end labelwidth=0-->
|
||||
<template v-else>
|
||||
<JnpfInput v-if="config.jnpfKey=='input'" v-model="config.defaultValue" detailed
|
||||
:useMask="item.useMask" :maskConfig="item.maskConfig" :addonBefore="item.addonBefore"
|
||||
:addonAfter="item.addonAfter" />
|
||||
<view class="jnpf-detail-text" v-else>{{ getValue(item) }}</view>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="jnpf-card" v-if="config.jnpfKey==='card'||config.jnpfKey==='row'">
|
||||
<view class="jnpf-card-cap u-line-1 u-flex" v-if="item.header" @click="clickIcon(item)">
|
||||
{{item.header}}
|
||||
<u-icon :name="config.tipLabel? 'question-circle-fill':''" class="u-m-l-10" color="#a0acb7" />
|
||||
</view>
|
||||
<Item v-for="(child, index) in config.children" :key="config.renderKey+index" :itemData="child"
|
||||
:formConf="formConf" :formData="formData" @toDetail="toDetail" @clickIcon='clickIcon' />
|
||||
</view>
|
||||
<template v-if="config.jnpfKey==='table'">
|
||||
<view class="jnpf-table">
|
||||
<view class="jnpf-table-title u-line-1" @click="clickIcon(item)">
|
||||
{{config.label}}
|
||||
<u-icon v-if="config.tipLabel" :name="'question-circle-fill'" class="u-m-l-10"
|
||||
color="#a0acb7" />
|
||||
</view>
|
||||
<view v-for="(column,columnIndex) in config.defaultValue" :key="columnIndex">
|
||||
<view class="jnpf-table-item-title">
|
||||
<view class="jnpf-table-item-title-num">({{columnIndex+1}})</view>
|
||||
</view>
|
||||
<view class="form-item-box" v-for="(childItem,cIndex) in config.children" :key="cIndex">
|
||||
<u-form-item :label="childItem.__config__.showLabel?childItem.__config__.label:''"
|
||||
:label-width="childItem.__config__.labelWidth ? childItem.__config__.labelWidth * 1.5 : undefined"
|
||||
@clickIcon="clickIcon(childItem)"
|
||||
:left-icon='childItem.__config__.tipLabel &&childItem.__config__.showLabel&& childItem.__config__.label? "question-circle-fill":""'
|
||||
:left-icon-style="{'color':'#a0acb7'}"
|
||||
v-if="!childItem.__config__.noShow&&(!childItem.__config__.visibility|| (Array.isArray(childItem.__config__.visibility) && childItem.__config__.visibility.includes('app')))">
|
||||
<template
|
||||
v-if="['relationFormAttr','popupAttr'].includes(childItem.__config__.jnpfKey)">
|
||||
<view class="jnpf-detail-text" v-if="!childItem.__vModel__">
|
||||
{{ column[childItem.relationField.split('_jnpfTable_')[0]+'_'+childItem.showField] }}
|
||||
</view>
|
||||
<view class="jnpf-detail-text" v-else>
|
||||
{{column[childItem.__vModel__]}}
|
||||
</view>
|
||||
</template>
|
||||
<view v-else-if="childItem.__config__.jnpfKey==='relationForm'" class="jnpf-detail-text"
|
||||
style="color:rgb(41, 121, 255)"
|
||||
@click.native="toTableDetail(childItem,column[childItem.__vModel__+'_id'])">
|
||||
{{column[childItem.__vModel__]}}
|
||||
</view>
|
||||
<JnpfSign v-else-if="childItem.__config__.jnpfKey=='sign'"
|
||||
v-model="column[childItem.__vModel__]" detailed />
|
||||
<JnpfSignature v-else-if="childItem.__config__.jnpfKey=='signature'"
|
||||
v-model="column[childItem.__vModel__]" detailed />
|
||||
<JnpfLocation v-else-if="childItem.__config__.jnpfKey=='location'"
|
||||
v-model="column[childItem.__vModel__]"
|
||||
:enableLocationScope="item.enableLocationScope" detailed />
|
||||
<!-- #ifndef APP-HARMONY -->
|
||||
<JnpfUploadFile v-else-if="childItem.__config__.jnpfKey==='uploadFile'"
|
||||
v-model="column[childItem.__vModel__]" detailed />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-HARMONY -->
|
||||
<JnpfUploadFileH v-else-if="childItem.__config__.jnpfKey==='uploadFile'"
|
||||
v-model="column[childItem.__vModel__]" detailed />
|
||||
<!-- #endif -->
|
||||
<JnpfUploadImg v-else-if="childItem.__config__.jnpfKey==='uploadImg'"
|
||||
v-model="column[childItem.__vModel__]" detailed />
|
||||
<JnpfInputNumber v-else-if="childItem.__config__.jnpfKey=='inputNumber'"
|
||||
v-model="column[childItem.__vModel__]" :step='childItem.step' :max='childItem.max'
|
||||
:min='childItem.min' :disabled="childItem.disabled"
|
||||
:placeholder="childItem.placeholder" :isAmountChinese="childItem.isAmountChinese"
|
||||
:thousands="childItem.thousands" :addonAfter="childItem.addonAfter"
|
||||
:addonBefore="childItem.addonBefore" :controls="childItem.controls"
|
||||
:precision="childItem.precision" detailed />
|
||||
<JnpfCalculate v-else-if="childItem.__config__.jnpfKey==='calculate'"
|
||||
:expression='childItem.expression' :vModel='childItem.__vModel__'
|
||||
:config='childItem.__config__' :formData='formData' :roundType="childItem.roundType"
|
||||
:dateCalConfig="childItem.dateCalConfig" :type="childItem.type"
|
||||
v-model="column[childItem.__vModel__]" :precision="childItem.precision"
|
||||
:isAmountChinese="childItem.isAmountChinese" :thousands="childItem.thousands"
|
||||
:rowIndex="columnIndex" />
|
||||
<JnpfDateCalculate v-else-if="childItem.__config__.jnpfKey==='dateCalculate'"
|
||||
:expression='childItem.expression' :vModel='childItem.__vModel__'
|
||||
:config='childItem.__config__' :formData='formData'
|
||||
v-model="column[childItem.__vModel__]"
|
||||
:startRelationField="childItem.startRelationField"
|
||||
:startTimeType="childItem.startTimeType" :startTimeValue="childItem.startTimeValue"
|
||||
:format="childItem.format" :rowIndex="columnIndex" />
|
||||
<JnpfRate v-else-if="childItem.__config__.jnpfKey==='rate'" :max="childItem.count"
|
||||
v-model="column[childItem.__vModel__]" :allowHalf="childItem.allowHalf" disabled />
|
||||
<JnpfSlider v-else-if="childItem.__config__.jnpfKey=='slider'"
|
||||
v-model="column[childItem.__vModel__]" :step="childItem.step"
|
||||
:min="childItem.min||0" :max="childItem.max||100" disabled />
|
||||
<template v-else>
|
||||
<JnpfInput v-if="childItem.__config__.jnpfKey=='input'"
|
||||
v-model="column[childItem.__vModel__]" detailed :useMask="childItem.useMask"
|
||||
:maskConfig="childItem.maskConfig" :addonBefore="childItem.addonBefore"
|
||||
:addonAfter="childItem.addonAfter" />
|
||||
<view class="jnpf-detail-text" v-else>{{column[childItem.__vModel__]}}</view>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
<view class="jnpf-table-item" v-if="item.showSummary && summaryField.length">
|
||||
<view class="jnpf-table-item-title u-flex u-row-between">
|
||||
<text class="jnpf-table-item-title-num">{{item.__config__.label}}合计</text>
|
||||
</view>
|
||||
<view class=" u-p-l-20 u-p-r-20 form-item-box">
|
||||
<u-form-item v-for="(item,index) in summaryField" :label="item.__config__.label"
|
||||
:key="item.__vModel__">
|
||||
<u-input input-align='right' v-model="item.value" disabled />
|
||||
</u-form-item>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view v-else-if="config.jnpfKey==='steps'" style="background-color: #fff;padding:15px 0">
|
||||
<view class="step-container">
|
||||
<u-steps :list="config.children" name="title" :mode="item.simple ? 'dot' :'number'"
|
||||
@change="onStepChange($event,item)" :current="stepCurrent">
|
||||
</u-steps>
|
||||
</view>
|
||||
<view v-for="(itemSub,i) in config.children" :key='i'>
|
||||
<view v-if="i === stepCurrent">
|
||||
<Item v-for="(childItem, childIndex) in itemSub.__config__.children" :key="childIndex"
|
||||
:itemData="childItem" :formConf="formConf" :formData="formData" @toDetail="toDetail"
|
||||
@clickIcon='clickIcon' />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="jnpf-tab" v-if="config.jnpfKey==='tab'">
|
||||
<u-tabs is-scroll :list="config.children" name="title" v-model="tabCurrent" @change="onTabChange" />
|
||||
<view v-for="(pane,i) in config.children" :key='i'>
|
||||
<view v-show="i == tabCurrent">
|
||||
<Item v-for="(childItem, childIndex) in pane.__config__.children" :key="childIndex"
|
||||
:itemData="childItem" :formConf="formConf" :formData="formData" @toDetail="toDetail"
|
||||
@clickIcon='clickIcon' />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="config.jnpfKey==='collapse'">
|
||||
<u-collapse :head-style="{'padding-left':'20rpx'}" :accordion="item.accordion" ref="collapseRef">
|
||||
<u-collapse-item :title="pane.title" v-for="(pane, i) in config.children" :key="i"
|
||||
:open="config.active && config.active.indexOf(pane.name)>-1">
|
||||
<Item v-for="(child, j) in pane.__config__.children" :key="child.__config__.renderKey"
|
||||
:itemData="child" :formConf="formConf" :formData="formData" @toDetail="toDetail"
|
||||
@clickIcon='clickIcon' />
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getRelationFormDetail,
|
||||
getDataInterfaceDataInfoByIds
|
||||
} from '@/api/common.js'
|
||||
// #ifdef MP
|
||||
import Item from './Item.vue' //兼容小程序
|
||||
// #endif
|
||||
import DisplayList from '@/components/displayList'
|
||||
const specialList = ['link', 'editor', 'button', 'alert']
|
||||
export default {
|
||||
name: 'Item',
|
||||
components: {
|
||||
// #ifdef MP
|
||||
Item,
|
||||
// #endif
|
||||
DisplayList
|
||||
},
|
||||
props: {
|
||||
itemData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
formConf: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
item() {
|
||||
const item = uni.$u.deepClone(this.itemData)
|
||||
this.initI18n(item)
|
||||
return item
|
||||
},
|
||||
config() {
|
||||
return this.item.__config__
|
||||
},
|
||||
labelWidth() {
|
||||
if (specialList.indexOf(this.config.jnpfKey) > -1) return 0
|
||||
return this.config.labelWidth ? this.config.labelWidth * 1.5 : undefined
|
||||
},
|
||||
label() {
|
||||
return this.config.showLabel && specialList.indexOf(this.config.jnpfKey) < 0 ? this.config.label : ''
|
||||
},
|
||||
realLabel() {
|
||||
return this.label ? (this.label + (this.formConf.labelSuffix || '')) : ''
|
||||
},
|
||||
leftIcon() {
|
||||
return this.config.tipLabel && this.label && this.config.showLabel ? "question-circle-fill" : ""
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabCurrent: 0,
|
||||
tableData: [],
|
||||
summaryField: [],
|
||||
stepCurrent: 0,
|
||||
extraObj: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.handleSummary()
|
||||
this.handleTab()
|
||||
},
|
||||
mounted() {
|
||||
if (this.config.jnpfKey === 'collapse') {
|
||||
this.$refs.collapseRef && this.$refs.collapseRef.init()
|
||||
}
|
||||
uni.$on('initCollapse', () => {
|
||||
this.$refs.collapseRef && this.$refs.collapseRef.init()
|
||||
})
|
||||
this.getDataChange()
|
||||
this.getDataInterfaceDataInfoByIds()
|
||||
},
|
||||
methods: {
|
||||
onStepChange(index, item) {
|
||||
if (this.stepCurrent === index) return
|
||||
item.__config__.active = index
|
||||
this.stepCurrent = index
|
||||
this.$nextTick(() => {
|
||||
uni.$emit('updateCode')
|
||||
uni.$emit('initCollapse')
|
||||
})
|
||||
},
|
||||
initI18n(item) {
|
||||
const config = item.__config__
|
||||
if (item.placeholderI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.placeholder = this.$t(item.placeholderI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.placeholder = this.$t(item.placeholderI18nCode, item.placeholder);
|
||||
//#endif
|
||||
}
|
||||
if (item.__config__.label && item.__config__.labelI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.__config__.label = this.$t(item.__config__.labelI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.__config__.label = this.$t(item.__config__.labelI18nCode, item.__config__.label);
|
||||
//#endif
|
||||
}
|
||||
if (item.__config__.tipLabel && item.__config__.tipLabelI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.__config__.tipLabel = this.$t(item.__config__.tipLabelI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.__config__.tipLabel = this.$t(item.__config__.tipLabelI18nCode, item.__config__.tipLabel);
|
||||
//#endif
|
||||
}
|
||||
if (['groupTitle', 'divider', 'link', 'text'].includes(config.jnpfKey)) {
|
||||
if (item.contentI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.content = this.$t(item.contentI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.content = this.$t(item.contentI18nCode, item.content);
|
||||
//#endif
|
||||
}
|
||||
if (item.helpMessageI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.helpMessage = this.$t(item.helpMessageI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.helpMessage = this.$t(item.helpMessageI18nCode, item.helpMessage);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'button') {
|
||||
if (item.buttonTextI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.buttonText = this.$t(item.buttonTextI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.buttonText = this.$t(item.buttonTextI18nCode.item.buttonText);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'alert') {
|
||||
if (item.titleI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.title = this.$t(item.titleI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.title = this.$t(item.titleI18nCode, item.title);
|
||||
//#endif
|
||||
}
|
||||
if (item.descriptionI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.description = this.$t(item.descriptionI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.description = this.$t(item.descriptionI18nCode, item.description);
|
||||
//#endif
|
||||
}
|
||||
if (item.closeTextI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.closeText = this.$t(item.closeTextI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.closeText = this.$t(item.closeTextI18nCode, item.closeText);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'card') {
|
||||
if (item.headerI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.header = this.$t(item.headerI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.header = this.$t(item.headerI18nCode, item.header);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
if (['tab', 'collapse', 'steps'].includes(config.jnpfKey)) {
|
||||
if (config.children && config.children.length) {
|
||||
for (let i = 0; i < config.children.length; i++) {
|
||||
if (config.children[i].titleI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
config.children[i].title =
|
||||
this.$t(config.children[i].titleI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
config.children[i].title =
|
||||
this.$t(config.children[i].titleI18nCode, config.children[i].title);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item.headerI18nCode) {
|
||||
//#ifdef MP-WEIXIN
|
||||
item.header = this.$t(item.headerI18nCode);
|
||||
//#endif
|
||||
//#ifndef MP-WEIXIN
|
||||
item.header = this.$t(item.headerI18nCode, item.header);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'table') {
|
||||
if (config.children && config.children.length) {
|
||||
for (let i = 0; i < config.children.length; i++) {
|
||||
this.initI18n(config.children[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleTab() {
|
||||
if (this.config.jnpfKey === 'steps') return this.stepCurrent = this.config.active
|
||||
if (this.config.jnpfKey !== 'tab') return
|
||||
for (var i = 0; i < this.config.children.length; i++) {
|
||||
if (this.config.active == this.config.children[i].name) {
|
||||
this.tabCurrent = i
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
getDataChange() {
|
||||
if (this.config.jnpfKey === 'relationForm' && this.config.defaultValue) {
|
||||
let query = {
|
||||
id: this.formData[this.item.__vModel__ + '_id'],
|
||||
};
|
||||
if (this.item.propsValue) query = {
|
||||
...query,
|
||||
propsValue: this.item.propsValue
|
||||
};
|
||||
getRelationFormDetail(this.item.modelId, query).then(res => {
|
||||
if ((!res.data || !res.data.data) || res.data.data === "undefined") return
|
||||
let data = JSON.parse(res.data?.data)
|
||||
this.extraObj = data
|
||||
})
|
||||
}
|
||||
},
|
||||
getDataInterfaceDataInfoByIds() {
|
||||
if (this.config.jnpfKey === 'popupSelect' && this.config.defaultValue) {
|
||||
let query = {
|
||||
ids: [this.config.defaultValue],
|
||||
interfaceId: this.item.interfaceId,
|
||||
propsValue: this.item.propsValue,
|
||||
relationField: this.item.relationField,
|
||||
paramList: this.getParamList()
|
||||
}
|
||||
getDataInterfaceDataInfoByIds(this.item.interfaceId, query).then(res => {
|
||||
const data = res.data && res.data.length ? res.data[0] : {};
|
||||
this.extraObj = data
|
||||
})
|
||||
}
|
||||
},
|
||||
getParamList() {
|
||||
let templateJson = this.item.templateJson
|
||||
if (!this.formData) return templateJson
|
||||
for (let i = 0; i < templateJson.length; i++) {
|
||||
if (templateJson[i].relationField && templateJson[i].sourceType == 1) {
|
||||
if (templateJson[i].relationField.includes('-')) {
|
||||
let tableVModel = templateJson[i].relationField.split('-')[0]
|
||||
let childVModel = templateJson[i].relationField.split('-')[1]
|
||||
templateJson[i].defaultValue = this.formData[tableVModel] && this.formData[tableVModel][this
|
||||
.rowIndex
|
||||
] && this.formData[tableVModel][this.rowIndex][childVModel] || ''
|
||||
} else {
|
||||
templateJson[i].defaultValue = this.formData[templateJson[i].relationField] || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
return templateJson
|
||||
},
|
||||
handleSummary() {
|
||||
if (this.item.__config__.jnpfKey !== 'table') return
|
||||
const val = this.item.__config__.defaultValue
|
||||
let summaryField = this.item.summaryField || []
|
||||
this.summaryField = []
|
||||
this.tableData = this.item.__config__.children || []
|
||||
for (let i = 0; i < summaryField.length; i++) {
|
||||
for (let o = 0; o < this.tableData.length; o++) {
|
||||
const item = this.tableData[o]
|
||||
if (this.tableData[o].__vModel__ === summaryField[i] && !item.__config__.noShow) {
|
||||
this.summaryField.push({
|
||||
value: '',
|
||||
...item
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => this.getTableSummaries(val, this.item))
|
||||
},
|
||||
toThousands(val, column) {
|
||||
if (val) {
|
||||
let valList = val.toString().split('.')
|
||||
let num = Number(valList[0])
|
||||
let newVal = column.thousands ? num.toLocaleString() : num
|
||||
return valList[1] ? newVal + '.' + valList[1] : newVal
|
||||
} else {
|
||||
return val
|
||||
}
|
||||
},
|
||||
getTableSummaries(newVal, config) {
|
||||
for (let i = 0; i < this.summaryField.length; i++) {
|
||||
let val = 0
|
||||
for (let j = 0; j < newVal.length; j++) {
|
||||
if (newVal[j][this.summaryField[i].__vModel__]) {
|
||||
let data = isNaN(newVal[j][this.summaryField[i].__vModel__]) ? 0 :
|
||||
Number(newVal[j][this.summaryField[i].__vModel__])
|
||||
val += data
|
||||
}
|
||||
}
|
||||
let realVal = val && !Number.isInteger(val) ? Number(val).toFixed(2) : val;
|
||||
if (this.summaryField[i].thousands) realVal = Number(realVal).toLocaleString('zh')
|
||||
this.summaryField[i].value = realVal
|
||||
}
|
||||
},
|
||||
clickIcon(e) {
|
||||
this.$emit('clickIcon', e)
|
||||
},
|
||||
onTabChange(index) {
|
||||
if (this.tabCurrent === index) return
|
||||
this.tabCurrent = index;
|
||||
this.$emit('tab-change', this.item, index)
|
||||
this.$nextTick(() => {
|
||||
uni.$emit('initCollapse')
|
||||
uni.$emit('updateCode')
|
||||
})
|
||||
},
|
||||
doPreviewImage(current, imageList) {
|
||||
const images = imageList.map(item => this.define.baseURL + item.url);
|
||||
uni.previewImage({
|
||||
urls: images,
|
||||
current: current,
|
||||
success: () => {},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '预览图片失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetail(item) {
|
||||
const data = {
|
||||
...item,
|
||||
...(item.__config__.jnpfKey === 'relationForm' ? {
|
||||
sourceRelationForm: true,
|
||||
propsValue: item.propsValue
|
||||
} : {})
|
||||
};
|
||||
this.$emit('toDetail', data)
|
||||
},
|
||||
toTableDetail(item, value) {
|
||||
item.__config__.defaultValue = value
|
||||
this.$emit('toDetail', item)
|
||||
},
|
||||
getValue(item) {
|
||||
if (Array.isArray(item.__config__.defaultValue)) {
|
||||
if (['timeRange', 'dateRange'].includes(item.__config__.jnpfKey)) {
|
||||
return item.__config__.defaultValue.join('')
|
||||
}
|
||||
return item.__config__.defaultValue.join()
|
||||
}
|
||||
return item.__config__.defaultValue
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.detail-text-box {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
68
pages/apply/dynamicModelList/components/detail/Parser.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<u-form class="jnpf-wrap-form" :model="formData" ref="dataForm"
|
||||
:label-position="formConf.labelPosition==='top'?'top':'left'"
|
||||
:label-align="formConf.labelPosition==='right'?'right':'left'"
|
||||
:label-width="formConf.labelWidth?formConf.labelWidth*1.5:150" :class='formConf.className'>
|
||||
<template v-for="(item, index) in formConf.fields" :key="item.__config__.renderKey">
|
||||
<Item :itemData="item" :formConf="formConf" :class="item.__config__.className" :formData="formData"
|
||||
:ref="item.__vModel__?item.__vModel__: undefined" @toDetail="toDetail" @clickIcon='clickIcon' />
|
||||
</template>
|
||||
<u-modal v-model="show" :content="content" width='70%' border-radius="16" :content-style="contentStyle"
|
||||
:titleStyle="titleStyle" :confirm-style="confirmStyle" :title="title" :confirm-text="$t('common.okText')">
|
||||
</u-modal>
|
||||
</u-form>
|
||||
</template>
|
||||
<script>
|
||||
import Item from './Item'
|
||||
export default {
|
||||
components: {
|
||||
Item
|
||||
},
|
||||
props: {
|
||||
formConf: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
content: '',
|
||||
contentStyle: {
|
||||
fontSize: '28rpx',
|
||||
padding: '20rpx',
|
||||
lineHeight: '44rpx',
|
||||
textAlign: 'left'
|
||||
},
|
||||
titleStyle: {
|
||||
padding: '20rpx'
|
||||
},
|
||||
confirmStyle: {
|
||||
height: '80rpx',
|
||||
lineHeight: '80rpx',
|
||||
},
|
||||
title: this.$t('common.tipTitle'),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clickIcon(e) {
|
||||
if (!e.__config__.tipLabel && !e.helpMessage) return
|
||||
this.content = e.helpMessage || e.__config__.tipLabel
|
||||
this.title = e.__config__.label
|
||||
if (e.__config__.jnpfKey === 'card') this.title = e.header
|
||||
if (e.__config__.jnpfKey === 'groupTitle') this.title = e.content
|
||||
this.show = true
|
||||
},
|
||||
toDetail(item) {
|
||||
this.$emit('toDetail', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
179
pages/apply/dynamicModelList/components/form/index.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<view class="jnpf-wrap jnpf-wrap-form">
|
||||
<JnpfParser v-if="!loading" ref="dynamicForm" :formConf="formConf" :key="key" @submit="sumbitForm" />
|
||||
<view class="buttom-actions" v-if="origin !='scan'">
|
||||
<u-button class="buttom-btn" @click.stop="resetForm">{{$t('common.resetText')}}</u-button>
|
||||
<u-button class="buttom-btn" type="primary" @click.stop="submit" :loading="btnLoading">
|
||||
{{getOkText}}
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
createModel,
|
||||
getModelInfo
|
||||
} from '@/api/apply/visualDev'
|
||||
export default {
|
||||
props: ['config', 'modelId', 'isPreview', 'origin', 'id'],
|
||||
data() {
|
||||
return {
|
||||
dataForm: {
|
||||
data: ''
|
||||
},
|
||||
formConf: {},
|
||||
key: +new Date(),
|
||||
btnLoading: false,
|
||||
loading: true,
|
||||
isAdd: false,
|
||||
userInfo: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getOkText() {
|
||||
const text = this.formConf.confirmButtonTextI18nCode ?
|
||||
this.$t(this.formConf.confirmButtonTextI18nCode, this.formConf.confirmButtonText) :
|
||||
this.formConf.confirmButtonText;
|
||||
return text || this.$t('common.okText');
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
this.formConf = JSON.parse(this.config.formData)
|
||||
this.loading = true
|
||||
this.initData()
|
||||
},
|
||||
initData() {
|
||||
this.$nextTick(() => {
|
||||
if (this.origin === 'scan') {
|
||||
let extra = {
|
||||
modelId: this.modelId,
|
||||
id: this.id,
|
||||
type: 2
|
||||
}
|
||||
uni.setStorageSync('dynamicModelExtra', extra)
|
||||
getModelInfo(this.modelId, this.id).then(res => {
|
||||
this.dataForm = res.data
|
||||
if (!this.dataForm.data) return
|
||||
this.formData = JSON.parse(this.dataForm.data)
|
||||
this.fillFormData(this.formConf, this.formData)
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.formData = {}
|
||||
this.loading = false
|
||||
this.isAdd = true
|
||||
this.fillFormData(this.formConf, this.formData)
|
||||
}
|
||||
this.key = +new Date()
|
||||
})
|
||||
},
|
||||
fillFormData(form, data) {
|
||||
const loop = list => {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i]
|
||||
let vModel = item.__vModel__
|
||||
let config = item.__config__
|
||||
if (vModel) {
|
||||
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
|
||||
if (!config.isSubTable) config.defaultValue = val
|
||||
if (this.isAdd || config.isSubTable) { //新增时候,默认当前
|
||||
if (config.defaultCurrent) {
|
||||
if (config.jnpfKey === 'datePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
let format = this.jnpf.handelFormat(item.format)
|
||||
let dateStr = this.jnpf.toDate(new Date().getTime(), format)
|
||||
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
|
||||
'-01 00:00:00' : format === 'yyyy-MM-dd' ?
|
||||
' 00:00:00' : ''
|
||||
val = new Date(dateStr + time).getTime()
|
||||
config.defaultValue = val
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'timePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
config.defaultValue = this.jnpf.toDate(new Date(), item.format)
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.organizeIds :
|
||||
this.userInfo.organizeId
|
||||
}
|
||||
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.positionIds :
|
||||
this.userInfo.positionId
|
||||
}
|
||||
const userId = this.userInfo.userId
|
||||
if (config.jnpfKey === 'userSelect' && userId) {
|
||||
config.defaultValue = item.multiple ? [userId] : userId;
|
||||
}
|
||||
if (config.jnpfKey === 'usersSelect' && userId) {
|
||||
config.defaultValue = [userId + '--user'];
|
||||
}
|
||||
if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
|
||||
config.defaultValue = this.userInfo.signImg
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.origin === 'scan') this.$set(item, 'disabled', true)
|
||||
let noShow = !config.noShow ? false : config.noShow
|
||||
let isVisibility = false
|
||||
if (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes(
|
||||
'app'))) isVisibility = true
|
||||
this.$set(config, 'isVisibility', isVisibility)
|
||||
this.$set(config, 'noShow', noShow)
|
||||
} else {
|
||||
let noShow = false,
|
||||
isVisibility = false
|
||||
if (!config.visibility || (Array.isArray(config.visibility) && config.visibility.includes(
|
||||
'app'))) isVisibility = true
|
||||
this.$set(config, 'isVisibility', isVisibility)
|
||||
this.$set(config, 'noShow', noShow)
|
||||
}
|
||||
if (config && config.children && Array.isArray(config.children)) loop(config.children)
|
||||
}
|
||||
}
|
||||
loop(form.fields)
|
||||
},
|
||||
sumbitForm(data, callback) {
|
||||
if (!data) return
|
||||
this.btnLoading = true
|
||||
this.dataForm.data = JSON.stringify(data)
|
||||
if (callback && typeof callback === "function") callback()
|
||||
createModel(this.modelId, this.dataForm).then(res => {
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
this.btnLoading = false
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
this.btnLoading = false
|
||||
})
|
||||
},
|
||||
submit() {
|
||||
if (this.isPreview) return this.$u.toast('功能预览不支持数据保存')
|
||||
this.$refs.dynamicForm && this.$refs.dynamicForm.submitForm()
|
||||
},
|
||||
resetForm() {
|
||||
this.loading = true
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
this.$refs.dynamicForm && this.$refs.dynamicForm.resetForm()
|
||||
this.init()
|
||||
this.key = +new Date()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
1051
pages/apply/dynamicModelList/components/list/index.vue
Normal file
273
pages/apply/dynamicModelList/components/list/list.vue
Normal file
@@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<view class="list u-p-b-20 u-p-l-20 u-p-r-20" ref="tableRef">
|
||||
<view class="list-box">
|
||||
<SwipeItem :list="list" :buttons="options" @action="actionClick" ref="swipeItem" :marginB="20">
|
||||
<template v-slot="{ item }">
|
||||
<view class="item" @tap.stop="goDetail(item)">
|
||||
<view class="item-content">
|
||||
<!-- 左侧信息区 -->
|
||||
<view class="item-left">
|
||||
<!-- 单号 + 普通标签(核心修改区域) -->
|
||||
<view class="item-row item-header">
|
||||
<!-- 新增:普通标签 -->
|
||||
<view class="flow-tag">单号</view>
|
||||
<text class="content unit-name">{{ item.billNo }}</text>
|
||||
</view>
|
||||
<view class="item-row">
|
||||
<text class="label">申请单位:</text>
|
||||
<text class="content unit-name">{{ item.applyDepName }}</text>
|
||||
</view>
|
||||
<view class="item-row">
|
||||
<text class="label">申请人员:</text>
|
||||
<text class="content">{{ item.applyUser}}</text>
|
||||
</view>
|
||||
<view class="item-row">
|
||||
<text class="label">创建时间:</text>
|
||||
<text class="content">{{ formatTime(item.create_time) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 右侧状态图 -->
|
||||
<view class="item-right">
|
||||
<image
|
||||
v-if="item.approveStatusName == '未审核'"
|
||||
src="../../img/UNAPPROVED.png"
|
||||
mode="widthFix"
|
||||
class="status-img" />
|
||||
<image
|
||||
v-if="item.approveStatusName == '审批中'"
|
||||
src="../../img/APPROVING.png"
|
||||
mode="widthFix"
|
||||
class="status-img" />
|
||||
<image
|
||||
v-if="item.approveStatusName == '已审批'"
|
||||
src="../../img/APPROVED.png"
|
||||
mode="widthFix"
|
||||
class="status-img" />
|
||||
<image
|
||||
v-if="item.approveStatusName == '已驳回'"
|
||||
src="../../img/REJECTED.png"
|
||||
mode="widthFix"
|
||||
class="status-img" />
|
||||
<image
|
||||
v-if="item.approveStatusName == '已作废'"
|
||||
src="../../img/INVALID.png"
|
||||
mode="widthFix"
|
||||
class="status-img" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</SwipeItem>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 脚本部分无需修改,保持原逻辑
|
||||
import { useDefineSetting } from '@/utils/useDefineSetting';
|
||||
import tableCell from '../tableCell.vue'
|
||||
import SwipeItem from "@/components/SwipeItem/index"
|
||||
export default {
|
||||
emits: ['selectCheckbox', 'handleClick', 'handleMoreClick', 'goDetail', 'relationFormClick', 'update:modelValue'],
|
||||
components: {
|
||||
tableCell,
|
||||
SwipeItem
|
||||
},
|
||||
props: [
|
||||
'config',
|
||||
'list',
|
||||
'actionOptions',
|
||||
'showSelect',
|
||||
'checkedAll',
|
||||
'modelValue',
|
||||
'isMoreBtn',
|
||||
'customBtnsList'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
selectData: [],
|
||||
useDefine: useDefineSetting()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
checkedAll: {
|
||||
handler(val) {
|
||||
this.handleCheckAll()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
if (!this.customBtnsList?.length) return this.actionOptions;
|
||||
return [{
|
||||
text: this.$t('common.moreText'),
|
||||
value: 'more',
|
||||
style: {
|
||||
backgroundColor: '#007aff'
|
||||
}
|
||||
},
|
||||
...this.actionOptions,
|
||||
];
|
||||
},
|
||||
showCheckbox() {
|
||||
return this.showSelect
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatTime(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
},
|
||||
getStatusClass(statusName) {
|
||||
switch (statusName) {
|
||||
case '已审批':
|
||||
return 'status-approved';
|
||||
case '未审核':
|
||||
return 'status-unchecked';
|
||||
default:
|
||||
return 'status-other';
|
||||
}
|
||||
},
|
||||
relationFormClick(item, column) {
|
||||
this.$emit('relationFormClick', item, column)
|
||||
},
|
||||
goDetail(item) {
|
||||
this.$emit('goDetail', item)
|
||||
},
|
||||
actionClick(data) {
|
||||
const { index, value } = data
|
||||
if (value === 'remove') return this.$emit('handleClick', index)
|
||||
if (value === 'more') return this.$emit('handleMoreClick', index)
|
||||
},
|
||||
checkboxChange(e, item) {
|
||||
const isSelected = e.value;
|
||||
const selectedItemsSet = new Set(this.selectData.map(selectedItem => selectedItem.id));
|
||||
if (isSelected) {
|
||||
selectedItemsSet.add(item.id);
|
||||
} else {
|
||||
selectedItemsSet.delete(item.id);
|
||||
}
|
||||
this.selectData = [...selectedItemsSet.values()].map(id => {
|
||||
return this.list.find(listItem => listItem.id === id);
|
||||
});
|
||||
this.$emit('selectCheckbox', this.selectData);
|
||||
},
|
||||
handleCheckAll() {
|
||||
this.selectData = []
|
||||
if (this.checkedAll) this.selectData = this.list.filter(o => o.checked)
|
||||
this.$emit('selectCheckbox', this.selectData);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
background-color: #f0f2f6;
|
||||
.list-box {
|
||||
.item {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
|
||||
.item-content {
|
||||
display: flex;
|
||||
align-items: flex-start; /* 改为顶部对齐,避免标签错位 */
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8rpx; /* 调整行间距 */
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.label {
|
||||
font-size: 26rpx;
|
||||
color: #909399;
|
||||
min-width: 140rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
.content {
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
// 单号+标签的布局样式(核心新增)
|
||||
.item-header {
|
||||
align-items: center;
|
||||
gap: 10rpx; // 标签、单号、单号值之间的间距
|
||||
// 普通标签样式
|
||||
.flow-tag {
|
||||
font-size: 22rpx;
|
||||
color: #1677ff;
|
||||
background: #e8f3ff;
|
||||
padding: 2rpx 8rpx;
|
||||
border-radius: 4rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
// 单号文本样式
|
||||
.bill-label {
|
||||
font-size: 26rpx;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
// 流程名称样式(对应图中的“管理员的动火审批流程”)
|
||||
.flow-name {
|
||||
font-size: 28rpx;
|
||||
color: #1E293B;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
&.status-approved {
|
||||
background-color: #67c23a;
|
||||
}
|
||||
&.status-unchecked {
|
||||
background-color: #e6a23c;
|
||||
}
|
||||
&.status-other {
|
||||
background-color: #909399;
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧状态图样式
|
||||
.item-right {
|
||||
width: 100rpx;
|
||||
height: 160rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.status-img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
224
pages/apply/dynamicModelList/components/parser/index.vue
Normal file
@@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<u-form :model="formData" ref="dataForm" :errorType="['toast']" label-position="left" label-width="150">
|
||||
<u-form-item :label="item.label" :prop="item.id" v-for="(item, i) in formConfCopy" :key="`${item.id}-${i}`">
|
||||
<JnpfInput v-if="useInputList.includes(item.__config__.jnpfKey)" input-align='right'
|
||||
v-model="formData[item.id]" :placeholder="textPrefix+item.label" clearable />
|
||||
<template v-if="['inputNumber','calculate'].includes(item.__config__.jnpfKey)">
|
||||
<JnpfInputNumber v-model="formData[item.id]" :precision="item.precision"
|
||||
:placeholder="textPrefix+item.__config__.label" v-if="item.__config__.isFromParam" />
|
||||
<JnpfNumberRange v-model="formData[item.id]"
|
||||
:precision="!item.precision && item.__config__.jnpfKey=='calculate'?0:item.precision" v-else />
|
||||
</template>
|
||||
<template v-if="['rate', 'slider'].includes(item.__config__.jnpfKey)">
|
||||
<JnpfNumberRange v-model="formData[item.id]" :precision="item.allowHalf ? 1 : 0" />
|
||||
</template>
|
||||
<JnpfSelect
|
||||
v-if="useSelectList.includes(item.__config__.jnpfKey)"
|
||||
v-model="formData[item.id]"
|
||||
:placeholder="selectPrefix+item.label"
|
||||
:options="item.options || []"
|
||||
:props="item.props || { label: 'label', value: 'value' }"
|
||||
:multiple="!!item.searchMultiple"
|
||||
:key="`select-${item.id}-${key}`"
|
||||
filterable
|
||||
/>
|
||||
|
||||
<JnpfCascader v-if="item.__config__.jnpfKey==='cascader'" v-model="formData[item.id]"
|
||||
:placeholder="selectPrefix+item.label" :options="item.options || []" :props="item.props" filterable
|
||||
:showAllLevels="item.showAllLevels" :multiple="item.searchMultiple" />
|
||||
<JnpfAutoComplete v-if="item.__config__.jnpfKey==='autoComplete'" v-model="formData[item.id]"
|
||||
:interfaceName="item.interfaceName" :placeholder="selectPrefix+item.label"
|
||||
:interfaceId="item.interfaceId" :total="item.total" :templateJson="item.templateJson"
|
||||
:formData='formData' :relationField="item.relationField" :propsValue="item.propsValue"
|
||||
:clearable='item.clearable' />
|
||||
<JnpfGroupSelect v-if="item.__config__.jnpfKey==='groupSelect'" v-model="formData[item.id]"
|
||||
:vModel='item.id' :multiple="item.searchMultiple" :disabled="item.disabled"
|
||||
:placeholder="selectPrefix+item.label" :ableIds="item.ableIds" :selectType="item.selectType" />
|
||||
<JnpfRoleSelect v-if="item.__config__.jnpfKey==='roleSelect'" v-model="formData[item.id]"
|
||||
:multiple="item.searchMultiple" :disabled="item.disabled" :placeholder="selectPrefix+item.label"
|
||||
:ableIds="item.ableIds" :selectType="item.selectType" />
|
||||
<JnpfOrganizeSelect v-if="['organizeSelect','currOrganize'].includes(item.__config__.jnpfKey)"
|
||||
v-model="formData[item.id]" :placeholder="selectPrefix+item.label"
|
||||
:multiple="item.__config__.jnpfKey === 'currOrganize' ? true : item.searchMultiple"
|
||||
:ableIds="item.ableIds" :selectType="item.selectType" />
|
||||
<JnpfPosSelect v-if="['posSelect','currPosition'].includes(item.__config__.jnpfKey)"
|
||||
v-model="formData[item.id]" :placeholder="selectPrefix+item.label" :ableIds="item.ableIds"
|
||||
:selectType="item.selectType"
|
||||
:multiple="item.__config__.jnpfKey === 'currPosition' ? true : item.searchMultiple" />
|
||||
<JnpfUserSelect v-if="['userSelect','createUser', 'modifyUser'].includes(item.__config__.jnpfKey)"
|
||||
v-model="formData[item.id]" :placeholder="selectPrefix+item.label" :ableDepIds="item.ableDepIds"
|
||||
:ableIds="item.ableIds" :selectType="item.selectType!='custom'?'all':'custom'"
|
||||
:multiple="item.searchMultiple" />
|
||||
<JnpfUsersSelect v-if="item.__config__.jnpfKey==='usersSelect'" v-model="formData[item.id]"
|
||||
:placeholder="selectPrefix+item.label" :clearable="item.clearable" />
|
||||
<JnpfTreeSelect v-if="item.__config__.jnpfKey==='treeSelect'" v-model="formData[item.id]"
|
||||
:options="item.options || []" :props="item.props" :placeholder="selectPrefix+item.label" filterable
|
||||
:multiple="item.searchMultiple" />
|
||||
<JnpfAreaSelect v-if="item.__config__.jnpfKey==='areaSelect'" v-model="formData[item.id]"
|
||||
:placeholder="selectPrefix+item.label" :level="item.level" :multiple="item.searchMultiple" />
|
||||
|
||||
<!-- 日期/时间选择 -->
|
||||
<template v-if="useDateList.includes(item.__config__.jnpfKey)">
|
||||
<JnpfDatePicker v-model="formData[item.id]" :format='item.format' v-if="item.__config__.isFromParam" />
|
||||
<JnpfDateRange v-model="formData[item.id]" :format='item.format' v-else />
|
||||
</template>
|
||||
<JnpfTimeRange v-if="item.__config__.jnpfKey==='timePicker'" v-model="formData[item.id]"
|
||||
:format='item.format' />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect'];
|
||||
const useSelectList = ['radio', 'checkbox', 'select'];
|
||||
const useInputList = ['input', 'textarea', 'text', 'link', 'billRule', 'location'];
|
||||
const useDateList = ['createTime', 'modifyTime', 'datePicker', 'dateCalculate'];
|
||||
const useArrList = ['cascader', 'address', 'numInput', 'calculate', ...useDateList]
|
||||
|
||||
export default {
|
||||
props: ['formConf', 'webType', 'searchFormData'],
|
||||
data() {
|
||||
return {
|
||||
useInputList,
|
||||
useDateList,
|
||||
useSelectList,
|
||||
formConfCopy: [], // 初始化为空,避免提前克隆
|
||||
formData: {},
|
||||
key: +new Date(),
|
||||
textPrefix: this.$t('common.inputTextPrefix') + ' ',
|
||||
selectPrefix: this.$t('common.chooseTextPrefix') + ' ',
|
||||
}
|
||||
},
|
||||
// 核心:深度监听formConf变化,确保数据同步
|
||||
watch: {
|
||||
// 监听父组件传递的formConf(深度+立即执行)
|
||||
formConf: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (!newVal) return;
|
||||
// 重新克隆最新的配置
|
||||
this.formConfCopy = this.$u.deepClone(newVal);
|
||||
// 延迟初始化,确保DOM更新
|
||||
this.$nextTick(() => {
|
||||
this.initRelationForm(this.formConfCopy);
|
||||
// 初始化时彻底跳过接口请求
|
||||
this.initFormData(this.formConfCopy, this.formData);
|
||||
});
|
||||
}
|
||||
},
|
||||
// 监听搜索数据变化
|
||||
searchFormData: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.formData = this.$u.deepClone(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 初始化表单数据(彻底跳过接口请求)
|
||||
*/
|
||||
initFormData(componentList, formData) {
|
||||
console.log('Parser接收的配置:', componentList);
|
||||
if (!componentList || !Array.isArray(componentList)) return;
|
||||
|
||||
componentList.forEach(cur => {
|
||||
const config = cur.__config__ || {};
|
||||
if (cur.id && formData[cur.id] === undefined) {
|
||||
// 初始化表单默认值
|
||||
formData[cur.id] = cur.value || (cur.searchMultiple ? [] : '');
|
||||
}
|
||||
|
||||
// 原接口逻辑全部注释,彻底跳过
|
||||
/*
|
||||
if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
|
||||
if (config.dataType === 'dictionary' && config.dictionaryType) {
|
||||
getDictionaryDataSelector(config.dictionaryType).then(res => {
|
||||
cur.options = res.data.list || []
|
||||
this.key = +new Date()
|
||||
this.resetForm()
|
||||
})
|
||||
}
|
||||
if (config.dataType === 'dynamic' && config.propsUrl) {
|
||||
const query = {
|
||||
paramList: this.jnpf.getParamList(config.templateJson) || []
|
||||
};
|
||||
getDataInterfaceRes(config.propsUrl, query).then(res => {
|
||||
let list = res.data || []
|
||||
cur.options = Array.isArray(list) ? list : [];
|
||||
this.key = +new Date()
|
||||
this.resetForm()
|
||||
})
|
||||
}
|
||||
}
|
||||
*/
|
||||
});
|
||||
|
||||
// 更新key强制刷新组件
|
||||
this.key = +new Date();
|
||||
},
|
||||
|
||||
/**
|
||||
* 初始化关联表单配置
|
||||
*/
|
||||
initRelationForm(componentList) {
|
||||
if (!componentList) return;
|
||||
componentList.forEach(cur => {
|
||||
const config = cur.__config__ || {};
|
||||
if (config.jnpfKey == 'relationFormAttr' || config.jnpfKey == 'popupAttr') {
|
||||
const relationKey = cur.relationField?.split("_jnpfTable_")[0];
|
||||
if (!relationKey) return;
|
||||
componentList.forEach(item => {
|
||||
const noVisibility = Array.isArray(item.__config__?.visibility) && !item.__config__.visibility.includes('app');
|
||||
if ((relationKey == item.id) && (noVisibility || !!item.__config__?.noShow)) {
|
||||
cur.__config__.noShow = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (cur.__config__?.children && cur.__config__.children.length) {
|
||||
this.initRelationForm(cur.__config__.children);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取表单数据(空值处理)
|
||||
*/
|
||||
allCondition() {
|
||||
const result = {...this.formData};
|
||||
for (let key in result) {
|
||||
if (result[key] === 0) continue;
|
||||
if (!result[key] || (Array.isArray(result[key]) && result[key].length === 0)) {
|
||||
delete result[key];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*/
|
||||
submitForm() {
|
||||
if (!this.$refs.dataForm) {
|
||||
this.$emit('submit', this.allCondition());
|
||||
return;
|
||||
}
|
||||
this.$refs.dataForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
this.$emit('submit', this.allCondition());
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
resetForm() {
|
||||
if (this.$refs.dataForm) {
|
||||
this.$refs.dataForm.resetFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
125
pages/apply/dynamicModelList/components/tableCell.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<uni-collapse class='collapse' accordion ref="collapse" @change="collapseChange" @click.stop>
|
||||
<uni-collapse-item :key="key">
|
||||
<template v-slot:title>
|
||||
<view class="u-font-24 u-flex">
|
||||
<view style="width: 124rpx;text-align: right;">
|
||||
<text>{{label+':'}}</text>
|
||||
</view>
|
||||
<text style="color: #606266;" class="u-m-l-28">{{$t('app.apply.expandData')}}</text>
|
||||
</view>
|
||||
</template>
|
||||
<view class="collapse-item" v-for="(item,d) in dataList" :key="d">
|
||||
<view v-if="d<allPageLen" class="item-cell-children">
|
||||
<view class="item-cell" v-for="(cld,c) in children" :key="c">
|
||||
<text
|
||||
class="item-cell-label">{{cld.labelI18nCode ? $t(cld.labelI18nCode, cld.label) : cld.label}}:</text>
|
||||
<text class="item-cell-content"
|
||||
v-if="['calculate','inputNumber'].includes(cld.__config__.jnpfKey)">
|
||||
{{toThousands(item[cld.vModel],cld) }}
|
||||
</text>
|
||||
<text class="item-cell-content text-primary"
|
||||
v-else-if="cld.__config__.jnpfKey === 'relationForm'"
|
||||
@click.stop="relationFormClick(item,cld)">
|
||||
{{item[cld.vModel]}}
|
||||
</text>
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'sign'">
|
||||
<JnpfSign v-model="item[cld.vModel]" align="left" detailed />
|
||||
</view>
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'signature'">
|
||||
<JnpfSignature v-model="item[cld.vModel]" align="left" detailed />
|
||||
</view>
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadImg'" @click.stop>
|
||||
<JnpfUploadImg v-model="item[cld.vModel]" detailed simple
|
||||
v-if="item[cld.vModel]&&item[cld.vModel].length" />
|
||||
</view>
|
||||
<!-- #ifndef APP-HARMONY -->
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadFile'" @click.stop>
|
||||
<JnpfUploadFile v-model="item[cld.vModel]" detailed
|
||||
v-if="item[cld.vModel]&&item[cld.vModel].length" align="left" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-HARMONY -->
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'uploadFile'" @click.stop>
|
||||
<JnpfUploadFileH v-model="item[cld.vModel]" detailed
|
||||
v-if="item[cld.vModel]&&item[cld.vModel].length" align="left" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'rate'">
|
||||
<JnpfRate v-model="item[cld.vModel]" :max="cld.count" :allowHalf="cld.allowHalf" disabled />
|
||||
</view>
|
||||
<view class="item-cell-content item-cell-slider" v-else-if="cld.jnpfKey == 'slider'">
|
||||
<JnpfSlider v-model="item[cld.vModel]" :min="cld.min" :max="cld.max" :step="cld.step"
|
||||
disabled />
|
||||
</view>
|
||||
<view class="item-cell-content" v-else-if="cld.jnpfKey == 'input'">
|
||||
<JnpfInput v-model="item[cld.vModel]" detailed showOverflow :useMask="cld.useMask"
|
||||
:maskConfig="cld.maskConfig" align='left' />
|
||||
</view>
|
||||
<text class="item-cell-content" v-else>{{item[cld.vModel]}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="loadMore" @click.stop="loadMore" v-if="!isAllData&&this.dataList.length>allPageLen">
|
||||
加载更多
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: ['childList', 'label', 'children', 'pageLen', 'thousands', 'thousandsField'],
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
isAllData: false,
|
||||
key: +new Date(),
|
||||
allPageLen: 3
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
childList: {
|
||||
handler(val) {
|
||||
this.dataList = val || []
|
||||
this.allPageLen = this.pageLen
|
||||
this.children.map(o => {
|
||||
if (o.childLabel.length > 4) o.childLabel = o.childLabel.substring(0, 4)
|
||||
})
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toThousands(val, column) {
|
||||
if (val) {
|
||||
let valList = val.toString().split('.')
|
||||
let num = Number(valList[0])
|
||||
let newVal = column.thousands ? num.toLocaleString() : num
|
||||
return valList[1] ? newVal + '.' + valList[1] : newVal
|
||||
}
|
||||
},
|
||||
relationFormClick(item, cld) {
|
||||
this.$emit('cRelationForm', item, cld)
|
||||
},
|
||||
loadMore() {
|
||||
this.allPageLen = this.childList.length
|
||||
this.isAllData = true
|
||||
this.resizeCollapse()
|
||||
},
|
||||
collapseChange(e) {
|
||||
if (!e) {
|
||||
this.isAllData = false
|
||||
setTimeout(() => {
|
||||
this.allPageLen = this.pageLen
|
||||
}, 500)
|
||||
}
|
||||
this.resizeCollapse()
|
||||
},
|
||||
resizeCollapse() {
|
||||
setTimeout(() => {
|
||||
this.$refs.collapse && this.$refs.collapse.resize()
|
||||
}, 50)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
450
pages/apply/dynamicModelList/detail.vue
Normal file
@@ -0,0 +1,450 @@
|
||||
<template>
|
||||
<view class="dynamicModel-form-v jnpf-wrap jnpf-wrap-form" v-if="showPage">
|
||||
<Parser :formConf="formConf" :formData="formData" ref="dynamicForm" v-if="!loading" :key="key"
|
||||
@toDetail="toDetail" />
|
||||
<view class="u-m-t-20 dataLog-box u-flex-col u-m-b-20" v-if="formConf.dataLog && !setting.noDataLog">
|
||||
<view class="title u-flex">
|
||||
<u-icon name=" icon-ym-generator-menu" custom-prefix="icon-ym"></u-icon>
|
||||
<text class="u-m-l-10">修改记录</text>
|
||||
</view>
|
||||
<view class="dataLog-v" v-if="dataLogList.length">
|
||||
<dataLog :dataLogList="dataLogList"></dataLog>
|
||||
</view>
|
||||
<JnpfEmpty v-else />
|
||||
</view>
|
||||
<view class="buttom-actions">
|
||||
<CustomButton class="u-flex buttom-btn-left-inner" v-if="showMoreBtn" btnText="更多" btnType="more"
|
||||
iconName="more-dot-fill" size="28" @handleBtn="showAction = $event" :btnLoading="loading" />
|
||||
<template v-if="showEditBtn">
|
||||
<CustomButton class="u-flex buttom-btn-left-inner" :btnText="$t('common.cancelText')"
|
||||
btnIcon="icon-ym icon-ym-add-cancel" customIcon :btnLoading="loading" />
|
||||
<u-button class="buttom-btn" type="primary" @click.stop="handleEdit" :loading="loading">
|
||||
{{labelS.btn_edit}}
|
||||
</u-button>
|
||||
</template>
|
||||
<u-button class="cancel" @click.stop="jnpf.goBack()"
|
||||
v-if="!showEditBtn && !showMoreBtn">{{$t('common.cancelText')}}</u-button>
|
||||
</view>
|
||||
<u-select :list="actionList" v-model="showAction" @confirm="selectBtnconfirm" />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import CustomButton from '@/components/CustomButton'
|
||||
import {
|
||||
getConfigData,
|
||||
getOnlineLog,
|
||||
getModelInfo,
|
||||
getDataChange,
|
||||
launchFlow
|
||||
} from "@/api/apply/visualDev";
|
||||
import {
|
||||
getRelationFormDetail,
|
||||
getDataInterfaceRes
|
||||
} from "@/api/common.js";
|
||||
import Parser from "./components/detail/Parser";
|
||||
import dataLog from '@/components/dataLog'
|
||||
import deepClone from '../../../uni_modules/vk-uview-ui/libs/function/deepClone';
|
||||
export default {
|
||||
components: {
|
||||
Parser,
|
||||
dataLog,
|
||||
CustomButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataLogList: [],
|
||||
actionList: [],
|
||||
showAction: false,
|
||||
showPage: false,
|
||||
loading: true,
|
||||
isPreview: "0",
|
||||
modelId: "",
|
||||
formConf: {},
|
||||
formData: {},
|
||||
dataForm: {
|
||||
id: "",
|
||||
data: "",
|
||||
},
|
||||
btnType: "",
|
||||
formPermissionList: {},
|
||||
formList: [],
|
||||
labelS: {}
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
this.init(option)
|
||||
},
|
||||
computed: {
|
||||
showMoreBtn() {
|
||||
if (this.actionList.length && !this.setting?.noShowBtn || 0 && this.setting?.noDataLog) return true
|
||||
return false
|
||||
},
|
||||
showEditBtn() {
|
||||
if (this.btnType === 'btn_edit' && !this.setting.noShowBtn && this.setting.enableEdit) return true
|
||||
return false
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
setTimeout(() => {
|
||||
uni.$emit('initCollapse')
|
||||
}, 100)
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off("refresh");
|
||||
},
|
||||
methods: {
|
||||
init(option) {
|
||||
// 提取公共解析方法
|
||||
const parseConfig = (rawConfig) => {
|
||||
try {
|
||||
return JSON.parse(this.jnpf.base64.decode(rawConfig)) || {}
|
||||
} catch (error) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
// 使用解构赋值提取配置
|
||||
const config = parseConfig(option.config)
|
||||
const {
|
||||
currentMenu,
|
||||
btnType = "",
|
||||
labelS: rawLabelS = {},
|
||||
modelId,
|
||||
isPreview = "0",
|
||||
id = ""
|
||||
} = config
|
||||
// 缓存解析结果
|
||||
const formPermissionList = currentMenu ? JSON.parse(decodeURIComponent(currentMenu)) : [];
|
||||
// 批量属性赋值
|
||||
Object.assign(this, {
|
||||
formPermissionList,
|
||||
formList: formPermissionList.formList || [],
|
||||
btnType,
|
||||
labelS: {
|
||||
btn_edit: this.$t('common.editText'),
|
||||
...rawLabelS
|
||||
},
|
||||
modelId,
|
||||
isPreview,
|
||||
dataForm: {
|
||||
id
|
||||
},
|
||||
setting: config
|
||||
})
|
||||
// 设置导航栏标题
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.$t('common.detailText')
|
||||
})
|
||||
this.getConfigData();
|
||||
uni.$on("refresh", () => {
|
||||
this.getConfigData();
|
||||
});
|
||||
},
|
||||
// 自定义按钮事件
|
||||
selectBtnconfirm(e) {
|
||||
var i = this.actionList.findIndex((item) => {
|
||||
return item.value == e[0].value
|
||||
})
|
||||
const item = this.actionList[i].actionConfig
|
||||
const row = this.formData
|
||||
// 自定义启用规则判断
|
||||
if (item.btnType == 1) this.handlePopup(item, row)
|
||||
if (item.btnType == 2) this.handleScriptFunc(item, row)
|
||||
if (item.btnType == 3) this.handleInterface(item, row)
|
||||
if (item.btnType == 4) this.handleLaunchFlow(item, [row])
|
||||
},
|
||||
//自定义按钮发起流程
|
||||
handleLaunchFlow(item, records) {
|
||||
const data = deepClone(item.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) {
|
||||
let data = {
|
||||
config: item,
|
||||
modelId: this.modelId,
|
||||
id: row.id,
|
||||
row,
|
||||
}
|
||||
data = encodeURIComponent(JSON.stringify(data))
|
||||
uni.navigateTo({
|
||||
url: '/pages/apply/customBtn/index?data=' + data
|
||||
})
|
||||
},
|
||||
//自定义按钮JS操作
|
||||
handleScriptFunc(item, row) {
|
||||
const parameter = {
|
||||
data: row,
|
||||
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, index) {
|
||||
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) => {
|
||||
let query = {
|
||||
paramList: this.jnpf.getParamList(item.templateJson, data) || [],
|
||||
}
|
||||
getDataInterfaceRes(item.interfaceId, query).then(res => {
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none'
|
||||
})
|
||||
if (item.isRefresh) this.initData();
|
||||
})
|
||||
}
|
||||
const handleFun = () => {
|
||||
handlerData();
|
||||
};
|
||||
if (!item.useConfirm) return handleFun()
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: item.confirmTitle || '确认执行此操作',
|
||||
success: (res) => {
|
||||
if (!res.cancel) handleFun()
|
||||
}
|
||||
})
|
||||
},
|
||||
getOnlineLog() {
|
||||
getOnlineLog(this.setting.modelId, this.setting.id).then(res => {
|
||||
this.dataLogList = res.data.list || []
|
||||
})
|
||||
},
|
||||
getConfigData() {
|
||||
this.loading = true;
|
||||
console.log(this.modelId,'modelId-------')
|
||||
getConfigData(this.modelId).then((res) => {
|
||||
if (res.code !== 200 || !res.data) {
|
||||
uni.showToast({
|
||||
title: "暂无此页面",
|
||||
icon: "none",
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.formConf = res.data.formData ? JSON.parse(res.data.formData) : {};
|
||||
this.actionList = this.formConf?.appCustomBtns || []
|
||||
this.actionList.map((o) => {
|
||||
if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode, o.label)
|
||||
})
|
||||
this.beforeInit(this.formConf.fields || []);
|
||||
this.showPage = true;
|
||||
this.key = +new Date();
|
||||
this.initData();
|
||||
});
|
||||
},
|
||||
beforeInit(fields) {
|
||||
const loop = (list) => {
|
||||
for (var index = 0; index < list.length; index++) {
|
||||
const config = list[index].__config__;
|
||||
if (config.children && config.children.length) loop(config.children);
|
||||
if (config.jnpfKey == "tableGrid") {
|
||||
let newList = [];
|
||||
for (var i = 0; i < config.children.length; i++) {
|
||||
let element = config.children[i];
|
||||
for (var j = 0; j < element.__config__.children.length; j++) {
|
||||
let item = element.__config__.children[j];
|
||||
newList.push(...item.__config__.children);
|
||||
}
|
||||
}
|
||||
list.splice(index, 1, ...newList);
|
||||
}
|
||||
}
|
||||
};
|
||||
loop(fields);
|
||||
},
|
||||
initData() {
|
||||
this.$nextTick(() => {
|
||||
if (this.dataForm.id) {
|
||||
let extra = {
|
||||
modelId: this.modelId,
|
||||
id: this.dataForm.id,
|
||||
type: 2,
|
||||
};
|
||||
uni.setStorageSync('dynamicModelExtra', extra)
|
||||
this.getRelationFormDetail()
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.getOnlineLog()
|
||||
})
|
||||
this.key = +new Date();
|
||||
});
|
||||
},
|
||||
getRelationFormDetail() {
|
||||
const processResponse = (res) => {
|
||||
this.dataForm = res.data;
|
||||
this.loading = false;
|
||||
if (!this.dataForm.data) return;
|
||||
this.formData = {
|
||||
...JSON.parse(this.dataForm.data),
|
||||
id: this.dataForm.id,
|
||||
};
|
||||
this.fillFormData(this.formConf, this.formData);
|
||||
this.initRelationForm(this.formConf.fields);
|
||||
};
|
||||
let requestParams = {
|
||||
id: this.dataForm.id,
|
||||
menuId: this.setting.menuId
|
||||
};
|
||||
if (this.setting?.sourceRelationForm) {
|
||||
if (this.setting.propsValue) requestParams.propsValue = this.setting.propsValue;
|
||||
}
|
||||
getDataChange(requestParams, this.modelId).then(res => {
|
||||
processResponse(res)
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
})
|
||||
},
|
||||
fillFormData(form, data) {
|
||||
const loop = (list, parent) => {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i];
|
||||
if (item.__vModel__) {
|
||||
if (
|
||||
item.__config__.jnpfKey === "relationForm" ||
|
||||
item.__config__.jnpfKey === "popupSelect"
|
||||
) {
|
||||
item.__config__.defaultValue = data[item.__vModel__ + "_id"];
|
||||
this.$set(item, "name", item.__config__.defaultValue || "");
|
||||
} else {
|
||||
let val = data.hasOwnProperty(item.__vModel__) ?
|
||||
data[item.__vModel__] :
|
||||
item.__config__.defaultValue;
|
||||
item.__config__.defaultValue = val;
|
||||
}
|
||||
if (this.formPermissionList.useFormPermission) {
|
||||
let id = item.__config__.isSubTable ?
|
||||
parent.__vModel__ + "-" + item.__vModel__ :
|
||||
item.__vModel__;
|
||||
let noShow = true;
|
||||
if (this.formList && this.formList.length) {
|
||||
noShow = !this.formList.some((o) => o.enCode === id);
|
||||
}
|
||||
noShow = item.__config__.noShow ? item.__config__.noShow : noShow;
|
||||
this.$set(item.__config__, "noShow", noShow);
|
||||
}
|
||||
} else {
|
||||
if (['relationFormAttr', 'popupAttr'].includes(item.__config__.jnpfKey)) {
|
||||
item.__config__.defaultValue =
|
||||
data[item.relationField.split('_jnpfTable_')[0] + '_' + item.showField];
|
||||
}
|
||||
}
|
||||
if (
|
||||
item.__config__ &&
|
||||
item.__config__.children &&
|
||||
Array.isArray(item.__config__.children)
|
||||
) {
|
||||
loop(item.__config__.children, item);
|
||||
}
|
||||
}
|
||||
};
|
||||
loop(form.fields);
|
||||
this.loading = false;
|
||||
},
|
||||
initRelationForm(componentList) {
|
||||
componentList.forEach((cur) => {
|
||||
const config = cur.__config__;
|
||||
if (
|
||||
config.jnpfKey == "relationFormAttr" ||
|
||||
config.jnpfKey == "popupAttr"
|
||||
) {
|
||||
const relationKey = cur.relationField.split("_jnpfTable_")[0];
|
||||
componentList.forEach((item) => {
|
||||
const noVisibility =
|
||||
Array.isArray(item.__config__.visibility) &&
|
||||
!item.__config__.visibility.includes("app");
|
||||
if (
|
||||
relationKey == item.__vModel__ &&
|
||||
(noVisibility || !!item.__config__.noShow) && !cur.__vModel__
|
||||
) {
|
||||
cur.__config__.noShow = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (cur.__config__.children && cur.__config__.children.length)
|
||||
this.initRelationForm(cur.__config__.children);
|
||||
});
|
||||
},
|
||||
toDetail(item) {
|
||||
const id = item.__config__.defaultValue;
|
||||
if (!id) return;
|
||||
let config = {
|
||||
modelId: item.modelId,
|
||||
id: id,
|
||||
formTitle: "详情",
|
||||
noShowBtn: 1,
|
||||
noDataLog: 1,
|
||||
sourceRelationForm: item?.sourceRelationForm || false,
|
||||
propsValue: item?.propsValue || ''
|
||||
};
|
||||
this.$nextTick(() => {
|
||||
const url =
|
||||
"/pages/apply/dynamicModel/detail?config=" +
|
||||
this.jnpf.base64.encode(JSON.stringify(config));
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
});
|
||||
},
|
||||
handleEdit() {
|
||||
if (this.setting.disableEdit) return;
|
||||
const currentMenu = encodeURIComponent(JSON.stringify(this.formPermissionList));
|
||||
let config = {
|
||||
modelId: this.modelId,
|
||||
isPreview: this.isPreview,
|
||||
id: this.setting.id,
|
||||
btnType: "btn_edit",
|
||||
currentMenu,
|
||||
list: this.setting.list,
|
||||
index: this.setting.index,
|
||||
menuId: this.setting.menuId
|
||||
};
|
||||
const url =
|
||||
"/pages/apply/dynamicModel/form?config=" +
|
||||
this.jnpf.base64.encode(JSON.stringify(config));
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
</style>
|
||||
1645
pages/apply/dynamicModelList/form.vue
Normal file
BIN
pages/apply/dynamicModelList/img/APPROVED.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
pages/apply/dynamicModelList/img/APPROVING.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
pages/apply/dynamicModelList/img/INVALID.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
pages/apply/dynamicModelList/img/REJECTED.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
pages/apply/dynamicModelList/img/UNAPPROVED.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
121
pages/apply/dynamicModelList/index.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<view class="dynamicModel-v">
|
||||
<!-- <Form :config="config" :modelId="modelId" :isPreview="isPreview" /> -->
|
||||
<List :config="config" :modelId="modelId" :isPreview="isPreview"
|
||||
:title="title" :menuId="menuId" ref="List" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Form from "./components/form/index.vue";
|
||||
import List from "./components/list/index.vue";
|
||||
import {
|
||||
getFlowStartFormId
|
||||
} from "@/api/workFlow/flowEngine";
|
||||
import {
|
||||
getConfigData
|
||||
} from "@/api/apply/visualDev";
|
||||
import {
|
||||
useBaseStore
|
||||
} from '@/store/modules/base'
|
||||
import { computed } from "vue";
|
||||
const baseStore = useBaseStore()
|
||||
|
||||
export default {
|
||||
name: "dynamicModel",
|
||||
components: {
|
||||
Form,
|
||||
List,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
webType: "",
|
||||
showPage: false,
|
||||
isPreview: false,
|
||||
modelId: "",
|
||||
menuId: "",
|
||||
title: "",
|
||||
config: {},
|
||||
preview: false,
|
||||
flowId: '',
|
||||
enableFlow: 0,
|
||||
};
|
||||
},
|
||||
onLoad(obj) {
|
||||
// baseStore.getDictionaryDataAll()
|
||||
this.config = JSON.parse(this.jnpf.base64.decode(obj.config)) || {};
|
||||
this.isPreview = this.config.isPreview || false;
|
||||
this.enableFlow = this.config.type === 9 ? 1 : 0;
|
||||
this.title = this.config.name || "";
|
||||
this.modelId = this.config.id || "";
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.title,
|
||||
});
|
||||
// if (!this.enableFlow) return this.getConfigData();
|
||||
this.flowId = this.config.moduleId
|
||||
// this.getModelId()
|
||||
},
|
||||
methods: {
|
||||
// 获取流程版本ID和发起节点表单ID
|
||||
getModelId() {
|
||||
getFlowStartFormId(this.flowId).then(res => {
|
||||
if (!res.data || !res.data.formId) return;
|
||||
this.config.moduleId = res.data.formId
|
||||
// this.getConfigData();
|
||||
})
|
||||
},
|
||||
getConfigData() {
|
||||
getConfigData(this.config.moduleId, this.menuId).then((res) => {
|
||||
if (res.code !== 200 || !res.data) return this.handleError('暂无此页面')
|
||||
if (this.enableFlow && res.data.webType == 1) return this.jump();
|
||||
this.config = {
|
||||
...res.data,
|
||||
...this.config,
|
||||
enableFlow: this.enableFlow,
|
||||
flowId: this.flowId
|
||||
};
|
||||
this.showPage = true;
|
||||
this.isPreview = !!this.config.isPreview;
|
||||
this.modelId = this.config.moduleId;
|
||||
this.menuId = this.config.id || "";
|
||||
this.webType = this.config.webType || 2;
|
||||
this.title = this.config.fullName || "";
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.title
|
||||
});
|
||||
});
|
||||
},
|
||||
jump() {
|
||||
const config = {
|
||||
id: "",
|
||||
flowId: this.flowId,
|
||||
opType: "-1",
|
||||
hideCancelBtn: true,
|
||||
hideSaveBtn: true
|
||||
};
|
||||
uni.redirectTo({
|
||||
url: "/pages/workFlow/flowBefore/index?config=" +
|
||||
this.jnpf.base64.encode(JSON.stringify(config)),
|
||||
fail: () => {
|
||||
this.$u.toast("暂无此页面");
|
||||
},
|
||||
});
|
||||
},
|
||||
handleError(msg) {
|
||||
this.$u.toast(msg);
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.dynamicModel-v {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
180
pages/apply/dynamicModelList/scanForm.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<view class="dynamicModel-v">
|
||||
<template v-if="showPage">
|
||||
<view class="jnpf-wrap jnpf-wrap-form" v-if="config.mt == 2">
|
||||
<JnpfParser :formConf="formConf" ref="dynamicForm" @submit="sumbitForm" :key="key" />
|
||||
</view>
|
||||
<template v-else>
|
||||
<FlowForm ref="flowForm" />
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FlowForm from '@/pages/workFlow/flowBefore/flowForm'
|
||||
import {
|
||||
getConfigData,
|
||||
getModelInfo
|
||||
} from '@/api/apply/visualDev'
|
||||
export default {
|
||||
name: 'scanForm',
|
||||
components: {
|
||||
FlowForm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
webType: '',
|
||||
showPage: false,
|
||||
origin: '',
|
||||
id: '',
|
||||
config: {},
|
||||
formConf: {},
|
||||
key: +new Date(),
|
||||
isAdd: false,
|
||||
userInfo: {}
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
this.config = JSON.parse(option.config)
|
||||
this.initData()
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
this.showPage = false
|
||||
if (this.config.mt == 2) {
|
||||
this.getConfigData()
|
||||
} else {
|
||||
this.isAdd = true
|
||||
let data = {
|
||||
flowId: this.config.fid,
|
||||
id: this.config.pid,
|
||||
formType: 2,
|
||||
opType: this.config.opt,
|
||||
taskId: this.config.ftid
|
||||
}
|
||||
this.showPage = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.flowForm.init(data)
|
||||
})
|
||||
}
|
||||
},
|
||||
getConfigData() {
|
||||
getConfigData(this.config.mid).then(res => {
|
||||
if (res.code !== 200 || !res.data) {
|
||||
uni.showToast({
|
||||
title: '暂无此页面',
|
||||
icon: 'none',
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
this.formConf = JSON.parse(res.data.formData)
|
||||
uni.setNavigationBarTitle({
|
||||
title: res.data.fullName
|
||||
})
|
||||
let extra = {
|
||||
modelId: this.config.mid,
|
||||
id: this.config.id,
|
||||
type: this.config.mt
|
||||
}
|
||||
uni.setStorageSync('dynamicModelExtra', extra)
|
||||
getModelInfo(this.config.mid, this.config.id).then(res => {
|
||||
if (!res.data.data) return
|
||||
let formData = JSON.parse(res.data.data)
|
||||
this.fillFormData(this.formConf, formData)
|
||||
this.$nextTick(() => {
|
||||
this.showPage = true
|
||||
this.key = +new Date()
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
fillFormData(form, data) {
|
||||
const loop = list => {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i]
|
||||
let vModel = item.__vModel__
|
||||
let config = item.__config__
|
||||
if (vModel) {
|
||||
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
|
||||
if (!config.isSubTable) config.defaultValue = val
|
||||
if (this.isAdd || config.isSubTable) { //新增时候,默认当前
|
||||
if (config.defaultCurrent) {
|
||||
if (config.jnpfKey === 'datePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
let format = this.jnpf.handelFormat(item.format)
|
||||
let dateStr = this.jnpf.toDate(new Date().getTime(), format)
|
||||
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
|
||||
'-01 00:00:00' : format === 'yyyy-MM-dd' ?
|
||||
' 00:00:00' : ''
|
||||
val = new Date(dateStr + time).getTime()
|
||||
config.defaultValue = val
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'timePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
config.defaultValue = this.jnpf.toDate(new Date(), item.format)
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.organizeIds :
|
||||
this.userInfo.organizeId
|
||||
}
|
||||
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.positionIds :
|
||||
this.userInfo.positionId
|
||||
}
|
||||
const userId = this.userInfo.userId
|
||||
if (config.jnpfKey === 'userSelect' && userId) {
|
||||
config.defaultValue = item.multiple ? [userId] : userId;
|
||||
}
|
||||
if (config.jnpfKey === 'usersSelect' && userId) {
|
||||
config.defaultValue = [userId + '--user'];
|
||||
}
|
||||
if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
|
||||
config.defaultValue = this.userInfo.signImg
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$set(item, 'disabled', true)
|
||||
let noShow = !item.__config__.noShow ? false : item.__config__.noShow
|
||||
let isVisibility = false
|
||||
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
.__config__.visibility.includes('app'))) isVisibility = true
|
||||
this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
this.$set(item.__config__, 'noShow', noShow)
|
||||
} else {
|
||||
let noShow = false,
|
||||
isVisibility = false
|
||||
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
.__config__.visibility.includes('app'))) isVisibility = true
|
||||
this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
this.$set(item.__config__, 'noShow', noShow)
|
||||
}
|
||||
if (item.__config__ && item.__config__.jnpfKey !== 'table' && item.__config__.children && Array
|
||||
.isArray(item.__config__.children)) {
|
||||
loop(item.__config__.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
loop(form.fields)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
}
|
||||
|
||||
.dynamicModel-v {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
635
pages/index/indexWork.vue
Normal file
@@ -0,0 +1,635 @@
|
||||
<template>
|
||||
<view class="index_v">
|
||||
<!-- <u-sticky>
|
||||
<view class="head-tabs u-flex">
|
||||
<view class="head-tabs-item" @click="openPage('/pages/workFlow/flowTodo/index','approve')">
|
||||
<text class="icon-ym icon-ym-flowTodo-app u-m-r-4 icon-style" />
|
||||
<text class="u-font-24 head-tabs-name">审批中心</text>
|
||||
<u-badge type="error" :count="count" :absolute="true" :offset="offset" />
|
||||
</view>
|
||||
<view class="head-tabs-item" @click="openPage('/pages/workFlow/entrustAgent/index','entrust')">
|
||||
<text class="icon-ym icon-ym-flowDone-app u-m-r-4 icon-style" />
|
||||
<text class="u-font-24 head-tabs-name">委托代理</text>
|
||||
</view>
|
||||
<view class="head-tabs-item" @click="openPage('/pages/workFlow/schedule/index','schedule')">
|
||||
<text class="icon-ym icon-ym-flowDone-app u-m-r-4 icon-style" />
|
||||
<text class="u-font-24 head-tabs-name">日程</text>
|
||||
</view>
|
||||
<view class="head-tabs-item" @click="openPage('/pages/workFlow/document/index','document')">
|
||||
<text class="icon-ym icon-ym-flowCopy-app u-m-r-4 icon-style" />
|
||||
<text class="u-font-24 head-tabs-name">文档</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-sticky> -->
|
||||
<!-- <CommonPane :flowList="homeData.favoritesFlowList || []" :menuList="homeData.favoritesMenuList || []"
|
||||
type="collect" @launch="launch" v-if="homeData.favoritesEnable" @openPage="openPage" @addApp="addApp"
|
||||
:showAdd="true" :flowEnabled="homeData.flowEnabled" />
|
||||
|
||||
<CommonPane title="最近使用" :flowList="homeData.latelyUseFlowList || []" type="use"
|
||||
:menuList="homeData.latelyUseMenuList || []" @launch="launch" v-if="homeData.latelyUseEnable"
|
||||
@openPage="openPage" :flowEnabled="homeData.flowEnabled" />
|
||||
|
||||
<CommonPane title="最近常用" :flowList="homeData.commonUseFlowList || []" type="common"
|
||||
:menuList="homeData.commonUseMenuList || []" @launch="launch" v-if="homeData.commonUseEnable"
|
||||
@openPage="openPage" :flowEnabled="homeData.flowEnabled" /> -->
|
||||
|
||||
<CommonPaneSys title="" :flowList="[]" type="common"
|
||||
:menuList="homeData || []" @launch="launch" v-if="homeData"
|
||||
@openPage="openPage" />
|
||||
<view class="todo-list-wrap">
|
||||
<view class="todo-title">
|
||||
<view class="title-left">
|
||||
<view >待处理事项</view>
|
||||
<u-badge type="error" :count="count" :absolute="true" :offset="offset" />
|
||||
</view>
|
||||
<view class="title-right" @click="openToDoPage">
|
||||
工作信息
|
||||
<u-icon name="arrow-right" class="u-p-r-10"color="#666"></u-icon>
|
||||
</view>
|
||||
</view >
|
||||
<scroll-view
|
||||
v-if="todoList.length > 0"
|
||||
class="todo-scroll-container"
|
||||
scroll-y
|
||||
show-scrollbar="true"
|
||||
:style="{height: todoList.length > 3 ? '350rpx' : 'auto'}"
|
||||
>
|
||||
<view
|
||||
class="todo-item"
|
||||
v-for="(item, index) in todoList"
|
||||
:key="index"
|
||||
@click="goDetail(item)"
|
||||
>
|
||||
<!-- 顶部单号栏 -->
|
||||
<view class="todo-header">
|
||||
<view class="todo-code">
|
||||
<text class="code-label">单号</text>
|
||||
<text class="code-value">{{item.businessInfo.billNo}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 信息列表 -->
|
||||
<view class="todo-info-list">
|
||||
<view class="todo-info-row">
|
||||
<text class="info-label">单据类型:</text>
|
||||
<text class="info-value">{{item.processInstance.name}}</text>
|
||||
</view>
|
||||
<view class="todo-info-row">
|
||||
<text class="info-label">发起人:</text>
|
||||
<text class="info-value">{{item.processInstance.startUserNickname}}</text>
|
||||
</view>
|
||||
<view class="todo-info-row">
|
||||
<text class="info-label">创建时间:</text>
|
||||
<text class="info-value">{{formatTime(item.createTime) || '2026-01-15 14:16:36'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="empty-container" v-else>
|
||||
<view>
|
||||
<image
|
||||
class="empty-icon"
|
||||
src="https://app.cdn.jnpfsoft.com/image/message/nodata.png"
|
||||
mode="widthFix"
|
||||
/></view>
|
||||
<text class="empty-tip">暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
<PasswordPopup @submit="dataFormSubmit" :passwordShow="passwordShow" :formData="baseForm"></PasswordPopup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
getFlowTodoCount
|
||||
} from "@/api/workFlow/flowEngine";
|
||||
import {
|
||||
getMenuData,
|
||||
getDonePage
|
||||
} from "@/api/index/index";
|
||||
import {
|
||||
useUserStore
|
||||
} from '@/store/modules/user'
|
||||
import {
|
||||
useChatStore
|
||||
} from '@/store/modules/chat'
|
||||
import {
|
||||
updatePassword,
|
||||
updatePasswordMessage
|
||||
} from '@/api/common.js'
|
||||
import chat from '@/libs/chat'
|
||||
import CommonPane from '@/components/CommonPane'
|
||||
import CommonPaneSys from '@/components/CommonPane/indexSystem'
|
||||
import PasswordPopup from './components/PasswordPopup'
|
||||
import {
|
||||
useLocale
|
||||
} from '@/locale/useLocale';
|
||||
const chatStore = useChatStore()
|
||||
export default {
|
||||
components: {
|
||||
CommonPane,
|
||||
CommonPaneSys,
|
||||
PasswordPopup
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
homeData: [],
|
||||
count: 0,
|
||||
offset: [430, 525],
|
||||
menuList: [],
|
||||
passwordShow: false,
|
||||
baseForm: {
|
||||
passwordStrengthLimit: 0,
|
||||
passwordLengthMin: false,
|
||||
passwordLengthMinNumber: 0,
|
||||
containsNumbers: false,
|
||||
includeLowercaseLetters: false,
|
||||
includeUppercaseLetters: false,
|
||||
containsCharacters: false,
|
||||
mandatoryModificationOfInitialPassword: 0,
|
||||
},
|
||||
userInfo: {},
|
||||
todoList: []
|
||||
};
|
||||
},
|
||||
// onLoad() {
|
||||
// const chatStore = useChatStore()
|
||||
// if (!chatStore.getSocket) chat && chat.initSocket()
|
||||
// const userStore = useUserStore()
|
||||
// userStore.getCurrentUser().then(() => {
|
||||
// this.getSystemName()
|
||||
// }).catch(() => {
|
||||
// setTimeout(() => {
|
||||
// userStore.resetToken()
|
||||
// setTimeout(() => {
|
||||
// uni.reLaunch({
|
||||
// url: '/pages/login/index'
|
||||
// })
|
||||
// }, 500)
|
||||
// }, 1000)
|
||||
// })
|
||||
// const {
|
||||
// changeLocale
|
||||
// } = useLocale();
|
||||
// changeLocale(uni.getLocale())
|
||||
// },
|
||||
onShow(e) {
|
||||
this.init()
|
||||
},
|
||||
computed: {
|
||||
baseURL() {
|
||||
return this.define.baseURL;
|
||||
},
|
||||
token() {
|
||||
return uni.getStorageSync('token')
|
||||
},
|
||||
report() {
|
||||
return this.define.report;
|
||||
},
|
||||
pcURL() {
|
||||
return this.define.pcURL;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 时间格式化
|
||||
formatTime(timestamp) {
|
||||
if (!timestamp) return '-';
|
||||
const date = new Date(timestamp);
|
||||
return `${date.getFullYear()}-${this.padZero(date.getMonth() + 1)}-${this.padZero(date.getDate())} ${this.padZero(date.getHours())}:${this.padZero(date.getMinutes())}:${this.padZero(date.getSeconds())}`;
|
||||
},
|
||||
padZero(num) {
|
||||
return num.toString().padStart(2, '0');
|
||||
},
|
||||
init() {
|
||||
this.getMenuData()
|
||||
this.getDonePage()
|
||||
// this.getFlowCount()
|
||||
// this.getSystemConfig()
|
||||
},
|
||||
// 获取系统配置
|
||||
getSystemConfig() {
|
||||
updatePasswordMessage();
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
const config = uni.getStorageSync('sysConfigInfo') || {};
|
||||
this.$nextTick(() => {
|
||||
this.baseForm.passwordStrengthLimit = config.passwordStrengthLimit
|
||||
this.baseForm.passwordLengthMin = config.passwordLengthMin
|
||||
this.baseForm.passwordLengthMinNumber = config.passwordLengthMinNumber
|
||||
this.baseForm.containsNumbers = config.containsNumbers
|
||||
this.baseForm.includeLowercaseLetters = config.includeLowercaseLetters
|
||||
this.baseForm.containsCharacters = config.containsCharacters
|
||||
this.baseForm.mandatoryModificationOfInitialPassword = config
|
||||
.mandatoryModificationOfInitialPassword
|
||||
if (this.userInfo.changePasswordDate == null && config
|
||||
.mandatoryModificationOfInitialPassword == 1)
|
||||
this.passwordShow = true;
|
||||
})
|
||||
},
|
||||
dataFormSubmit(query) {
|
||||
updatePassword(query).then((res) => {
|
||||
const userStore = useUserStore()
|
||||
// userStore.logout().then(() => {
|
||||
// uni.reLaunch({
|
||||
// url: "/pages/login/index",
|
||||
// });
|
||||
// });
|
||||
})
|
||||
},
|
||||
//获取并设置应用名称
|
||||
getSystemName() {
|
||||
const userInfo = uni.getStorageSync("userInfo");
|
||||
this.menuList = uni.getStorageSync("menuList");
|
||||
uni.setNavigationBarTitle({
|
||||
title: userInfo.systemName
|
||||
})
|
||||
},
|
||||
launch(item) {
|
||||
console.log(item,'item-------')
|
||||
if (item.tabType == 'flow') return this.JumpFlow(item)
|
||||
if (item.tabType == 'menu') return this.JumpApply(item)
|
||||
},
|
||||
JumpApply(item) {
|
||||
let url = "/pages/apply/dynamicModelList/index?config=" + this.jnpf.base64.encode(JSON.stringify(item))
|
||||
// if (item.type == 1) {
|
||||
// getChildList(item.id).then(res => {
|
||||
// this.listChild = res.data || []
|
||||
// this.handleProperty(this.listChild)
|
||||
// this.$nextTick(() => {
|
||||
// uni.navigateTo({
|
||||
// url: "/pages/apply/catalog/index?config=" +
|
||||
// this.jnpf.base64.encode(JSON.stringify(this.listChild[0])),
|
||||
// fail: (err) => {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// },
|
||||
// });
|
||||
// })
|
||||
// })
|
||||
// return;
|
||||
// }
|
||||
// let url = ''
|
||||
// // 2-页面 11-回传表单
|
||||
// if (item.type == 2 || item.type == 11) {
|
||||
// if (!item.pageAddress) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// url = item.pageAddress + "?menuId=" + item.id + "&fullName=" + item.fullName
|
||||
// }
|
||||
// // 3-在线表单 9-流程
|
||||
// if (item.type == 3 || item.type == 9) {
|
||||
// if (!item.moduleId) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// url = "/pages/apply/dynamicModel/index?config=" + this.jnpf.base64.encode(JSON.stringify(item))
|
||||
// }
|
||||
// // 外链
|
||||
// if (item.type == 7) {
|
||||
// if (!item.pageAddress) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// url = "/pages/apply/externalLink/index?url=" + encodeURIComponent(item.pageAddress) + "&fullName=" +
|
||||
// item.fullName + "&type=" + item.type
|
||||
// }
|
||||
// // 报表(原)
|
||||
// if (item.type == 5) {
|
||||
// if (!item.moduleId) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// userInfo = uni.getStorageSync('userInfo') || {}
|
||||
// const appCode = userInfo.systemCode
|
||||
// const urlPre = encodeURIComponent(
|
||||
// `${this.report}/preview.html?id=${item.moduleId}&token=${this.token}&appCode=${appCode}&page=1&from=menu`
|
||||
// )
|
||||
// url = "/pages/apply/externalLink/index?url=" + urlPre + "&fullName=" + item.fullName + "&type=" +
|
||||
// item.type
|
||||
// }
|
||||
// // 报表
|
||||
// if (item.type == 10) {
|
||||
// if (!item.moduleId) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// const urlPre = encodeURIComponent(
|
||||
// `${this.pcURL}/reportPreview?id=${item.moduleId}&token=${this.token}&from=app`
|
||||
// );
|
||||
// url = "/pages/apply/externalLink/index?url=" + urlPre + "&fullName=" + item.fullName + "&type=" +
|
||||
// item.type
|
||||
// }
|
||||
// // 门户
|
||||
// if (item.type == 8) {
|
||||
// if (!item.moduleId) {
|
||||
// this.$u.toast("暂无此页面");
|
||||
// return;
|
||||
// }
|
||||
// url = "/pages/portal/scanPortal/index?id=" + item.moduleId + "&portalType=1&fullName=" +
|
||||
// item.fullName
|
||||
// }
|
||||
if (!url) return;
|
||||
uni.navigateTo({
|
||||
url,
|
||||
fail: () => {
|
||||
this.$u.toast("暂无此页面");
|
||||
},
|
||||
});
|
||||
},
|
||||
handleProperty(list) {
|
||||
const loop = (par) => {
|
||||
par.map(o => {
|
||||
if (o?.propertyJson) {
|
||||
let propertyJson = JSON.parse(o.propertyJson);
|
||||
this.$set(o, "iconBackground", propertyJson.iconBackgroundColor || "");
|
||||
this.$set(o, "moduleId", propertyJson.moduleId || "");
|
||||
}
|
||||
if (o?.children && o?.children?.length) loop(o.children)
|
||||
})
|
||||
}
|
||||
loop(list)
|
||||
},
|
||||
JumpFlow(item) {
|
||||
const config = {
|
||||
id: "",
|
||||
flowId: item.id,
|
||||
opType: "-1",
|
||||
isFlow: 1
|
||||
};
|
||||
uni.navigateTo({
|
||||
url: "/pages/workFlow/flowBefore/index?config=" +
|
||||
this.jnpf.base64.encode(JSON.stringify(config))
|
||||
});
|
||||
},
|
||||
//获取审批中心待办条数
|
||||
getFlowCount() {
|
||||
getFlowTodoCount().then((res) => {
|
||||
this.count = res.data.flowTodo || 0;
|
||||
})
|
||||
},
|
||||
getMenuData() {
|
||||
getMenuData().then((res) => {
|
||||
const list = res?.data
|
||||
this.homeData = list
|
||||
}).catch(() => {
|
||||
const userStore = useUserStore()
|
||||
setTimeout(() => {
|
||||
userStore.resetToken()
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index'
|
||||
})
|
||||
}, 500)
|
||||
}, 1000)
|
||||
});
|
||||
},
|
||||
// 获取待办信息
|
||||
getDonePage() {
|
||||
const params = {
|
||||
pageNo:1,
|
||||
pageSize: 3
|
||||
}
|
||||
getDonePage(params).then(res=>{
|
||||
console.log(res,'res-------')
|
||||
this.count = res.data.total
|
||||
this.todoList = res.data.list || []
|
||||
})
|
||||
},
|
||||
//更多按钮
|
||||
openPage(path, type) {
|
||||
if (type === 'approve') {
|
||||
let workFlowList = this.menuList.filter(o => o.enCode === 'workFlow')
|
||||
console.log(this.menuList,'menuList---------')
|
||||
if (!workFlowList[0]?.children?.length) return this.$u.toast('暂无权限')
|
||||
}
|
||||
if (!path) return;
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
});
|
||||
},
|
||||
// 跳转待办
|
||||
openToDoPage() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/workFlow/flowTodo/index',
|
||||
});
|
||||
},
|
||||
//添加按钮
|
||||
addApp(path) {
|
||||
if (!path) return;
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
});
|
||||
},
|
||||
// 待处理事项跳转详情
|
||||
goDetail(item) {
|
||||
console.log(item,'item----------')
|
||||
const config = {
|
||||
opType: item.opType,
|
||||
operatorId: item.id,
|
||||
category: '1',
|
||||
...item
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/pages/workFlow/flowBefore/index?config=' +
|
||||
this.jnpf.base64.encode(JSON.stringify(config))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f0f2f6;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.index_v {
|
||||
.head-tabs {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
justify-content: space-between;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.head-tabs-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
color: #303133;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
height: 120rpx;
|
||||
|
||||
.icon-style {
|
||||
font-size: 42rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.head-tabs-name {
|
||||
color: #303133;
|
||||
font-family: PingFang SC;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.todo-list-wrap {
|
||||
background: #fff;
|
||||
margin: 20rpx 0;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
.todo-title {
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.title-left {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
/* 滚动容器样式 */
|
||||
.todo-scroll-container {
|
||||
width: 100%;
|
||||
max-height: 680rpx !important;
|
||||
::-webkit-scrollbar {
|
||||
width: 4rpx;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #e5e5e5;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
.todo-item {
|
||||
// display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
/* 最后一项去掉下划线 */
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
.todo-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 15rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.todo-content {
|
||||
flex: 1;
|
||||
}
|
||||
.todo-code {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.todo-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
.todo-meta {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 8rpx;
|
||||
display: flex;
|
||||
// justify-content: space-between;
|
||||
}
|
||||
.todo-time {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
|
||||
.todo-list-wrap {
|
||||
background: #fff;
|
||||
margin: 20rpx 0;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
.todo-title {
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.title-left {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.title-right {
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
/* 滚动容器 */
|
||||
.todo-scroll-container {
|
||||
width: 100%;
|
||||
max-height: 350rpx;
|
||||
::-webkit-scrollbar {
|
||||
width: 4rpx;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #e5e5e5;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
}
|
||||
/* 每个待办项容器 */
|
||||
.todo-item {
|
||||
background: #f9f9f9;
|
||||
border-radius: 8rpx;
|
||||
padding: 15rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
/* 单号栏 */
|
||||
.todo-header {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
.todo-header .code-label{
|
||||
font-size: 22rpx;
|
||||
color: #1677ff;
|
||||
background: #e8f3ff;
|
||||
padding: 2rpx 8rpx;
|
||||
border-radius: 4rpx;
|
||||
font-weight: 500;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
.todo-code {
|
||||
display: flex;
|
||||
}
|
||||
/* 信息列表 */
|
||||
.todo-info-list {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
/* 每一行信息 */
|
||||
.todo-info-row {
|
||||
display: flex;
|
||||
margin-bottom: 8rpx;
|
||||
color: #666;
|
||||
}
|
||||
.info-label {
|
||||
width: 120rpx; /* 固定宽度,对齐更整齐 */
|
||||
color: #999;
|
||||
}
|
||||
.info-value {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
}
|
||||
// 暂无数据样式
|
||||
.empty-container {
|
||||
text-align: center;
|
||||
}
|
||||
.empty-icon {
|
||||
width: 260rpx;
|
||||
height: auto;
|
||||
margin-bottom: 20rpx;
|
||||
// opacity: 0.5;
|
||||
}
|
||||
.empty-tip {
|
||||
font-size: 28rpx;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,7 @@
|
||||
<view class="launch-img">
|
||||
<image :src="startup" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="copyright">Copyright © 2025 引迈信息技术有限公司出品</view>
|
||||
<view class="copyright">Copyright © 2025 CSCN技术有限公司出品</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
<view class="login-bg">
|
||||
<image src="../../static/image/login-bg.jpg" mode="widthFix"></image>
|
||||
<view class="logoImg">
|
||||
<u-image :src="appIcon" mode="widthFix" :border-radius="20" width="160" height="160">
|
||||
<image src="../../static/image/logoT.png" mode="widthFix"></image>
|
||||
<!-- <u-image src="../../static/image/logo.png" mode="widthFix" :border-radius="20" width="160" height="160">
|
||||
<template #error>
|
||||
<u-image :src="logoImg" mode="widthFix" width="160" height="160">
|
||||
</u-image>
|
||||
</template>
|
||||
</u-image>
|
||||
</u-image> -->
|
||||
</view>
|
||||
<view class="login-version">
|
||||
<!-- <view class="login-version">
|
||||
<view class="login-version-text">{{sysConfigInfo.sysVersion || define.sysVersion}}</view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="logo-hd u-flex-col">
|
||||
<view class="loginSwitch u-flex-col">
|
||||
<view class="loginInputBox u-flex-col" v-show="!isSso && !ssoLoading">
|
||||
<u-form :model="formData" :rules="rules" ref="dataForm" :errorType="['toast']" label-position="left"
|
||||
label-width="150" label-align="left">
|
||||
<u-form-item prop="account" :borderBottom="false">
|
||||
<u-input input-align='left' v-model="formData.account" placeholder="请输入帐号" @focus="onFocus"
|
||||
<u-form-item v-show="false" prop="account" :borderBottom="false">
|
||||
<u-input input-align='left' v-model="formData.tenantName" placeholder="请输入租户名称" @focus="onFocus"
|
||||
@blur="onBlur" border border-color="#F0F1F3" placeholder-style="#9D9D9D">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item prop="username" :borderBottom="false">
|
||||
<u-input input-align='left' v-model="formData.username" placeholder="请输入帐号" @focus="onFocus"
|
||||
@blur="onBlur" border border-color="#F0F1F3" placeholder-style="#9D9D9D">
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
@@ -107,13 +113,14 @@
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<view class="copyright" v-if="isKeyUp">{{copyright}}</view>
|
||||
<view class="copyright">{{copyright}}</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
login,
|
||||
getConfig,
|
||||
getPermissionInfo,
|
||||
getByName,
|
||||
getCallback,
|
||||
otherlogin,
|
||||
getLoginConfig,
|
||||
@@ -135,7 +142,8 @@
|
||||
imgUrl: '',
|
||||
loading: false,
|
||||
formData: {
|
||||
account: "",
|
||||
tenantName: "000000",
|
||||
username: "",
|
||||
password: "",
|
||||
code: "",
|
||||
origin: 'password'
|
||||
@@ -144,7 +152,7 @@
|
||||
codeLength: 4,
|
||||
isCode: false,
|
||||
rules: {
|
||||
account: [{
|
||||
username: [{
|
||||
required: true,
|
||||
message: '请输入账号',
|
||||
trigger: 'blur',
|
||||
@@ -158,7 +166,7 @@
|
||||
sysConfigInfo: {},
|
||||
appIcon: '',
|
||||
sysName: '',
|
||||
copyright: '',
|
||||
copyright: '综合监控系统',
|
||||
socialsList: [],
|
||||
show: false,
|
||||
tenantUserInfo: [],
|
||||
@@ -203,23 +211,25 @@
|
||||
}
|
||||
this.ssoTicket = uni.getStorageSync('ssoTicket')
|
||||
this.sysConfigInfo = uni.getStorageSync('sysConfigInfo')
|
||||
console.log(this.define,'define-------------')
|
||||
this.appIcon = !!this.sysConfigInfo.appIcon ? this.baseURL + this.sysConfigInfo.appIcon :
|
||||
logoImg
|
||||
this.sysName = !!this.sysConfigInfo.companyName ? this.sysConfigInfo.sysName :
|
||||
'JNPF快速开发平台'
|
||||
this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright :
|
||||
this.define.copyright
|
||||
// this.copyright = !!this.sysConfigInfo.copyright ? this.sysConfigInfo.copyright :
|
||||
// this.define.copyright
|
||||
// this.copyright = !!this.sysConfigInfo.copyright && this.sysConfigInfo.copyright
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.sysName
|
||||
})
|
||||
let needCode = uni.getStorageSync('app_loginNeedCode')
|
||||
this.isCode = needCode
|
||||
this.changeCode()
|
||||
this.getLoginConfig()
|
||||
// this.getLoginConfig()
|
||||
this.formData.password = '';
|
||||
if (options.data) {
|
||||
this.tenantUserInfo = JSON.parse(options.data)
|
||||
if (this.tenantUserInfo) this.show = true
|
||||
// if (this.tenantUserInfo) this.show = true
|
||||
}
|
||||
this.initAccount()
|
||||
// #ifndef H5
|
||||
@@ -228,6 +238,8 @@
|
||||
return this.isKeyUp
|
||||
})
|
||||
// #endif
|
||||
|
||||
this.initLoginConfig()
|
||||
},
|
||||
methods: {
|
||||
initAccount() {
|
||||
@@ -279,7 +291,7 @@
|
||||
if (this.tenantUserInfo.length == 1) {
|
||||
this.loginHandel()
|
||||
} else {
|
||||
this.show = true
|
||||
// this.show = true
|
||||
}
|
||||
} else {
|
||||
this.show = false
|
||||
@@ -442,14 +454,37 @@
|
||||
this.ssoLoading = false
|
||||
})
|
||||
},
|
||||
getCodeConfig(val) {
|
||||
if (!val) return
|
||||
getConfig(val).then(res => {
|
||||
this.needCode = !!res.data.enableVerificationCode
|
||||
if (this.needCode) {
|
||||
this.codeLength = res.data.verificationCodeNumber || 4
|
||||
this.changeCode()
|
||||
}
|
||||
|
||||
initLoginConfig() {
|
||||
// 1. 强制关闭SSO登录,显示账号密码登录
|
||||
this.isSso = false
|
||||
// 2. 关闭SSO加载状态,让页面正常显示
|
||||
this.ssoLoading = false
|
||||
// 3. 可选:配置第三方登录列表(如果需要显示微信/QQ登录)
|
||||
// 如需显示第三方登录,取消下面注释并调整配置;不需要则留空数组
|
||||
this.socialsList = [
|
||||
// 示例:微信登录配置(根据实际项目的icon/class调整)
|
||||
// {
|
||||
// enname: 'wechat_open',
|
||||
// name: '微信登录',
|
||||
// icon: 'icon-ym icon-ym-wechat' // 替换成项目真实的微信图标类名
|
||||
// },
|
||||
// 示例:QQ登录配置
|
||||
// {
|
||||
// enname: 'qq',
|
||||
// name: 'QQ登录',
|
||||
// icon: 'icon-ym icon-ym-qq' // 替换成项目真实的QQ图标类名
|
||||
// }
|
||||
]
|
||||
// 4. 可选:SSO相关配置(用不到可以不赋值)
|
||||
this.preUrl = ''
|
||||
this.ticketParams = ''
|
||||
},
|
||||
getCodeConfig() {
|
||||
const userStore = useUserStore()
|
||||
getByName(this.formData.tenantName).then(res => {
|
||||
const data = res.data
|
||||
userStore.setTenantId(data)
|
||||
})
|
||||
},
|
||||
changeCode() {
|
||||
@@ -464,14 +499,20 @@
|
||||
this.loading = true
|
||||
const password = md5Libs.md5(this.formData.password);
|
||||
const encryptPassword = this.jnpf.aesEncryption.encrypt(password);
|
||||
// let query = {
|
||||
// account: this.formData.account,
|
||||
// password: encryptPassword,
|
||||
// timestamp: this.timestamp,
|
||||
// code: this.formData.code,
|
||||
// origin: this.formData.origin,
|
||||
// jnpf_ticket: this.ssoTicket,
|
||||
// grant_type: 'password',
|
||||
// }
|
||||
let query = {
|
||||
account: this.formData.account,
|
||||
password: encryptPassword,
|
||||
timestamp: this.timestamp,
|
||||
code: this.formData.code,
|
||||
origin: this.formData.origin,
|
||||
jnpf_ticket: this.ssoTicket,
|
||||
grant_type: 'password',
|
||||
tenantName: this.formData.tenantName,
|
||||
username: this.formData.username,
|
||||
password: this.formData.password,
|
||||
rememberMe : false
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
const clientId = plus.push.getClientInfo().clientid;
|
||||
@@ -480,19 +521,30 @@
|
||||
// query.Client_Id = uni.getStorageSync('cid')
|
||||
// #endif
|
||||
login(query).then(res => {
|
||||
let token = res.data.token
|
||||
let token = res.data.accessToken
|
||||
userStore.setToken(token)
|
||||
this.rememberAccount()
|
||||
setTimeout(()=>{
|
||||
userStore.getCurrentUser().then(res => {
|
||||
this.loading = false
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
if(res.code == 0){
|
||||
getPermissionInfo().then(res=>{
|
||||
if(res.code == 0){
|
||||
userStore.setUserInfo(res.data)
|
||||
uni.switchTab({
|
||||
url: '/pages/index/indexWork'
|
||||
});
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},1000)
|
||||
}
|
||||
// setTimeout(()=>{
|
||||
// userStore.getCurrentUser().then(res => {
|
||||
// this.loading = false
|
||||
// uni.switchTab({
|
||||
// url: '/pages/index/index'
|
||||
// });
|
||||
// }).catch(() => {
|
||||
// this.loading = false
|
||||
// })
|
||||
// },1000)
|
||||
// getPermissionInfo
|
||||
}).catch((err) => {
|
||||
uni.showToast({
|
||||
title: err,
|
||||
@@ -571,8 +623,8 @@
|
||||
}
|
||||
|
||||
.logoImg {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
width: 260rpx;
|
||||
height: 260rpx;
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
/* #ifdef APP-PLUS */
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
bcg: 'u-type-primary-bg'
|
||||
}
|
||||
],
|
||||
copyright: 'Copyright © 2024 引迈信息技术有限公司出品',
|
||||
copyright: 'Copyright © 2024 CSCN技术有限公司出品',
|
||||
show: false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
watch: {
|
||||
option(v) {
|
||||
// #ifdef APP-PLUS
|
||||
console.log(v,'v--------')
|
||||
this.lsjFile && this.show();
|
||||
// #endif
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<view>
|
||||
<template v-if="config.formType == 1">
|
||||
<template >
|
||||
<dynamicForm ref="form" @eventReceiver="eventReceiver" @setBtnLoad="setBtnLoad" :config="config" />
|
||||
</template>
|
||||
<template v-if="config.formType == 2">
|
||||
<!-- <template v-if="config.formType == 2">
|
||||
<crmOrder ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='crmOrder'"
|
||||
:config="config" />
|
||||
<leaveApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='leaveApply'"
|
||||
@@ -12,7 +12,7 @@
|
||||
:config="config" />
|
||||
<revokeApply ref="form" @eventReceiver="eventReceiver" v-if="config.formEnCode==='revoke'"
|
||||
:config="config" />
|
||||
</template>
|
||||
</template> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -36,6 +36,15 @@
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
config:{
|
||||
handler(val){
|
||||
console.log(val,'val1233')
|
||||
},
|
||||
deep:true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
eventReceiver(formData, eventType) {
|
||||
this.$emit('eventReceiver', formData, eventType)
|
||||
|
||||
@@ -99,7 +99,9 @@
|
||||
import {
|
||||
createModel,
|
||||
updateModel,
|
||||
getOnlineLog
|
||||
getOnlineLog,
|
||||
getDesForm,
|
||||
getProcessBusinessInfo
|
||||
} from '@/api/apply/visualDev'
|
||||
import {
|
||||
createComment
|
||||
@@ -127,6 +129,8 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formConf: {},
|
||||
processBusinessInfo: {},
|
||||
dataLogList: [],
|
||||
dataLog: false,
|
||||
childFormKey: +new Date(),
|
||||
@@ -207,6 +211,7 @@
|
||||
onLoad(option) {
|
||||
if (!option.config) return this.jnpf.goBack()
|
||||
this.config = JSON.parse(this.jnpf.base64.decode(option.config))
|
||||
|
||||
uni.$on('operate', (data) => {
|
||||
this.btnLoading = true
|
||||
this[data.eventType + 'Handle'](data)
|
||||
@@ -450,7 +455,7 @@
|
||||
})
|
||||
})
|
||||
},
|
||||
init() {
|
||||
async init() {
|
||||
this.processId = this.config.id
|
||||
if (this.config.id) {
|
||||
let extra = {
|
||||
@@ -464,6 +469,10 @@
|
||||
}
|
||||
uni.setStorageSync('dynamicModelExtra', extra)
|
||||
}
|
||||
// 先获取id
|
||||
const res = await getProcessBusinessInfo(this.config.processInstance.id)
|
||||
console.log(res,'res----------')
|
||||
this.processBusinessInfo = res.data || {}
|
||||
/**
|
||||
* opType
|
||||
* -1 - 我发起的新建/编辑
|
||||
@@ -484,100 +493,110 @@
|
||||
};
|
||||
if (config.isFlow) query.isFlow = config.isFlow
|
||||
if (config.opType != "-1" && config.opType != '0') query.operatorId = config.operatorId;
|
||||
FlowTask(config?.taskId || config?.id || 0, query).then((res) => {
|
||||
this.flowInfo = res.data.flowInfo || {};
|
||||
this.properties = res.data.nodeProperties || {};
|
||||
this.auxiliaryInfo = this.properties.auxiliaryInfo
|
||||
this.$nextTick(() => {
|
||||
this.initApprovalField()
|
||||
})
|
||||
this.formInfo = res.data.formInfo || {};
|
||||
this.taskInfo = res.data.taskInfo || {};
|
||||
this.btnInfo = res.data.btnInfo || [];
|
||||
this.progressList = res.data.progressList || [];
|
||||
config.formOperates = res.data.formOperates || [];
|
||||
config.formType = this.formInfo.type
|
||||
const fullName =
|
||||
config.opType == "-1" ?
|
||||
this.flowInfo.fullName :
|
||||
this.taskInfo.fullName;
|
||||
config.fullName = fullName;
|
||||
this.title = this.flowInfo.fullName;
|
||||
this.thisStep = this.taskInfo.thisStep || "";
|
||||
if (config.status !== 0 && config.status !== 3) {
|
||||
this.title = this.thisStep ?
|
||||
config.fullName + "/" + this.thisStep :
|
||||
config.fullName;
|
||||
getDesForm(this.processBusinessInfo.dbformId).then((res) => {
|
||||
// this.flowInfo = res.data.flowInfo || {};
|
||||
// this.properties = res.data.nodeProperties || {};
|
||||
// this.auxiliaryInfo = this.properties.auxiliaryInfo
|
||||
// this.$nextTick(() => {
|
||||
// this.initApprovalField()
|
||||
// })
|
||||
const data = res.data ? JSON.parse(res.data) : {};
|
||||
console.log(data,'data---11')
|
||||
// this.formConf = JSON.parse(data.formData)
|
||||
this.config = {
|
||||
...data,
|
||||
formConf: data.formData
|
||||
}
|
||||
config.type = this.flowInfo.type;
|
||||
config.draftData = res.data.draftData || null;
|
||||
config.formData = res.data.formData || {};
|
||||
let dataId = config.formData.id
|
||||
config.formEnCode = this.formInfo.enCode;
|
||||
this.nodeList = res.data.nodeList || [];
|
||||
this.recordList = (res.data.recordList || []).reverse();
|
||||
config.formConf = this.formInfo.formData;
|
||||
if (config.formConf) {
|
||||
this.dataLog = JSON.parse(config.formConf).dataLog
|
||||
if (this.dataLog) this.getOnlineLog(dataId)
|
||||
}
|
||||
this.hasComment = this.flowInfo.flowNodes.global.hasComment;
|
||||
console.log(this.config,'config--')
|
||||
// this.$refs.child.$refs.form.init(this.formConf)
|
||||
// console.log(JSON.parse(data.formData),'判断---')
|
||||
// this.formInfo = res.data.formInfo || {};
|
||||
// this.taskInfo = res.data.taskInfo || {};
|
||||
// this.btnInfo = res.data.btnInfo || [];
|
||||
// this.progressList = res.data.progressList || [];
|
||||
// config.formOperates = res.data.formOperates || [];
|
||||
// config.formType = this.formInfo.type
|
||||
// const fullName =
|
||||
// config.opType == "-1" ?
|
||||
// this.flowInfo.fullName :
|
||||
// this.taskInfo.fullName;
|
||||
// config.fullName = fullName;
|
||||
// // this.title = this.flowInfo.fullName;
|
||||
// this.thisStep = this.taskInfo.thisStep || "";
|
||||
// if (config.status !== 0 && config.status !== 3) {
|
||||
// this.title = this.thisStep ?
|
||||
// config.fullName + "/" + this.thisStep :
|
||||
// config.fullName;
|
||||
// }
|
||||
// config.type = this.flowInfo.type;
|
||||
// config.draftData = res.data.draftData || null;
|
||||
// config.formData = res.data.formData || {};
|
||||
// let dataId = config.formData.id
|
||||
// config.formEnCode = this.formInfo.enCode;
|
||||
// this.nodeList = res.data.nodeList || [];
|
||||
// this.recordList = (res.data.recordList || []).reverse();
|
||||
// config.formConf = this.formInfo.formData;
|
||||
// if (config.formConf) {
|
||||
// this.dataLog = JSON.parse(config.formConf).dataLog
|
||||
// if (this.dataLog) this.getOnlineLog(dataId)
|
||||
// }
|
||||
// this.hasComment = this.flowInfo.flowNodes.global.hasComment;
|
||||
this.loading = false;
|
||||
this.formLoding = true;
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.config.formEnCode === "revoke" ? `${this.flowInfo.fullName}撤销申请` : this
|
||||
.flowInfo.fullName,
|
||||
});
|
||||
if (config.formRecords && config.title) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: config.title,
|
||||
});
|
||||
}
|
||||
this.flowUrgent = this.taskInfo.flowUrgent || 1;
|
||||
const getSelectInfo = () => {
|
||||
var obj = {
|
||||
value: this.flowUrgent,
|
||||
extra: "0",
|
||||
label: "普通",
|
||||
};
|
||||
this.flowUrgentList.forEach((e, i) => {
|
||||
if (e.value == this.flowUrgent) {
|
||||
obj.extra = i;
|
||||
obj.label = e.label;
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
this.selectflowUrgent = getSelectInfo();
|
||||
this.initRightBtnList();
|
||||
if (config.opType != "-1" && config.opType != "3") config.readonly =
|
||||
true;
|
||||
config.formOperates = [];
|
||||
if (config.opType == 0) {
|
||||
if (this.properties && this.properties && this.properties.formOperates) config
|
||||
.formOperates = this.properties.formOperates || [];
|
||||
} else {
|
||||
config.formOperates = res.data.formOperates || [];
|
||||
}
|
||||
this.getFlowStatus()
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
if (!this.$refs.child || !this.$refs.child.$refs.form) {
|
||||
uni.showToast({
|
||||
title: "暂无此流程表单",
|
||||
icon: "none",
|
||||
complete: () => {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$refs.child.$refs.form.init(config)
|
||||
});
|
||||
}, 100);
|
||||
this.config = config;
|
||||
// this.formLoding = true;
|
||||
// uni.setNavigationBarTitle({
|
||||
// title: this.config.formEnCode === "revoke" ? `${this.flowInfo.fullName}撤销申请` : this
|
||||
// .flowInfo.fullName,
|
||||
// });
|
||||
// if (config.formRecords && config.title) {
|
||||
// uni.setNavigationBarTitle({
|
||||
// title: config.title,
|
||||
// });
|
||||
// }
|
||||
// this.flowUrgent = this.taskInfo.flowUrgent || 1;
|
||||
// const getSelectInfo = () => {
|
||||
// var obj = {
|
||||
// value: this.flowUrgent,
|
||||
// extra: "0",
|
||||
// label: "普通",
|
||||
// };
|
||||
// this.flowUrgentList.forEach((e, i) => {
|
||||
// if (e.value == this.flowUrgent) {
|
||||
// obj.extra = i;
|
||||
// obj.label = e.label;
|
||||
// }
|
||||
// });
|
||||
// return obj;
|
||||
// };
|
||||
// this.selectflowUrgent = getSelectInfo();
|
||||
// this.initRightBtnList();
|
||||
// if (config.opType != "-1" && config.opType != "3") config.readonly =
|
||||
// true;
|
||||
// config.formOperates = [];
|
||||
// if (config.opType == 0) {
|
||||
// if (this.properties && this.properties && this.properties.formOperates) config
|
||||
// .formOperates = this.properties.formOperates || [];
|
||||
// } else {
|
||||
// config.formOperates = res.data.formOperates || [];
|
||||
// }
|
||||
// this.getFlowStatus()
|
||||
// setTimeout(() => {
|
||||
// this.$nextTick(() => {
|
||||
// if (!this.$refs.child || !this.$refs.child.$refs.form) {
|
||||
// uni.showToast({
|
||||
// title: "暂无此流程表单",
|
||||
// icon: "none",
|
||||
// complete: () => {
|
||||
// setTimeout(() => {
|
||||
// uni.navigateBack();
|
||||
// }, 1500);
|
||||
// },
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// this.$refs.child.$refs.form.init(config)
|
||||
// });
|
||||
// }, 100);
|
||||
// this.config = config;
|
||||
});
|
||||
},
|
||||
//获取修改记录
|
||||
|
||||
@@ -103,30 +103,35 @@ const statusMap = {
|
||||
|
||||
import {
|
||||
getOperatorList,
|
||||
getFlowLaunchList
|
||||
getFlowLaunchList,
|
||||
getMyPage,
|
||||
getTodoPage,
|
||||
getDonePage,
|
||||
getCcMyPage
|
||||
} from '@/api/workFlow/template'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mescrollTop: 206,
|
||||
statusList: [],
|
||||
|
||||
tabsList: [{
|
||||
fullName: '在办',
|
||||
fullName: '我的消息',
|
||||
category: '1',
|
||||
key: 3,
|
||||
enCode: "workFlow.flowLaunch"
|
||||
},{
|
||||
fullName: '待办任务',
|
||||
category: '2',
|
||||
key: 2,
|
||||
enCode: "workFlow.flowDoing"
|
||||
}, {
|
||||
fullName: '发起',
|
||||
category: null,
|
||||
key: 3,
|
||||
enCode: "workFlow.flowLaunch"
|
||||
}, {
|
||||
fullName: '已办',
|
||||
fullName: '已办任务',
|
||||
category: '3',
|
||||
key: 4,
|
||||
enCode: "workFlow.flowDone"
|
||||
}, {
|
||||
fullName: '抄送',
|
||||
fullName: '抄送任务',
|
||||
category: '4',
|
||||
key: 5,
|
||||
enCode: "workFlow.flowCirculate"
|
||||
@@ -147,7 +152,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.statusList = statusMap[this.tabsList[val].key]
|
||||
this.mescrollTop = 322 / 2
|
||||
this.mescrollTop = 220 / 2
|
||||
this.category = this.tabsList[this.current].category
|
||||
},
|
||||
immediate: true,
|
||||
@@ -182,9 +187,9 @@ export default {
|
||||
}
|
||||
}
|
||||
];
|
||||
configToCheck.forEach(config => {
|
||||
if (this.sysConfigInfo[config.key] === 1) return this.tabsList.unshift(config.tab);
|
||||
});
|
||||
// configToCheck.forEach(config => {
|
||||
// if (this.sysConfigInfo[config.key] === 1) return this.tabsList.unshift(config.tab);
|
||||
// });
|
||||
this.menuList = uni.getStorageSync("menuList");
|
||||
let workFlowList = this.menuList.filter(o => o.enCode === 'workFlow')
|
||||
if (!workFlowList.length) return
|
||||
@@ -203,6 +208,8 @@ export default {
|
||||
/* tab1 */
|
||||
change(index) {
|
||||
let item = this.tabsList[index]
|
||||
console.log(item,'item------------')
|
||||
console.log(index,'index------------')
|
||||
this.current = index;
|
||||
this.status = ''
|
||||
this.keyword = ''
|
||||
@@ -225,13 +232,13 @@ export default {
|
||||
},
|
||||
/* 列表数据 */
|
||||
upCallback(page) {
|
||||
let methods = this.category ? getOperatorList : getFlowLaunchList;
|
||||
let methods = this.getList(this.category)
|
||||
let query = {
|
||||
currentPage: page.num,
|
||||
pageNo: page.num,
|
||||
pageSize: page.size,
|
||||
keyword: this.keyword,
|
||||
category: this.tabsList[this.current].category,
|
||||
status: this.status
|
||||
// category: this.tabsList[this.current].category,
|
||||
// status: this.status
|
||||
}
|
||||
methods(query, {
|
||||
load: page.num == 1
|
||||
@@ -245,11 +252,32 @@ export default {
|
||||
'swipeAction': this.swipeAction(o.status),
|
||||
...o
|
||||
}))
|
||||
console.log(list,'list---')
|
||||
this.list = this.list.concat(list);
|
||||
}).catch(() => {
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
},
|
||||
// 流程列表接口
|
||||
getList(category){
|
||||
let methods = ''
|
||||
console.log(category,'category---')
|
||||
switch(category){
|
||||
case '1':
|
||||
methods = getMyPage
|
||||
break;
|
||||
case '2':
|
||||
methods = getTodoPage
|
||||
break;
|
||||
case '3':
|
||||
methods = getDonePage
|
||||
break;
|
||||
case '4':
|
||||
methods = getCcMyPage
|
||||
break;
|
||||
}
|
||||
return methods
|
||||
},
|
||||
swipeAction(status) {
|
||||
let swipeAction = true
|
||||
if (this.tabsList[this.current].key === 3 && !this.category && (status == '0' || status == '9'))
|
||||
|
||||
@@ -11,20 +11,27 @@
|
||||
<view class='common-lable-entrust' v-if="item.delegateUser">
|
||||
{{!category ? '委托' : '代理' }}
|
||||
</view>
|
||||
<view class='common-lable'
|
||||
:class="{'urgent-lable':item.flowUrgent==2,'important-lable':item.flowUrgent==3}">
|
||||
{{getLableValue(item.flowUrgent)}}
|
||||
<view class='common-lable'>
|
||||
单号
|
||||
</view>
|
||||
<text class="title u-font-28 u-line-1">{{item.fullName}}</text>
|
||||
<text class="title u-font-28 u-line-1">{{item.businessInfo.billNo}}</text>
|
||||
</view>
|
||||
<text class="title u-line-1 u-font-24">审批节点:{{item.currentNodeName}}<text
|
||||
<text class="title u-line-1 u-font-24">单据类型:{{item.name || item.processInstanceName}}<text
|
||||
class="titInner">{{item.thisStep ? item.thisStep : ''}}</text></text>
|
||||
<text class="time title u-font-24">发起时间:<text
|
||||
class="titInner">{{item.startTime?$u.timeFormat(item.startTime, 'yyyy-mm-dd hh:MM:ss'):''}}</text></text>
|
||||
class="titInner">{{item.createTime?$u.timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss'):''}}</text></text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<image :src="item.flowStatus" mode="widthFix" class="item-right-img">
|
||||
</image>
|
||||
<view v-if="category == 2" class="item-right">
|
||||
<image v-if="item.result == 1" src="./img/jihuo.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-else src="./img/wanc.png" mode="widthFix" class="item-right-img" />
|
||||
</view>
|
||||
<view v-else class="item-right">
|
||||
<image v-if="item.result == 1" src="./img/doing.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-if="item.result == 2" src="./img/togo.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-if="item.result == 3" src="./img/pass.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-if="item.result == 4" src="./img/quxiao.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-if="item.result == 5" src="./img/REJECTED.png" mode="widthFix" class="item-right-img" />
|
||||
<image v-if="item.result == 6" src="./img/weipai.png" mode="widthFix" class="item-right-img" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -105,24 +112,6 @@
|
||||
this.list.splice(index, 1)
|
||||
})
|
||||
},
|
||||
getLableValue(value) {
|
||||
var lableValue = ''
|
||||
switch (value) {
|
||||
case 1:
|
||||
lableValue = '普通'
|
||||
break;
|
||||
case 2:
|
||||
lableValue = '重要'
|
||||
break;
|
||||
case 3:
|
||||
lableValue = '紧急'
|
||||
break;
|
||||
default:
|
||||
lableValue = '普通'
|
||||
break;
|
||||
}
|
||||
return lableValue
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
BIN
pages/workFlow/flowTodo/img/REJECTED.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
pages/workFlow/flowTodo/img/doing.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
pages/workFlow/flowTodo/img/jihuo.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
pages/workFlow/flowTodo/img/pass.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
pages/workFlow/flowTodo/img/quxiao.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
pages/workFlow/flowTodo/img/togo.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
pages/workFlow/flowTodo/img/wanc.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
pages/workFlow/flowTodo/img/wanchen.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
pages/workFlow/flowTodo/img/weipai.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
@@ -10,11 +10,11 @@
|
||||
<u-tabs ref="tabs" :list="tabsList" active-color="#0177FF" inactive-color="#303133" font-size="30"
|
||||
v-model="current" name="fullName" @change="change" height="80" :is-scroll="false"></u-tabs>
|
||||
</view>
|
||||
<view class="flow-status-tabs" v-if="statusList.length">
|
||||
<!-- <view class="flow-status-tabs" v-if="statusList.length">
|
||||
<u-subsection :list="statusList" :current="subsectionIndex" name="name" active-color="#2979FF"
|
||||
inactive-color="#999999" bg-color="#F2F3F7" font-size="24" :bold="false"
|
||||
@change="subsection"></u-subsection>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption"
|
||||
:up="upOption" :top="mescrollTop">
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
this.userInfo = uni.getStorageSync('userInfo') || {}
|
||||
this.setting = data
|
||||
this.formConf = data.formConf ? JSON.parse(data.formConf) : {}
|
||||
console.log(this.formConf,'formConf112')
|
||||
this.dataForm.id = data.id || null;
|
||||
this.dataForm.flowId = data.flowId;
|
||||
this.loading = true;
|
||||
@@ -74,91 +75,91 @@
|
||||
},
|
||||
fillFormData(form, data) {
|
||||
form.disabled = this.setting.readonly
|
||||
const loop = (list, parent) => {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i]
|
||||
let vModel = item.__vModel__
|
||||
let config = item.__config__
|
||||
if (vModel) {
|
||||
let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
|
||||
if (!config.isSubTable) config.defaultValue = val
|
||||
if (this.isAdd || config.isSubTable) { //新增时候,默认当前
|
||||
if (config.defaultCurrent) {
|
||||
if (config.jnpfKey === 'datePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
let format = this.jnpf.handelFormat(item.format)
|
||||
let dateStr = this.jnpf.toDate(new Date().getTime(), format)
|
||||
let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
|
||||
'-01 00:00:00' : format === 'yyyy-MM-dd' ?
|
||||
' 00:00:00' : ''
|
||||
val = new Date(dateStr + time).getTime()
|
||||
config.defaultValue = val
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'timePicker') {
|
||||
if (!data.hasOwnProperty(vModel)) {
|
||||
config.defaultValue = this.jnpf.toDate(new Date(), item.format)
|
||||
}
|
||||
}
|
||||
if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.organizeIds :
|
||||
this.userInfo.organizeId
|
||||
}
|
||||
if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
|
||||
config.defaultValue = item.multiple ? this.userInfo.positionIds :
|
||||
this.userInfo.positionId
|
||||
}
|
||||
const userId = this.userInfo.userId
|
||||
if (config.jnpfKey === 'userSelect' && userId) {
|
||||
config.defaultValue = item.multiple ? [userId] : userId;
|
||||
}
|
||||
if (config.jnpfKey === 'usersSelect' && userId) {
|
||||
config.defaultValue = [userId + '--user'];
|
||||
}
|
||||
if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
|
||||
config.defaultValue = this.userInfo.signImg
|
||||
}
|
||||
}
|
||||
}
|
||||
let noShow = item.__config__.noShow || false,
|
||||
isDisabled = item.disabled || false,
|
||||
required = item.__config__.required || false,
|
||||
isVisibility = false
|
||||
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
.__config__.visibility.includes('app'))) isVisibility = true
|
||||
if (this.setting.formOperates && this.setting.formOperates.length) {
|
||||
let id = item.__config__.isSubTable ? parent?.__vModel__ + '-' + item?.__vModel__ :
|
||||
item
|
||||
.__vModel__
|
||||
let arr = this.setting.formOperates.filter(o => o.id === id) || []
|
||||
if (arr.length) {
|
||||
let obj = arr[0]
|
||||
noShow = !obj.read
|
||||
isDisabled = !obj.write
|
||||
required = obj.required ? obj.required : item.__config__.required
|
||||
}
|
||||
}
|
||||
isDisabled = item.readonly ? item.readonly : isDisabled;
|
||||
if (this.setting.readonly || config.disabled) isDisabled = true
|
||||
if (this.setting.origin === 'scan') isDisabled = true
|
||||
this.$set(item, 'disabled', isDisabled)
|
||||
this.$set(item.__config__, 'noShow', noShow)
|
||||
this.$set(item.__config__, 'required', required)
|
||||
this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
} else {
|
||||
let noShow = item.__config__.noShow ? item.__config__.noShow : false,
|
||||
isVisibility = false
|
||||
if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
.__config__.visibility.includes('app'))) isVisibility = true
|
||||
this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
this.$set(item.__config__, 'noShow', noShow)
|
||||
}
|
||||
if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) {
|
||||
loop(item.__config__.children, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
loop(form.fields)
|
||||
// const loop = (list, parent) => {
|
||||
// for (let i = 0; i < list?.length; i++) {
|
||||
// let item = list[i]
|
||||
// let vModel = item.__vModel__
|
||||
// let config = item.__config__
|
||||
// if (vModel) {
|
||||
// let val = data.hasOwnProperty(vModel) ? data[vModel] : config.defaultValue
|
||||
// if (!config.isSubTable) config.defaultValue = val
|
||||
// if (this.isAdd || config.isSubTable) { //新增时候,默认当前
|
||||
// if (config.defaultCurrent) {
|
||||
// if (config.jnpfKey === 'datePicker') {
|
||||
// if (!data.hasOwnProperty(vModel)) {
|
||||
// let format = this.jnpf.handelFormat(item.format)
|
||||
// let dateStr = this.jnpf.toDate(new Date().getTime(), format)
|
||||
// let time = format === 'yyyy' ? '-01-01 00:00:00' : format === 'yyyy-MM' ?
|
||||
// '-01 00:00:00' : format === 'yyyy-MM-dd' ?
|
||||
// ' 00:00:00' : ''
|
||||
// val = new Date(dateStr + time).getTime()
|
||||
// config.defaultValue = val
|
||||
// }
|
||||
// }
|
||||
// if (config.jnpfKey === 'timePicker') {
|
||||
// if (!data.hasOwnProperty(vModel)) {
|
||||
// config.defaultValue = this.jnpf.toDate(new Date(), item.format)
|
||||
// }
|
||||
// }
|
||||
// if (config.jnpfKey === 'organizeSelect' && this.userInfo.organizeIds?.length) {
|
||||
// config.defaultValue = item.multiple ? this.userInfo.organizeIds :
|
||||
// this.userInfo.organizeId
|
||||
// }
|
||||
// if (config.jnpfKey === 'posSelect' && this.userInfo.positionIds?.length) {
|
||||
// config.defaultValue = item.multiple ? this.userInfo.positionIds :
|
||||
// this.userInfo.positionId
|
||||
// }
|
||||
// const userId = this.userInfo.userId
|
||||
// if (config.jnpfKey === 'userSelect' && userId) {
|
||||
// config.defaultValue = item.multiple ? [userId] : userId;
|
||||
// }
|
||||
// if (config.jnpfKey === 'usersSelect' && userId) {
|
||||
// config.defaultValue = [userId + '--user'];
|
||||
// }
|
||||
// if (config.jnpfKey === 'sign' && this.userInfo.signImg) {
|
||||
// config.defaultValue = this.userInfo.signImg
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// let noShow = item.__config__.noShow || false,
|
||||
// isDisabled = item.disabled || false,
|
||||
// required = item.__config__.required || false,
|
||||
// isVisibility = false
|
||||
// if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
// .__config__.visibility.includes('app'))) isVisibility = true
|
||||
// if (this.setting.formOperates && this.setting.formOperates.length) {
|
||||
// let id = item.__config__.isSubTable ? parent?.__vModel__ + '-' + item?.__vModel__ :
|
||||
// item
|
||||
// .__vModel__
|
||||
// let arr = this.setting.formOperates.filter(o => o.id === id) || []
|
||||
// if (arr.length) {
|
||||
// let obj = arr[0]
|
||||
// noShow = !obj.read
|
||||
// isDisabled = !obj.write
|
||||
// required = obj.required ? obj.required : item.__config__.required
|
||||
// }
|
||||
// }
|
||||
// isDisabled = item.readonly ? item.readonly : isDisabled;
|
||||
// if (this.setting.readonly || config.disabled) isDisabled = true
|
||||
// if (this.setting.origin === 'scan') isDisabled = true
|
||||
// this.$set(item, 'disabled', isDisabled)
|
||||
// this.$set(item.__config__, 'noShow', noShow)
|
||||
// this.$set(item.__config__, 'required', required)
|
||||
// this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
// } else {
|
||||
// let noShow = item.__config__.noShow ? item.__config__.noShow : false,
|
||||
// isVisibility = false
|
||||
// if (!item.__config__.visibility || (Array.isArray(item.__config__.visibility) && item
|
||||
// .__config__.visibility.includes('app'))) isVisibility = true
|
||||
// this.$set(item.__config__, 'isVisibility', isVisibility)
|
||||
// this.$set(item.__config__, 'noShow', noShow)
|
||||
// }
|
||||
// if (item.__config__ && item.__config__.children && Array.isArray(item.__config__.children)) {
|
||||
// loop(item.__config__.children, item)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// loop(form.fields)
|
||||
form.formData = data
|
||||
},
|
||||
sumbitForm(data, callback) {
|
||||
|
||||