xy 11 months ago
parent 5369221251
commit dd86bb3af5

@ -2,6 +2,7 @@
ENV = 'development'
# base api
#VUE_APP_BASE_API='http://192.167.20.118:8080/'
VUE_APP_BASE_API='http://cz-hjjc-test.115.langye.net'
VUE_APP_UPLOAD_API='http://cz-hjjc-test.115.langye.net/api/upload-file'
VUE_APP_PREVIEW=//view.langye.net/preview/onlinePreview

@ -12,10 +12,11 @@
v-model="showModal"
:footer-hide="true"
title="预览"
:padding="false"
>
<template>
<iframe
style="width: 100%; height: 100%;"
style="display: block;width: 100%;height: 100%;border: 0;"
:src="codeUri"
frameborder="0"
></iframe>
@ -44,6 +45,15 @@ export default {
}
},
computed: {},
watch: {
showModal(newVal) {
if (!newVal) {
this.codeUri = ''
} else {
this.zIndex = PopupManager.nextZIndex()
}
}
},
created() {
this.$bus.$on('online-file',(url) => this.open(url))
},

@ -181,9 +181,10 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
if (!!info.multiple) {
return target[info.name] ? target[info.name].toString()?.split(/,|\|/).map(i => isNaN(Number(i)) ? i : Number(i)) : []
} else {
return isNaN(Number(target[info.name])) ? target[info.name] : Number(target[info.name])
return (isNaN(Number(target[info.name])) || !target[info.name]) ? target[info.name] : Number(target[info.name])
}
}
console.log(info.name, getSelectValue(), target[info.name])
formItem = h(
formBuilderMap(device).get(info.type),
{
@ -672,17 +673,21 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
res = isNaN(Number(target[info.name])) ? target[info.name] : Number(target[info.name])
}
if (res instanceof Array) {
return options?.filter((i) =>
typeof i === "object"
? res.indexOf(i.id) !== -1
: res.indexOf(i) !== -1
)?.map(i => typeof i === 'object' ? i.name : i)?.toString()
if (typeof options[0] === 'object') {
return options?.filter((i) =>
res.indexOf(i.id) !== -1
)?.map(i => i.name)?.toString()
} else {
return res
}
} else {
return options?.filter((i) =>
typeof i === "object"
? res === i.id
: res === i
)?.map(i => typeof i === 'object' ? i.name : i)?.toString()
if (typeof options[0] === 'object') {
return options?.filter((i) =>
res === i.id
)?.map(i => i.name)?.toString()
} else {
return res
}
}
}
formItem = h(
@ -810,6 +815,7 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
},
on: {
click: _ => {
console.log(file)
this.$bus.$emit('online-file', file.url)
}
}
@ -896,33 +902,9 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
"grid-row-end": info.gs_y + 1 + (info.name === 'flow_title' ? 0 : 1) + info.gs_height,
},
},
isJointly ? [(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,(() => {
if (info.is_sign && !(/\/detail/.test(this.$route.path && this.$route.query.flow_id && jointlySignContent.length > 0))) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1) && (row ? row[info.name] : this.form[info.name])
if (log && log.user) {
return h('div',[
(log.user.sign_file && log.user.sign_file.url) ? h('el-image',{
style: {
'max-height': '80px',
'max-width': '120px'
},
props: {
src: log.user?.sign_file?.url,
fit: 'contain',
alt: log.user?.name
},
attrs: {
src: log.user?.sign_file?.url,
alt: log.user?.name
}
}) : h('span', log.user?.name),
h('div', this.$moment(log.updated_at).format('YYYY年MM月DD日 HH时mm分'))
])
}
}
})(),jointlySignContent] : [formItem,(() => {
isJointly ? [(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,jointlySignContent] : [formItem,(() => {
if (info.is_sign) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1 && (row ? row[info.name] : this.form[info.name]))
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name && field.type === 'write') !== -1 && (target[info.name]))
if (log && log.user) {
return h('div',[
(log.user.sign_file && log.user.sign_file.url) ? h('el-image',{
@ -1229,6 +1211,7 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
},
on: {
click: _ => {
console.log(file)
this.$bus.$emit('online-file', file.url)
}
}
@ -1508,6 +1491,7 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
},
on: {
click:_ => {
console.log(file)
this.$bus.$emit('online-file', file.url)
}
}
@ -1678,33 +1662,9 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
}
})
})
return isJointly ? [(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,(() => {
if (info.is_sign && !(/\/detail/.test(this.$route.path && this.$route.query.flow_id && jointlySignContent.length > 0))) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1) && (row ? row[info.name] : this.form[info.name])
if (log && log.user) {
return h('van-cell',[
(log.user.sign_file && log.user.sign_file.url) ? h('el-image',{
style: {
'max-height': '80px',
'max-width': '120px'
},
props: {
src: log.user?.sign_file?.url,
fit: 'contain',
alt: log.user?.name
},
attrs: {
src: log.user?.sign_file?.url,
alt: log.user?.name
}
}) : h('span', log.user?.name),
h('div', this.$moment(log.updated_at).format('YYYY年MM月DD日 HH时mm分'))
])
}
}
})(),jointlySignContent] : [formItem,(() => {
return isJointly ? [(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,jointlySignContent] : [formItem,(() => {
if (info.is_sign) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1 && (row ? row[info.name] : this.form[info.name]))
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name && field.type === 'write') !== -1 && (target[info.name]))
if (log && log.user) {
return h('van-cell',[
(log.user.sign_file && log.user.sign_file.url) ? h('el-image',{

@ -283,10 +283,11 @@
:width="defaultModalSize.width"
:height="defaultModalSize.height"
esc-closable
:padding="false"
>
<iframe
:src="modalUrl"
style="width: 100%; height: 100%"
style="display: block;width: 100%;height: 100%;border: 0;"
frameborder="0"
/>
</vxe-modal>

@ -5,7 +5,7 @@ import {PopupManager} from "element-ui/lib/utils/popup";
import request from '@/utils/request'
import moment from "moment/moment";
import {defaultModalSize} from "@/settings";
import {getToken} from '@/utils/auth'
import { getToken } from '@/utils/auth'
export default {
props: {
config: {
@ -202,12 +202,6 @@ export default {
},
computed: {},
watch: {
info(newVal) {
let keys = newVal.map((i) => i.name);
keys.forEach((key) => {
this.form[key] = "";
});
},
originalForm(newVal) {
this.form = deepCopy(newVal);
},
@ -273,7 +267,7 @@ export default {
props: {
model: this.form,
"label-position": "right",
"label-width": "140px",
"label-width": "130px",
rules: this.rules,
"inline-message": true,
},

@ -0,0 +1,181 @@
<template>
<div>
<vxe-modal
title="查看"
:z-index="zIndex"
:value="isShow"
@input="e => $emit('update:isShow', e)"
size="mini"
:loading="loading"
:id="id.toString()"
:lock-view="false"
:lock-scroll="false"
:mask="false"
:min-height="300"
resize
:fullscreen="$store.getters.device === 'mobile'"
show-zoom
draggable
storage
:padding="false"
:position="$store.getters.device === 'mobile' ? {} : pos">
<MobileForm
device="mobile"
ref="mobileForm"
:config="config"
:is-first-node="false"
:sub-form="subConfig"
:fields="fields"
:original-form="form"
:readable="config.customModel ? config.customModel.fields.map(i => i.id) : []"
:writeable="[]"
:logs="config.logs"
></MobileForm>
</vxe-modal>
</div>
</template>
<script>
import {
fieldConfig,
view,
} from "@/api/flow";
import MobileForm from "@/views/flow/MobileForm.vue";
import { PopupManager } from 'element-ui/lib/utils/popup'
export default {
components: {
MobileForm
},
props: {
isShow: {
type: Boolean,
default: false
},
id: {
type: [String,Number],
default: ""
},
pos: {
type: Object,
default: () => ({ top: 0, left: 0 })
}
},
data() {
return {
zIndex: PopupManager.nextZIndex(),
loading: false,
form: {},
subConfig: new Map(),
config: {},
fields: [],
}
},
methods: {
generateForm(object, fields, relation = false, pname) {
fields.forEach((field) => {
if (field.type === "relation") {
object[field.name] = [{}];
this.generateForm(
object[field.name][0],
this.subConfig.get(field.sub_custom_model_id)?.customModel?.fields,
true,
field.name
);
} else {
object[field.name] = "";
}
});
},
async getConfig() {
this.loading = true
try {
const res = await view(this.id);
let { fields } = res?.customModel;
fields = fields.filter(i => i.show_in_list)
this.fields = fields
let subFormRequest = [];
const getSubForm = async (id) => {
subFormRequest.push(fieldConfig(id));
};
for (let j = 0;j < fields.length;j++) {
let field = fields[j]
if (field.sub_custom_model_id) {
await getSubForm(field.sub_custom_model_id);
}
}
const subConfigs = await Promise.all(subFormRequest);
subConfigs.forEach((sub) => {
if (sub.customModel?.id) {
this.subConfig.set(sub.customModel?.id, sub);
}
});
this.config = res;
this.generateForm(this.form, fields);
this.form = Object.assign({}, this.form);
const { data } = res?.flow;
for (let key in data) {
try {
let jsonObj = JSON.parse(data[key]);
jsonObj.forEach(item => {
//
for (const key in item) {
if (typeof item[key] === 'string') {
try {
// JSON
const parsedValue = JSON.parse(item[key]);
//
item[key] = parsedValue;
} catch (e) {
//
}
}
}
})
if (this.form.hasOwnProperty(key)) {
this.form[key] = jsonObj;
}
} catch (err) {
if (this.form.hasOwnProperty(key)) {
if (data[key] instanceof Array) {
if (data[key].length > 0 && data[key][0].hasOwnProperty('url')) {
this.form[key] = data[key].map(i => ({
name: i.original_name,
url: i.url,
response: i,
}))
} else {
this.form[key] = ''
}
}
this.form[key] = data[key];
}
}
}
this.loading = false
} catch (err) {
console.error(err);
this.$message.error("配置失败");
this.loading = false
}
}
},
computed: {},
watch: {
id(newVal) {
if (!!newVal) {
this.getConfig()
}
},
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
}
}
</script>
<style scoped lang="scss">
</style>

@ -0,0 +1,125 @@
<template>
<div>
<vxe-modal
title="批量审批"
:z-index="zIndex"
:value="isShow"
@input="e => $emit('update:isShow', e)"
:min-height="300"
resize
:width="defaultModalSize.sWidth"
:height="defaultModalSize.sHeight"
:fullscreen="$store.getters.device === 'mobile'"
show-zoom
draggable
storage
show-footer
>
<vxe-table
ref="table"
stripe
keep-source
show-overflow
:column-config="{ resizable: true }"
:print-config="{}"
:export-config="{}"
:row-config="{ keyField: 'id' }"
:custom-config="{ mode: 'popup' }"
:data="flows"
>
<vxe-column
min-width="140"
header-align="center"
field="title"
title="工作名称"
></vxe-column>
<vxe-column
width="80"
align="center"
field="id"
title="流水号"
></vxe-column>
<vxe-column
width="80"
title="发起人"
align="center"
field="creator.name"
></vxe-column>
<vxe-column
width="80"
title="承办人员"
align="center"
field="last_log.user.name"
></vxe-column>
<vxe-column
header-align="center"
min-width="120"
field="custom_model.name"
title="流程名称"
></vxe-column>
<vxe-column
width="164"
field="no"
align="center"
title="编号"
></vxe-column>
<vxe-column
width="200"
:visible="$route.params.type === 'all'"
align="center"
field="created_at"
title="发起日期"
:formatter="
({ cellValue }) =>
$moment(cellValue).format('YYYY-MM-DD HH:mm:ss')
"
:export-method="
({ row, column, options }) =>
$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss')
"
></vxe-column>
</vxe-table>
<template #footer>
<el-button type="primary" :loading="loading" @click="">确认</el-button>
</template>
</vxe-modal>
</div>
</template>
<script>
import { PopupManager } from 'element-ui/lib/utils/popup'
import { defaultModalSize } from "@/settings";
export default {
props: {
isShow: {
type: Boolean,
default: false
},
flows: {
type: Array,
default: () => []
}
},
data() {
return {
loading: false,
defaultModalSize,
zIndex: PopupManager.nextZIndex(),
}
},
methods: {},
computed: {},
watch: {
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
}
}
</script>
<style scoped lang="scss">
</style>

@ -737,17 +737,20 @@ export default {
}
copyForm = deepCopy(this.$refs["mobileForm"].form);
}
const uploadHandler = (form) => {
const uploadHandler = (form, fields) => {
let keys = Object.keys(form)
keys.forEach(key => {
if (form[key] instanceof Array) {
if (form[key].length > 0) {
if (form[key][0].hasOwnProperty('response')) {
form[key] = form[key].map(i => i.response)
} else {
form[key].forEach(i => {
uploadHandler(i)
})
if (form[key].length > 0 && typeof form[key][0] === 'object') {
const myField = fields.find(field => field.name === key)
if (myField) {
if (myField.type === 'file') {
form[key] = form[key].map(i => i.hasOwnProperty('response') ? i.response : i)
} else {
form[key].forEach(i => {
uploadHandler(i, this.subConfig.get(myField.sub_custom_model_id)?.customModel?.fields)
})
}
}
} else {
form[key] = ''
@ -759,7 +762,7 @@ export default {
}
})
}
uploadHandler(copyForm)
uploadHandler(copyForm, this.fields)
for (let key in copyForm) {
let myField = this.fields.find(i => i.name === key)
if (myField && this.writeableFields.indexOf(myField.id) === -1) {

@ -63,6 +63,14 @@
@click="getList"
>搜索</el-button
>
<el-button
icon="el-icon-edit"
type="primary"
size="small"
plain
@click="multiDeal"
>批量审批</el-button
>
</div>
</template>
</vxe-toolbar>
@ -82,12 +90,61 @@
:export-config="{}"
:expand-config="{
accordion: true,
padding: true
}"
:checkbox-config="{
reserve: true,
highlight: true
}"
:row-config="{ keyField: 'id' }"
:custom-config="{ mode: 'popup' }"
:data="list"
@cell-click="cellClickEvent"
@cell-dblclick="cellDblclickEvent"
>
<vxe-column type="checkbox" width="60" align="center"></vxe-column>
<vxe-column :visible="$store.getters.device === 'mobile'" field="m-operate" type="expand" title="操作" width="60" align="center">
<template #content="{ row }">
<div>
<template v-if="$route.params.type !== 'all'">
<el-button
v-if="row.my_log"
type="primary"
size="mini"
@click="handle(row)"
>办理</el-button
>
<el-button
plain
type="primary"
size="mini"
@click="copyTo(row)"
>抄送</el-button
>
<el-button
v-if="row.can_recall"
plain
type="danger"
size="mini"
@click="recall(row)"
>撤回</el-button
>
<el-button
v-if="row.can_delete"
plain
type="danger"
size="mini"
@click="destroy(row)"
>删除</el-button
>
</template>
<el-button plain type="success" size="mini" @click="detail(row)"
>查看</el-button
>
</div>
</template>
</vxe-column>
<vxe-column
v-if="$route.params.type === 'all'"
align="center"
@ -100,9 +157,10 @@
header-align="center"
field="title"
title="工作名称"
:title-prefix="{ content: '点击工作名称查看简要' }"
></vxe-column>
<vxe-column
v-if="$route.params.type === 'all'"
:visible="$route.params.type === 'all'"
width="80"
align="center"
field="id"
@ -115,7 +173,7 @@
field="creator.name"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'all'"
:visible="$route.params.type !== 'all'"
width="80"
title="承办人员"
align="center"
@ -128,14 +186,14 @@
title="流程名称"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'all'"
:visible="$route.params.type !== 'all'"
align="center"
width="140"
field="current_node.name"
title="当前节点"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'all'"
:visible="$route.params.type !== 'all'"
title="收藏状态"
width="90"
field="my_fav"
@ -158,7 +216,7 @@
></vxe-column>
<vxe-column
width="200"
v-if="$route.params.type === 'all'"
:visible="$route.params.type === 'all'"
align="center"
field="created_at"
title="发起日期"
@ -190,98 +248,53 @@
>
</template>
</vxe-column>
<template v-if="$store.getters.device === 'mobile'">
<vxe-column field="m-operate" type="expand" width="60" fixed="left">
<template #content="{ row }">
<div>
<template v-if="$route.params.type !== 'all'">
<el-button
v-if="row.my_log"
type="primary"
size="mini"
@click="handle(row)"
>办理</el-button
>
<el-button
plain
type="primary"
size="mini"
@click="copyTo(row)"
>抄送</el-button
>
<el-button
v-if="row.can_recall"
plain
type="danger"
size="mini"
@click="recall(row)"
>撤回</el-button
>
<el-button
v-if="row.can_delete"
plain
type="danger"
size="mini"
@click="destroy(row)"
>删除</el-button
>
</template>
<el-button plain type="success" size="mini" @click="detail(row)"
>查看</el-button
>
</div>
</template>
</vxe-column>
</template>
<template v-else>
<vxe-column
min-width="280"
header-align="center"
field="operate"
title="操作"
fixed="right"
>
<template #default="{ row }">
<template v-if="$route.params.type !== 'all'">
<el-button
v-if="row.my_log"
type="primary"
size="mini"
@click="handle(row)"
>办理</el-button
>
<el-button
plain
type="primary"
size="mini"
@click="copyTo(row)"
>抄送</el-button
>
<el-button
v-if="row.can_recall"
plain
type="danger"
size="mini"
@click="recall(row)"
>撤回</el-button
>
<el-button
v-if="row.can_delete"
plain
type="danger"
size="mini"
@click="destroy(row)"
>删除</el-button
>
</template>
<el-button plain type="success" size="mini" @click="detail(row)"
>查看</el-button
<vxe-column
:visible="$store.getters.device === 'desktop'"
min-width="280"
header-align="center"
field="operate"
title="操作"
fixed="right"
>
<template #default="{ row }">
<template v-if="$route.params.type !== 'all'">
<el-button
v-if="row.my_log"
type="primary"
size="mini"
@click="handle(row)"
>办理</el-button
>
<el-button
plain
type="primary"
size="mini"
@click="copyTo(row)"
>抄送</el-button
>
<el-button
v-if="row.can_recall"
plain
type="danger"
size="mini"
@click="recall(row)"
>撤回</el-button
>
<el-button
v-if="row.can_delete"
plain
type="danger"
size="mini"
@click="destroy(row)"
>删除</el-button
>
</template>
</vxe-column>
</template>
<el-button plain type="success" size="mini" @click="detail(row)"
>查看</el-button
>
</template>
</vxe-column>
</vxe-table>
<el-pagination
@ -310,20 +323,35 @@
</el-card>
<share ref="share" :is-show.sync="isShowShare" :flow="pickedFlow"></share>
<list-popover :is-show.sync="isShowListPopover" :id="listPopoverId" :pos="listPopoverPos" />
<multi-deal :is-show.sync="isShowMultiDeal" :flows="multiDealFlows" @refresh="getList" />
</div>
</template>
<script>
import { flowList, toggleFav, destroy, recall, updateFlowTime } from "@/api/flow";
import moment from "moment/moment";
import ListPopover from "./components/ListPopover.vue";
import MultiDeal from "./components/MultiDeal.vue"
import share from "./components/share.vue";
export default {
name: "flowList",
components: {
share
share,
ListPopover,
MultiDeal
},
data() {
return {
isShowMultiDeal: false,
multiDealFlows: [],
isShowListPopover: false,
listPopoverId: "",
listPopoverPos: {
top: 100,
left: 100
},
myStatus: new Map([
[-1, "已退回"],
[0, "办理中"],
@ -427,6 +455,14 @@ export default {
};
},
methods: {
cellClickEvent(e) {
if (e.column?.field !== 'title') return
this.listPopoverId = e.row.id
this.listPopoverPos.top = e.$event.clientX
this.listPopoverPos.left = e.$event.clientY
this.isShowListPopover = true
},
handle(row) {
this.$router.push(
`/flow/create?module_id=${row.custom_model.id}&flow_id=${row.id}`
@ -499,6 +535,14 @@ export default {
})
}
},
multiDeal() {
const reserveRecords = this.$refs['table']?.getCheckboxReserveRecords() || []
const records = this.$refs['table']?.getCheckboxRecords(true) || []
this.multiDealFlows = [...reserveRecords, ...records]
this.isShowMultiDeal = true
}
},
computed: {
},

Loading…
Cancel
Save