ui Check Workflow
This commit is contained in:
parent
7fcd4968c5
commit
a75773b747
4 changed files with 534 additions and 0 deletions
|
|
@ -99,4 +99,7 @@ export default {
|
||||||
/** หมอบหมาย*/
|
/** หมอบหมาย*/
|
||||||
commandSysAssign: `${organization}/commandSys/assign`,
|
commandSysAssign: `${organization}/commandSys/assign`,
|
||||||
posAssign: `${organization}/pos/assign`,
|
posAssign: `${organization}/pos/assign`,
|
||||||
|
|
||||||
|
/** View Work Flow*/
|
||||||
|
viewWorkflow: `${organization}/view-workflow`,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
73
src/interface/viewWorkflow/response.ts
Normal file
73
src/interface/viewWorkflow/response.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
interface DataWorkflow {
|
||||||
|
name: string;
|
||||||
|
sysName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkflowLists {
|
||||||
|
createdAt: string;
|
||||||
|
createdFullName: string;
|
||||||
|
createdUserId: string;
|
||||||
|
id: string;
|
||||||
|
lastUpdateFullName: string;
|
||||||
|
lastUpdateUserId: string;
|
||||||
|
lastUpdatedAt: string;
|
||||||
|
metaWorkflowId: string;
|
||||||
|
name: string;
|
||||||
|
order: number;
|
||||||
|
type: string;
|
||||||
|
metaStateOperators: MetaStateOperators[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MetaStateOperators {
|
||||||
|
canCancel: boolean;
|
||||||
|
canChangeState: boolean;
|
||||||
|
canComment: boolean;
|
||||||
|
canDelete: boolean;
|
||||||
|
canOperate: boolean;
|
||||||
|
canSign: boolean;
|
||||||
|
canUpdate: boolean;
|
||||||
|
canView: boolean;
|
||||||
|
createdAt: string;
|
||||||
|
createdFullName: string;
|
||||||
|
createdUserId: string;
|
||||||
|
id: string;
|
||||||
|
lastUpdateFullName: string;
|
||||||
|
lastUpdateUserId: string;
|
||||||
|
lastUpdatedAt: string;
|
||||||
|
metaStateId: string;
|
||||||
|
operator: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OptionsType {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
posLevels: PosLevel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OptionsLevel {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PosType {
|
||||||
|
id: string;
|
||||||
|
posTypeName: string;
|
||||||
|
posTypeRank: number;
|
||||||
|
posLevels: PosLevel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PosLevel {
|
||||||
|
id: string;
|
||||||
|
posLevelAuthority: string;
|
||||||
|
posLevelName: string;
|
||||||
|
posLevelRank: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {
|
||||||
|
WorkflowLists,
|
||||||
|
DataWorkflow,
|
||||||
|
OptionsType,
|
||||||
|
OptionsLevel,
|
||||||
|
PosType,
|
||||||
|
PosLevel,
|
||||||
|
};
|
||||||
|
|
@ -4,6 +4,7 @@ const MainLayout = () => import("@/views/MainLayout.vue");
|
||||||
const Dashboard = () => import("@/views/Dashboard.vue");
|
const Dashboard = () => import("@/views/Dashboard.vue");
|
||||||
const Error404NotFound = () => import("@/views/Error404NotFound.vue");
|
const Error404NotFound = () => import("@/views/Error404NotFound.vue");
|
||||||
const loginView = () => import("@/views/login.vue");
|
const loginView = () => import("@/views/login.vue");
|
||||||
|
const CheckWorkflow = () => import("@/views/CheckWorkflow.vue");
|
||||||
|
|
||||||
import ModuleMetadata from "@/modules/01_metadata/router";
|
import ModuleMetadata from "@/modules/01_metadata/router";
|
||||||
import ModuleUser from "@/modules/02_users/router";
|
import ModuleUser from "@/modules/02_users/router";
|
||||||
|
|
@ -32,6 +33,16 @@ const router = createRouter({
|
||||||
Role: ["SUPER_ADMIN", "ADMIN"],
|
Role: ["SUPER_ADMIN", "ADMIN"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/check-workflow",
|
||||||
|
name: "check-workflow",
|
||||||
|
component: CheckWorkflow,
|
||||||
|
meta: {
|
||||||
|
Auth: true,
|
||||||
|
Key: [7],
|
||||||
|
Role: ["SUPER_ADMIN", "ADMIN"],
|
||||||
|
},
|
||||||
|
},
|
||||||
...ModuleMetadata,
|
...ModuleMetadata,
|
||||||
...ModuleUser,
|
...ModuleUser,
|
||||||
...ModuleLogs,
|
...ModuleLogs,
|
||||||
|
|
|
||||||
447
src/views/CheckWorkflow.vue
Normal file
447
src/views/CheckWorkflow.vue
Normal file
|
|
@ -0,0 +1,447 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from "vue";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import type {
|
||||||
|
WorkflowLists,
|
||||||
|
DataWorkflow,
|
||||||
|
OptionsType,
|
||||||
|
OptionsLevel,
|
||||||
|
PosType,
|
||||||
|
PosLevel,
|
||||||
|
} from "@/interface/viewWorkflow/response";
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
|
const { showLoader, hideLoader, messageError } = useCounterMixin();
|
||||||
|
|
||||||
|
const isSearch = ref<boolean>(false);
|
||||||
|
const formFilter = reactive({
|
||||||
|
name: "",
|
||||||
|
type: "",
|
||||||
|
level: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataWorkflow = ref<DataWorkflow[]>([]);
|
||||||
|
const dataType = ref<OptionsType[]>([]);
|
||||||
|
const dataLevel = ref<OptionsLevel[]>([]);
|
||||||
|
const optionName = ref<DataWorkflow[]>([]);
|
||||||
|
const optionType = ref<OptionsType[]>([]);
|
||||||
|
const optionLevel = ref<OptionsLevel[]>([]);
|
||||||
|
|
||||||
|
const rows = ref<WorkflowLists[]>([]);
|
||||||
|
const expanded = ref<string[]>(["รอดำเนินการ"]);
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ขั้นตอนการทำงาน",
|
||||||
|
sortable: false,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const columnsExpanded = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "operator",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: false,
|
||||||
|
field: "operator",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canCancel",
|
||||||
|
align: "left",
|
||||||
|
label: "canCancel",
|
||||||
|
sortable: false,
|
||||||
|
field: "canCancel",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canChangeState",
|
||||||
|
align: "left",
|
||||||
|
label: "canChangeState",
|
||||||
|
sortable: false,
|
||||||
|
field: "canChangeState",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canComment",
|
||||||
|
align: "left",
|
||||||
|
label: "canComment",
|
||||||
|
sortable: false,
|
||||||
|
field: "canComment",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canDelete",
|
||||||
|
align: "left",
|
||||||
|
label: "canDelete",
|
||||||
|
sortable: false,
|
||||||
|
field: "canDelete",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canOperate",
|
||||||
|
align: "left",
|
||||||
|
label: "canOperate",
|
||||||
|
sortable: false,
|
||||||
|
field: "canOperate",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canSign",
|
||||||
|
align: "left",
|
||||||
|
label: "canSign",
|
||||||
|
sortable: false,
|
||||||
|
field: "canSign",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canUpdate",
|
||||||
|
align: "left",
|
||||||
|
label: "canUpdate",
|
||||||
|
sortable: false,
|
||||||
|
field: "canUpdate",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "canView",
|
||||||
|
align: "left",
|
||||||
|
label: "canView",
|
||||||
|
sortable: false,
|
||||||
|
field: "canView",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
function fetchWorkflowList() {
|
||||||
|
http
|
||||||
|
.get(config.API.viewWorkflow + `/lists`)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
dataWorkflow.value = data;
|
||||||
|
optionName.value = data;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
messageError($q, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchType() {
|
||||||
|
http
|
||||||
|
.get(config.API.orgPosType)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
dataType.value = data.map((e: PosType) => ({
|
||||||
|
id: e.posTypeName,
|
||||||
|
name: e.posTypeName,
|
||||||
|
posLevels: e.posLevels,
|
||||||
|
}));
|
||||||
|
optionType.value = dataType.value;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
messageError($q, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSelectPosType(id: string) {
|
||||||
|
const data = dataType.value.find(
|
||||||
|
(e: OptionsType) => e.id === id && e.posLevels
|
||||||
|
)?.posLevels;
|
||||||
|
|
||||||
|
dataLevel.value =
|
||||||
|
data?.map((e: PosLevel) => ({
|
||||||
|
id: e.posLevelName,
|
||||||
|
name: e.posLevelName,
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
formFilter.level = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function searchWorkflow() {
|
||||||
|
if (
|
||||||
|
formFilter.name !== "" &&
|
||||||
|
formFilter.type !== "" &&
|
||||||
|
formFilter.level !== ""
|
||||||
|
) {
|
||||||
|
showLoader();
|
||||||
|
rows.value = [];
|
||||||
|
await http
|
||||||
|
.get(
|
||||||
|
config.API.viewWorkflow +
|
||||||
|
`?sysName=${formFilter.name}&posTypeName=${formFilter.type}&posLevelName=${formFilter.level}`
|
||||||
|
)
|
||||||
|
.then(async (res) => {
|
||||||
|
const data = await res.data.result;
|
||||||
|
if (data && data[0]?.metaStates) {
|
||||||
|
rows.value = data[0].metaStates;
|
||||||
|
expanded.value = rows.value.map((e: WorkflowLists) => e.name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
messageError($q, err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
hideLoader();
|
||||||
|
isSearch.value = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterSelector(val: string, update: Function, refData: string) {
|
||||||
|
switch (refData) {
|
||||||
|
case "name":
|
||||||
|
update(() => {
|
||||||
|
optionName.value = dataWorkflow.value.filter(
|
||||||
|
(v: DataWorkflow) => v.name.indexOf(val) > -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "type":
|
||||||
|
update(() => {
|
||||||
|
optionType.value = dataType.value.filter(
|
||||||
|
(v: OptionsType) => v.name.indexOf(val) > -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "level":
|
||||||
|
update(() => {
|
||||||
|
optionLevel.value = dataLevel.value.filter(
|
||||||
|
(v: OptionsLevel) => v.name.indexOf(val) > -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
showLoader();
|
||||||
|
await Promise.all([fetchType(), fetchWorkflowList()]).finally(() => {
|
||||||
|
hideLoader();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="toptitle text-dark col-12 row items-center">Check Workflow</div>
|
||||||
|
|
||||||
|
<div class="q-pa-sm">
|
||||||
|
<q-card>
|
||||||
|
<div class="row col-12 q-mb-sm">
|
||||||
|
<q-form
|
||||||
|
class="col-12"
|
||||||
|
q-form
|
||||||
|
greedy
|
||||||
|
@submit.prevent
|
||||||
|
@validation-success="searchWorkflow"
|
||||||
|
>
|
||||||
|
<div class="row justify-between q-gutter-y-sm q-pa-lg">
|
||||||
|
<div class="col-6 col-md-4">
|
||||||
|
<q-select
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
use-input
|
||||||
|
lazy-rules
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
hide-bottom-space
|
||||||
|
option-label="name"
|
||||||
|
option-value="sysName"
|
||||||
|
v-model="formFilter.name"
|
||||||
|
:options="optionName"
|
||||||
|
label="Workflow"
|
||||||
|
:rules="[(val: string) => !!val || `${'กรุณาเลือก Workflow'}`]"
|
||||||
|
@filter="(inputValue: string,
|
||||||
|
doneFn: Function) => filterSelector(inputValue, doneFn, 'name'
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<template v-slot:no-option>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section class="text-italic text-grey">
|
||||||
|
ไม่มีข้อมูล
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 col-md-3">
|
||||||
|
<q-select
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
use-input
|
||||||
|
lazy-rules
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
hide-bottom-space
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="formFilter.type"
|
||||||
|
:options="optionType"
|
||||||
|
@update:model-value="onSelectPosType"
|
||||||
|
label="ประเภทตำแหน่ง"
|
||||||
|
:rules="[(val: string) => !!val || `${'กรุณาเลือก ประเภทตำแหน่ง'}`]"
|
||||||
|
@filter="(inputValue: string,
|
||||||
|
doneFn: Function) => filterSelector(inputValue, doneFn, 'type'
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<template v-slot:no-option>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section class="text-italic text-grey">
|
||||||
|
ไม่มีข้อมูล
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 col-md-3">
|
||||||
|
<q-select
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
use-input
|
||||||
|
lazy-rules
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
hide-bottom-space
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="formFilter.level"
|
||||||
|
:options="optionLevel"
|
||||||
|
label="ระดับตำแหน่ง"
|
||||||
|
:rules="[(val: string) => !!val || `${'กรุณาเลือก ระดับตำแหน่ง'}`]"
|
||||||
|
@filter="(inputValue: string,
|
||||||
|
doneFn: Function) => filterSelector(inputValue, doneFn, 'level'
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<template v-slot:no-option>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section class="text-italic text-grey">
|
||||||
|
ไม่มีข้อมูล
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-btn
|
||||||
|
type="submit"
|
||||||
|
dense
|
||||||
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
class="col-5 col-md-1"
|
||||||
|
label="ค้นหา"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-card v-if="isSearch">
|
||||||
|
<d-table
|
||||||
|
v-if="rows.length !== 0"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
row-key="name"
|
||||||
|
v-model:expanded="expanded"
|
||||||
|
:hide-bottom="true"
|
||||||
|
>
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
{{ col.label }}
|
||||||
|
</q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
{{ col.value }}
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr v-show="props.expand" :props="props">
|
||||||
|
<q-td colspan="100%">
|
||||||
|
<div class="q-pa-md">
|
||||||
|
<q-card bordered>
|
||||||
|
<q-card-section style="padding: 0px">
|
||||||
|
<d-table
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
:rows="props.row.metaStateOperators"
|
||||||
|
:columns="columnsExpanded"
|
||||||
|
row-key="name"
|
||||||
|
:hide-bottom="true"
|
||||||
|
>
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
>
|
||||||
|
{{ col.label }}
|
||||||
|
</q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
>
|
||||||
|
<div v-if="col.name !== 'operator'">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value"
|
||||||
|
name="check"
|
||||||
|
color="primary"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</d-table>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</d-table>
|
||||||
|
|
||||||
|
<q-banner inline-actions rounded class="bg-grey-1 text-center" v-else>
|
||||||
|
ไม่มีข้อมูล
|
||||||
|
</q-banner>
|
||||||
|
</q-card>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue