流转,列表等

master
xy 1 year ago
parent 348d7e9dea
commit 3ca29b6aa1

@ -1,4 +1,5 @@
import request from '@/utils/request'
import { MessageBox } from 'element-ui'
import qs from 'qs'
export function flow(isLoading=false) {
return request({
@ -24,7 +25,7 @@ export function fieldConfig(custom_model_id,isLoading=false) {
})
}
export function create(data,custom_model_id) {
export function create(custom_model_id, data) {
return request({
method: 'post',
url: `/api/oa/flow/create/${custom_model_id}`,
@ -45,7 +46,7 @@ export function preDeal(flow_id,params,isLoading=false) {
})
}
export function deal(data,flow_id) {
export function deal(flow_id,data) {
return request({
method: 'post',
url: `/api/oa/flow/deal/${flow_id}`,
@ -76,6 +77,7 @@ export function flowList(type,params,isLoading = false) {
return request({
method: 'get',
url: `/api/oa/flow/list/${type}`,
params,
isLoading
})
}
@ -88,3 +90,52 @@ export function assign(flow_id, data) {
data
})
}
//详情
export function view(flow_id) {
return request({
method: 'get',
url: `/api/oa/flow/view/${flow_id}`,
})
}
export function preShare(flow_id, params,isLoading = true) {
return request({
method: 'get',
url: `/api/oa/flow/share-pre/${flow_id}`,
params,
isLoading
})
}
//收藏
export function toggleFav(data,isLoading=true) {
return request({
method: 'post',
url: '/api/oa/flow/toggle-fav',
data,
isLoading
})
}
//撤回
export async function recall(data,isLoading=true) {
await MessageBox.confirm("确认撤回?","提示")
return request({
method: 'post',
url: '/api/oa/flow/recall',
data,
isLoading
})
}
//删除
export async function destroy(data,isLoading=true) {
await MessageBox.confirm("确认删除?","提示")
return request({
method: 'post',
url: '/api/oa/flow/delete',
data,
isLoading
})
}

@ -0,0 +1 @@
<svg t="1726714952792" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4261" width="200" height="200"><path d="M515.2 67.2c-246.4 0-448 201.6-448 448s201.6 448 448 448 448-201.6 448-448-201.6-448-448-448z m214.4 425.6l-86.4 86.4 19.2 121.6c3.2 12.8-3.2 25.6-12.8 32-6.4 3.2-12.8 6.4-19.2 6.4-6.4 0-9.6 0-16-3.2L512 678.4 409.6 736c-9.6 6.4-22.4 6.4-35.2-3.2-9.6-6.4-16-19.2-12.8-32l19.2-121.6-83.2-86.4c-9.6-9.6-12.8-22.4-6.4-32 3.2-12.8 12.8-19.2 25.6-22.4l115.2-16 51.2-112c6.4-9.6 16-19.2 28.8-19.2s22.4 6.4 28.8 19.2l51.2 112 115.2 19.2c12.8 3.2 22.4 9.6 25.6 22.4 6.4 6.4 6.4 19.2-3.2 28.8z" fill="currentColor" p-id="4262"></path></svg>

After

Width:  |  Height:  |  Size: 687 B

@ -0,0 +1 @@
<svg t="1726735724213" class="icon" viewBox="0 0 1246 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12391" width="200" height="200"><path d="M461.362637 150.613694h324.598479c33.758242 0 61.457312-27.69907 61.457312-60.591716 0-33.758242-27.69907-60.591716-61.457312-60.591716H461.362637c-33.758242 0-61.457312 27.69907-61.457312 60.591716s27.69907 60.591716 61.457312 60.591716z" fill="currentColor" p-id="12392"></path><path d="M623.229079 786.826712c0-141.957735 115.12426-257.947591 257.94759-257.947591 70.113271 0 133.301775 27.69907 179.178361 72.710059V162.732037c0-40.683009-32.892646-73.575655-73.575656-73.575655h-78.76923v60.591716c0 33.758242-27.69907 61.457312-61.457312 61.457312H399.905325c-33.758242 0-60.591716-27.69907-60.591716-60.591716v-60.591716H259.678783c-40.683009 0-73.575655 32.892646-73.575655 73.575655v759.127642c0 40.683009 32.892646 73.575655 73.575655 73.575655h470.884192C665.64328 948.693153 623.229079 872.52071 623.229079 786.826712zM505.50803 383.459003H917.531699c13.849535 0 25.967878 12.118343 25.967878 25.967878s-12.118343 25.967878-25.967878 25.967878H505.50803c-16.446323 0-25.967878-9.521555-25.967878-25.967878 0-12.983939 12.118343-25.967878 25.967878-25.967878z m-71.844463 199.952662l-70.978867 70.978868c-6.059172 6.059172-15.580727 6.059172-22.505495 0l-45.010989-45.010989c-6.059172-6.059172-6.059172-16.446323 2.596788-24.236687 6.059172-5.193576 16.446323-5.193576 22.505495 0.865596l27.69907 27.69907 3.462384 3.462384c1.731192-0.865596 2.596788-2.596788 3.462383-3.462384l51.935757-51.935756c8.655959-8.655959 22.505495-6.924768 27.69907 2.596788 4.32798 6.059172 4.32798 13.849535-0.865596 19.04311z m0-197.355875l-70.978867 70.978868c-6.059172 6.059172-15.580727 6.059172-22.505495 0l-45.010989-45.010989c-6.059172-6.059172-6.059172-16.446323 2.596788-24.236687 6.059172-5.193576 16.446323-5.193576 22.505495 0.865596l27.69907 27.69907 3.462384 3.462384c1.731192-0.865596 2.596788-2.596788 3.462383-3.462384l51.935757-51.935756c8.655959-8.655959 22.505495-6.924768 27.69907 2.596788 4.32798 6.059172 4.32798 13.849535-0.865596 19.04311z m167.060017 246.694844h-95.215554c-16.446323 0-25.967878-9.521555-25.967878-25.967878 0-13.849535 12.118343-25.967878 25.967878-25.967879h95.215554c13.849535 0 25.967878 12.118343 25.967878 25.967879s-12.118343 25.967878-25.967878 25.967878z" fill="currentColor" p-id="12393"></path><path d="M818.853762 670.836855v187.83432l-73.575655-74.441251c-8.655959-8.655959-21.639899-8.655959-30.295858 0s-8.655959 22.505495 0 31.161454l110.79628 112.527472c8.655959 8.655959 21.639899 8.655959 30.295858 0 3.462384-3.462384 5.193576-7.790363 6.059172-12.983939 0-1.731192 0.865596-3.462384 0.865596-6.059171V670.836855c0-12.118343-9.521555-21.639899-21.639899-21.639898h-0.865596c-12.118343 0-21.639899 9.521555-21.639898 21.639898z m89.156382-2.596787c0 1.731192-1.731192 3.462384-1.731192 5.193575v237.173289c0 12.118343 9.521555 21.639899 21.639898 21.639898s21.639899-9.521555 21.639899-21.639898V724.503804l73.575655 74.441251c8.655959 8.655959 21.639899 8.655959 30.295858 0s8.655959-21.639899 0-30.295858L943.499577 656.98732c-8.655959-8.655959-21.639899-8.655959-30.295858 0-3.462384 2.596788-5.193576 6.924768-5.193575 11.252748z" fill="currentColor" p-id="12394"></path></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -0,0 +1 @@
<svg t="1726715680698" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7198" width="200" height="200"><path d="M515.451851 803.276868c0-159.757781 129.475473-289.130213 289.198907-289.130213a288.511974 288.511974 0 0 1 219.349242 100.750213V121.300967A121.289518 121.289518 0 0 0 902.710482 0H121.30099A121.289518 121.289518 0 0 0 0.000023 121.358211v781.352248a121.289518 121.289518 0 0 0 121.358211 121.289518h496.412328a288.580667 288.580667 0 0 1-102.318711-220.723109zM204.625995 212.342523a34.346664 34.346664 0 0 1 34.346664-34.346664h546.11195a34.346664 34.346664 0 0 1 34.346663 34.346664 34.346664 34.346664 0 0 1-34.346663 34.346663h-546.11195a34.346664 34.346664 0 0 1-34.346664-34.346663z m306.830194 194.631093a34.346664 34.346664 0 0 1-34.346663 34.346663h-238.136867a34.346664 34.346664 0 0 1-34.346664-34.346663 34.346664 34.346664 0 0 1 34.346664-34.346664h238.136867a34.346664 34.346664 0 0 1 34.346663 34.346664z" p-id="7199"></path><path d="M804.650758 582.748391c-121.793269 0-220.528478 98.735209-220.528478 220.528477s98.735209 220.528478 220.528478 220.528478S1025.167787 925.070137 1025.167787 803.276868 926.444027 582.748391 804.650758 582.748391z m100.06328 319.584255a28.702362 28.702362 0 0 1-40.483268 0l-79.890339-79.855993a28.542077 28.542077 0 0 1-8.311893-21.592602v-114.191207a28.62222 28.62222 0 0 1 57.24444 0v103.726923l71.44106 71.441061a28.702362 28.702362 0 0 1 0 40.471818z" p-id="7200"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -66,15 +66,36 @@ export const constantRoutes = [
component: () => import('@/views/flow/index.vue'),
meta: { title: '流程创建', icon: 'tree' }
},{
path: '/list',
path: 'list/:type',
name: 'flowList',
hidden: true,
component: () => import('@/views/flow/list.vue'),
meta: { title: '流程监管', icon: 'table', type: 'created-by-me' }
},{
path: 'list/created-by-me',
name: 'flowList',
meta: { title: '流程监管', icon: 'table' }
},{
path: 'list/fav',
name: 'flowList',
meta: { title: '我收藏的', icon: 'fav' }
},{
path: 'list/todo',
name: 'flowList',
meta: { title: '待办流程', icon: 'todo' }
},{
path: 'list/handled',
name: 'flowList',
meta: { title: '办理过的', icon: 'flow-through-me' }
},{
path: 'create',
name: 'create',
component: () => import('@/views/flow/create'),
hidden: true
},{
path: 'detail',
name: 'detail',
component: () => import('@/views/flow/create'),
hidden: true
}]
}

File diff suppressed because it is too large Load Diff

@ -60,8 +60,12 @@ export default {
originalForm(newVal) {
this.form = deepCopy(newVal)
},
fileList(newVal) {
this.file = deepCopy(newVal)
fileList: {
handler:function(newVal) {
this.file = deepCopy(newVal)
},
immediate: true,
deep: true
},
scriptContent(newVal) {
if(newVal) {
@ -77,7 +81,7 @@ export default {
const authFields = this.fields.map(field => ({
...field,
_readable: this.readable.indexOf(field.id) !== -1,
_writeable: this.writeable.indexOf(field.id) !== -1
_writeable: this.writeable.indexOf(field.id) !== -1,
}))
return h('el-form', {
class: 'form',
@ -86,6 +90,8 @@ export default {
'label-position': 'top'
}
},authFields.map(field => formBuilder.bind(this)(this.device, field, h)))
},
created() {
}
}
</script>

@ -164,10 +164,11 @@ export default {
props: {
'show-toolbar': true,
columns: this.vanPopupOption.columns,
'value-key': typeof this.vanPopupOption.columns[0] === 'object' ? 'name' : 'yext'
},
on: {
confirm: value => {
this.$set(this.form,this.vanPopupOption.forFormName,value)
this.$set(this.form,this.vanPopupOption.forFormName,typeof value === 'object' ? value['id'] : value)
this.$set(this.vanPopupOption,'isShow',false)
},
cancel: _ => {

@ -1,6 +1,7 @@
<template>
<div>
<el-dialog
:close-on-click-modal="false"
:title="title"
width="920px"
:visible.sync="visible"
@ -14,9 +15,10 @@
<el-step
:title="node.name"
status="finish"
icon="el-icon-edit"
:icon="isLastNode ? 'el-icon-check' : 'el-icon-edit'"
></el-step>
<el-step
v-if="!isLastNode"
title="流转到下一节点"
icon="el-icon-right"
status="wait"
@ -26,34 +28,36 @@
<el-divider></el-divider>
<div class="next-nodes">
<div class="next-nodes__label">下一节点</div>
<template v-if="!isLastNode">
<div class="next-nodes">
<div class="next-nodes__label">下一节点</div>
<div>
<el-radio-group v-model="form.next_node_id" @change="pickUsers = node2Users.get(form.next_node_id)">
<el-radio v-for="node in node.nextNodes" :label="node.id">{{ node.name }}</el-radio>
</el-radio-group>
<div>
<el-radio-group v-model="form.next_node_id" @change="pickUsers = node2Users.get(form.next_node_id)">
<el-radio v-for="node in node.nextNodes" :label="node.id">{{ node.name }}</el-radio>
</el-radio-group>
</div>
</div>
</div>
<el-divider></el-divider>
<el-divider></el-divider>
<div class="users">
<div class="users__label">承办人员</div>
<div class="users">
<div class="users__label">承办人员</div>
<div>
<el-radio-group v-model="form.user_id">
<div v-for="group in pickUsers" :key="group.id">
<div class="group-name">{{ group.name }}</div>
<el-radio v-for="user in group.users" :label="user.id">{{ user.name }}</el-radio>
</div>
</el-radio-group>
<div>
<el-radio-group v-model="form.user_id">
<div v-for="group in pickUsers" :key="group.id">
<div class="group-name">{{ group.name }}</div>
<el-radio v-for="user in group.users" :label="user.id">{{ user.name }}</el-radio>
</div>
</el-radio-group>
</div>
</div>
</div>
</template>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submit"
> </el-button
>{{ isLastNode ? '结束流程' : '确 定'}}</el-button
>
</span>
</el-dialog>
@ -74,7 +78,7 @@ export default {
result: {
type: Object,
required: true
}
},
},
data() {
return {
@ -107,8 +111,12 @@ export default {
async submit() {
try {
await assign(this.result.id, this.form)
this.$router.push("/flow/list");
if(this.isLastNode) {
await assign(this.result.id)
} else {
await assign(this.result.id, this.form)
}
this.$router.push("/flow/list/handled");
} catch(err) {
}
@ -121,19 +129,14 @@ export default {
node() {
return this.config?.currentNode || {};
},
isLastNode() {
return this.node?.category === 'end'
}
},
watch: {
// node: {
// handler:function (newVal) {
// if(newVal && newVal.nextNodes && newVal.nextNodes?.length > 0) {
// this.getNextNodesUsers()
// }
// },
// immediate: true
// },
visible(newVal) {
if(newVal) {
if(this.node && this.node.nextNodes && this.node.nextNodes?.length > 0) {
if(this.node && this.node.nextNodes && this.node.nextNodes?.length > 0 && !this.isLastNode) {
this.getNextNodesUsers()
}
}
@ -163,4 +166,8 @@ export default {
display: flex;
justify-content: center;
}
::v-deep .steps {
display: flex;
justify-content: center;
}
</style>

@ -6,7 +6,7 @@
</template>
<template>
<div class="steps">
<div class="steps" v-if="!/\/detail/.test($route.path)">
<el-steps :space="120" finish-status="success" align-center>
<el-step
:title="node.name"
@ -21,9 +21,10 @@
status="wait"
></el-step>
</el-steps>
</div>
<el-divider></el-divider>
<el-divider></el-divider>
</div>
<div class="form-container">
<template v-if="device === 'desktop'">
@ -55,14 +56,101 @@
</div>
</template>
<!-- 审批日志-->
<div v-if="/\/detail/.test($route.path)" style="margin-top: 10px">
<div>流转记录</div>
<vxe-table
ref="table"
stripe
keep-source
show-overflow
:column-config="{ resizable: true }"
:print-config="{}"
:export-config="{}"
:custom-config="{ mode: 'popup' }"
:data="config.logs || []"
>
<vxe-column type="seq" width="58" align="center" title="编号"/>
<vxe-column title="节点名称" align="center" field="node.name"></vxe-column>
<vxe-column title="办理状态" field="status_label"></vxe-column>
<vxe-column title="承办人员" field="user.name"></vxe-column>
<vxe-column title="流转时间" field="created_at"></vxe-column>
<vxe-column title="退回原因" field="reason"></vxe-column>
<vxe-column title="办理时间" field="updated_at"></vxe-column>
<vxe-column title="耗时"></vxe-column>
</vxe-table>
</div>
<div class="btns" ref="btns">
<el-button type="primary" size="small" @click="submit('assign')"
<template v-if="!/\/detail/.test($route.path)">
<el-button
v-if="$route.query.flow_id"
icon="el-icon-arrow-left"
type="danger"
size="small"
@click=""
>退回</el-button
>
<el-button
v-if="$route.query.flow_id"
icon="el-icon-caret-right"
type="primary"
plain
size="small"
@click=""
>部门内转办</el-button
>
<el-button
v-if="$route.query.flow_id"
icon="el-icon-document-add"
type="info"
size="small"
@click="submit('only-submit')"
>暂存不流转</el-button
>
<el-button type="primary" size="small" @click="submit('assign')"
>保存并流转 <i class="el-icon-right"></i
></el-button>
></el-button>
<el-button
v-if="!$route.query.flow_id"
type="info"
size="small"
@click="$router.go(-1)"
>返回</el-button
>
</template>
<template v-else>
<el-button
plain
size="small"
@click="$router.go(-1)"
>返回</el-button
>
<el-button
plain
size="small"
>打印</el-button
>
<el-button
plain
size="small"
>打印(带审批记录)</el-button
>
<el-button
plain
size="small"
>下载附件</el-button
>
</template>
</div>
</el-card>
<assign ref="assign" :visible.sync="isShowAssign" :config="config" :result="result"></assign>
<assign
ref="assign"
:visible.sync="isShowAssign"
:config="config"
:result="result"
></assign>
<el-backtop></el-backtop>
</div>
@ -72,7 +160,7 @@
import DesktopForm from "./DesktopForm.vue";
import MobileForm from "./MobileForm.vue";
import assign from "./components/assign.vue";
import {create, fieldConfig, preConfig,} from "@/api/flow";
import { create, deal, fieldConfig, preConfig, preDeal, view } from "@/api/flow";
import { deepCopy } from "@/utils";
export default {
@ -118,76 +206,183 @@ export default {
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.8)",
});
try {
const res = await preConfig(this.$route.query.module_id);
const { fields } = res?.customModel;
let subFormRequest = [];
const getSubForm = (id) => {
subFormRequest.push(fieldConfig(id));
};
fields.forEach((field) => {
if (field.sub_custom_model_id) {
getSubForm(field.sub_custom_model_id);
//detail
if(/\/detail/.test(this.$route.path) && this.$route.query.flow_id) {
try {
const res = await view(this.$route.query.flow_id);
console.log('view',res)
const { fields } = res?.customModel;
let subFormRequest = [];
const getSubForm = (id) => {
subFormRequest.push(fieldConfig(id));
};
fields.forEach((field) => {
if (field.sub_custom_model_id) {
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]);
if (this.form.hasOwnProperty(key)) {
this.form[key] = jsonObj;
}
if (this.fileList.hasOwnProperty(key)) {
this.fileList[key] = jsonObj.map((i) => ({
name: i.name,
url: i.url,
response: i,
}));
}
} catch (err) {
if (this.form.hasOwnProperty(key)) {
this.form[key] = data[key];
}
}
}
});
const subConfigs = await Promise.all(subFormRequest);
subConfigs.forEach((sub) => {
if (sub.customModel?.id) {
this.subConfig.set(sub.customModel?.id, sub);
this.fileList = Object.assign({}, this.fileList);
loading.close();
} catch (err) {
console.error(err);
this.$message.error("配置失败");
loading.close();
}
} else if (!this.$route.query.flow_id) {
try {
const res = await preConfig(this.$route.query.module_id);
const { fields } = res?.customModel;
let subFormRequest = [];
const getSubForm = (id) => {
subFormRequest.push(fieldConfig(id));
};
fields.forEach((field) => {
if (field.sub_custom_model_id) {
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);
loading.close();
} catch (err) {
console.error(err);
this.$message.error("配置失败");
loading.close();
}
} else {
try {
const res = await preDeal(this.$route.query.flow_id);
const { fields } = res?.customModel;
let subFormRequest = [];
const getSubForm = (id) => {
subFormRequest.push(fieldConfig(id));
};
fields.forEach((field) => {
if (field.sub_custom_model_id) {
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]);
if (this.form.hasOwnProperty(key)) {
this.form[key] = jsonObj;
}
if (this.fileList.hasOwnProperty(key)) {
this.fileList[key] = jsonObj.map((i) => ({
name: i.name,
url: i.url,
response: i,
}));
}
} catch (err) {
if (this.form.hasOwnProperty(key)) {
this.form[key] = data[key];
}
}
}
});
this.config = res;
this.generateForm(this.form, fields);
this.form = Object.assign({}, this.form);
loading.close();
} catch (err) {
console.error(err);
this.$message.error("配置失败");
loading.close();
this.fileList = Object.assign({}, this.fileList);
loading.close();
} catch (err) {
console.error(err);
this.$message.error("配置失败");
loading.close();
}
}
},
async submit(type) {
let copyForm,copyFile;
if (this.device === "desktop") {
console.log(this.$refs["desktopForm"].form);
let copyForm = deepCopy(this.$refs["desktopForm"].form);
let copyFile = deepCopy(this.$refs["desktopForm"].file);
for (let [key, value] of Object.entries(copyFile)) {
if (copyForm.hasOwnProperty(key)) {
copyForm[key] = value.map((i) => i.response?.id)?.toString();
}
copyForm = deepCopy(this.$refs["desktopForm"].form);
copyFile = deepCopy(this.$refs["desktopForm"].file);
} else {
copyForm = deepCopy(this.$refs["mobileForm"].form);
copyFile = deepCopy(this.$refs["mobileForm"].file);
}
console.log(copyForm,copyFile)
for (let [key, value] of Object.entries(copyFile)) {
if (copyForm.hasOwnProperty(key)) {
copyForm[key] = value.map((i) => i.response?.id)?.toString();
}
// for (let key in copyForm) {
// if(copyForm[key] instanceof Array && copyForm[key][0]) {
// let formatObj = {}
// let subKeys = Object.keys(copyForm[key][0])
// subKeys.forEach(key => {
// formatObj[key] = []
// })
// copyForm[key].forEach(item => {
// subKeys.forEach(subKey => {
// formatObj[subKey].push(item[subKey])
// })
// })
// delete formatObj['_X_ROW_KEY']
// copyForm[key] = formatObj
//
// }
// }
}
copyForm["current_node_id"] = this.config.currentNode.id;
try {
this.result = await create(copyForm, this.$route.query.module_id);
switch (type) {
case "only-submit":
this.$router.push("/flow/list");
break;
case "assign":
this.isShowAssign = true;
break;
}
} catch (err) {
console.error(err);
try {
let callback;
switch (type) {
case "only-submit":
if (this.$route.query.flow_id) {
copyForm["temporary_save"] = 1;
}
callback = () => this.$router.push("/flow/list/todo");
break;
case "assign":
if (this.$route.query.flow_id) {
copyForm["temporary_save"] = 0;
}
callback = () => (this.isShowAssign = true);
break;
}
if (this.$route.query.flow_id) {
copyForm.id = this.$route.query.flow_id;
const { flow, is_last_handled_log } = await deal(
this.$route.query.flow_id,
copyForm
);
this.result = flow;
} else {
this.result = await create(this.$route.query.module_id, copyForm);
}
callback();
} catch (err) {
console.error(err);
}
},
},
@ -199,7 +394,7 @@ export default {
return this.config?.customModel?.fields || [];
},
readableFields() {
return this.config?.currentNode?.readable || [];
return /\/detail/.test(this.$route.path) ? this.fields?.map(i => i.id) : (this.config?.currentNode?.readable || []);
},
writeableFields() {
return this.config?.currentNode?.writeable || [];
@ -208,7 +403,9 @@ export default {
return this.config?.currentNode || {};
},
scriptContent() {
if (this.config?.customModel?.js) {
if (this.config?.customModel?.view_js && this.$route.query.flow_id) {
return this.config?.customModel?.view_js;
} else if (this.config?.customModel?.js && !this.$route.query.flow_id) {
return this.config?.customModel?.js;
}
},
@ -230,9 +427,12 @@ export default {
position: relative;
}
.btns {
display: flex;
justify-content: center;
margin-top: 10px;
position: sticky;
bottom: 20px;
flex-wrap: wrap;
}
}
.form-container {

@ -3,7 +3,7 @@
<el-card shadow="always">
<template #header>
<p>{{ title }}</p>
<vxe-toolbar ref="toolbar" custom print>
<vxe-toolbar ref="toolbar" custom print export>
<template #buttons>
<div class="selects">
<el-select
@ -79,15 +79,155 @@
show-overflow
:column-config="{ resizable: true }"
:print-config="{}"
:export-config="{}"
:custom-config="{ mode: 'popup' }"
:data="list"
>
<vxe-column field="title" title="工作名称"></vxe-column>
<vxe-column width="80" align="center" field="id" title="流水号"></vxe-column>
<vxe-column field="custom_model.name" title="流程名称"></vxe-column>
<vxe-column width="200" align="center" field="created_at" title="发起日期" :formatter="({ cellValue }) => $moment(cellValue).format('YYYY-MM-DD HH:mm:ss')"></vxe-column>
<vxe-column width="100" align="center" field="status" title="当前状态"></vxe-column>
<vxe-column
v-if="$route.params.type === 'created-by-me'"
align="center"
type="checkbox"
width="40"
title=""
></vxe-column>
<vxe-column
min-width="100"
header-align="center"
field="title"
title="工作名称"
></vxe-column>
<vxe-column
v-if="$route.params.type === 'created-by-me'"
width="80"
align="center"
field="id"
title="流水号"
></vxe-column>
<vxe-column
v-if="$route.params.type === 'created-by-me'"
width="80"
title="发起人"
align="center"
field="creator.name"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'created-by-me'"
width="80"
title="承办人员"
align="center"
field="last_log.user.name"
></vxe-column>
<vxe-column
header-align="center"
min-width="140"
field="custom_model.name"
title="流程名称"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'created-by-me'"
align="center"
width="140"
field="current_node.name"
title="当前节点"
></vxe-column>
<vxe-column
v-if="$route.params.type !== 'created-by-me'"
title="收藏状态"
width="90"
field="my_fav"
align="center"
>
<template #default="{ row }">
<el-button
:type="row.my_fav ? 'success' : 'primary'"
size="mini"
@click="toggleFav(row)"
>{{ row.my_fav ? "已收藏" : "未收藏" }}</el-button
>
</template>
</vxe-column>
<vxe-column
width="164"
field="no"
align="center"
title="编号"
></vxe-column>
<vxe-column
width="200"
v-if="$route.params.type === 'created-by-me'"
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-column
width="80"
align="center"
field="status"
title="当前状态"
:formatter="({ cellValue }) => myStatus.get(cellValue)"
:export-method="
({ row, column, options }) => myStatus.get(row['status'])
"
>
<template #default="{ row }">
<el-tag
size="mini"
:type="statusColor.get(row.status)"
effect="dark"
>{{ myStatus.get(row.status) }}</el-tag
>
</template>
</vxe-column>
<vxe-column
min-width="280"
header-align="center"
field="status"
title="操作"
fixed="right"
>
<template #default="{ row }">
<template v-if="$route.params.type !== 'created-by-me'">
<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
>
</template>
</vxe-column>
</vxe-table>
<el-pagination
@ -106,7 +246,7 @@
}
"
:current-page="select.page"
:page-sizes="[20, 30, 40, 50]"
:page-sizes="[10, 20, 30, 40, 50]"
:page-size="select.page_size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@ -118,11 +258,22 @@
</template>
<script>
import { flowList } from "@/api/flow";
import { flowList, toggleFav, destroy, recall } from "@/api/flow";
import moment from "moment/moment";
export default {
data() {
return {
myStatus: new Map([
[-1, "已退回"],
[0, "办理中"],
[1, "已完成"],
]),
statusColor: new Map([
[-1, "warning"],
[0, ""],
[1, "success"],
]),
pickerOptions: {
shortcuts: [
{
@ -212,10 +363,44 @@ export default {
};
},
methods: {
handle(row) {
this.$router.push(
`/flow/create?module_id=${row.custom_model.id}&flow_id=${row.id}`
);
},
detail(row) {
this.$router.push(
`/flow/detail?module_id=${row.custom_model.id}&flow_id=${row.id}`
);
},
async toggleFav(row) {
try {
await toggleFav({
id: row.id,
});
await this.getList();
} catch (err) {}
},
async recall(row) {
try {
await recall({ id: row.id })
await this.getList()
} catch (err) {}
},
async copyTo(row) {},
async destroy(row) {
try {
await destroy({ id: row.id })
await this.getList()
} catch (err) {}
},
async getList() {
this.loading = true;
try {
const res = await flowList(this.$route.meta.type, this.select, false);
const res = await flowList(this.$route.params.type, this.select, false);
console.log(res);
this.list = res?.data?.data || [];
this.total = res?.data?.total ?? 0;
@ -234,12 +419,11 @@ export default {
},
mounted() {
this.$nextTick(() => {
if(this.$refs['table'] && this.$refs['toolbar']) {
this.$refs['table'].connect(this.$refs['toolbar'])
if (this.$refs["table"] && this.$refs["toolbar"]) {
this.$refs["table"].connect(this.$refs["toolbar"]);
}
})
}
});
},
};
</script>

@ -69,13 +69,6 @@ const defaultSettings = require('../../../src/settings.js')
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请正确输入登录名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码输入错误'))
@ -93,8 +86,7 @@ export default {
loginRules: {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
trigger: 'blur'
}],
password: [{
required: true,

Loading…
Cancel
Save