<template>
|
<div style="background-color: white; margin: 10px 10px; height: auto;">
|
<div style="padding: 10px 20px;">
|
<el-row>
|
<el-col :span="12">
|
<div v-if="user" style="padding: 10px 20px;display: flex; align-items: center; justify-items: inherit;">
|
<div>
|
<el-avatar v-if="user.employee&&user.employee.userface" :size="70" :src="user.employee.userface"
|
style="margin-right: 5px;margin-top: 5px;"/>
|
<svg-icon v-else name="administrator" width="70" height="70"
|
style="margin-right: 5px;margin-top: 5px; border-radius: 100px;" color=""/>
|
</div>
|
<div>
|
<p class="text-overflow">
|
<el-text tag="b" size="default" type="primary">
|
{{ $t('message.HelloWords', {name: user.name}) }}
|
</el-text>
|
</p>
|
<p class="text-overflow" v-if="positiontitle||organizationStructure">
|
<el-text type="info">
|
{{ `${positiontitle}|${organizationStructure}` }}
|
</el-text>
|
</p>
|
<p class="text-overflow" v-else>
|
<el-text v-for="(item,i) in user.roles" type="info">
|
{{ $t('label.Role', {name: user.name}) }} / {{ `${item.name} (${item.code})` }}
|
</el-text>
|
</p>
|
</div>
|
</div>
|
<div v-else style="padding: 10px 20px;">
|
<el-skeleton style="--el-skeleton-circle-size: 80px">
|
<template #template>
|
<div style="display: flex; align-items: center; justify-items: inherit;">
|
<div>
|
<el-skeleton-item variant="circle"/>
|
</div>
|
<div style="margin: 0 10px;">
|
<el-skeleton-item variant="text" style="width: 150px;"/>
|
<br/>
|
<el-skeleton-item variant="text" style="width: 220px;"/>
|
<br/>
|
<el-skeleton-item variant="text" style="width: 300px;"/>
|
</div>
|
</div>
|
</template>
|
</el-skeleton>
|
</div>
|
</el-col>
|
<el-col :span="12">
|
<div style="display: flex;justify-content: space-between">
|
<div class="statistic-card">
|
<el-statistic :value="98500">
|
<template #title>
|
<div style="display: inline-flex; align-items: center">
|
{{ $t('label.MyTask') }}
|
</div>
|
</template>
|
</el-statistic>
|
</div>
|
<div class="statistic-card">
|
<el-statistic :value="693700">
|
<template #title>
|
<div style="display: inline-flex; align-items: center">
|
{{ $t('label.MyApproval') }}
|
</div>
|
</template>
|
</el-statistic>
|
</div>
|
<div class="statistic-card">
|
<el-statistic :value="72000">
|
<template #title>
|
<div style="display: inline-flex; align-items: center">
|
{{ $t('label.MyNotification') }}
|
</div>
|
</template>
|
</el-statistic>
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
<el-divider :style="{'margin':'0px 0px 10px 0px'}"></el-divider>
|
<el-row :style="{'margin':'5px 0px'}">
|
<el-col :span="16">
|
<el-row>
|
<el-col :span="24">
|
<el-card>
|
<el-tabs style="min-height: 300px;">
|
<el-tab-pane
|
v-if="operations.filter(e=>e.children.filter(p=>p.path&&p.path.includes('ContractPurchase')).length>0)">
|
<template #label>
|
<span>
|
<svg-icon width="18" height="18" name="purchase" color=""/>
|
{{ `${$t('menu.ContractPurchase')}` }}
|
</span>
|
</template>
|
</el-tab-pane>
|
<el-tab-pane
|
v-if="operations.filter(e=>e.children.filter(p=>p.path&&p.path.includes('ContractSale')).length>0)">
|
<template #label>
|
<span>
|
<svg-icon width="18" height="18" name="sale" color=""/>
|
{{ `${$t('menu.ContractSales')}` }}
|
</span>
|
</template>
|
</el-tab-pane>
|
</el-tabs>
|
</el-card>
|
</el-col>
|
</el-row>
|
<el-row style="margin-top: 10px;">
|
<el-col :span="24">
|
<el-card>
|
<el-tabs style="min-height: 300px;">
|
<el-tab-pane>
|
<template #label>
|
<span>
|
<svg-icon width="18" height="18" name="task" color=""/>
|
{{ $t('label.MyTask') }}
|
</span>
|
</template>
|
<LatestTask/>
|
</el-tab-pane>
|
<el-tab-pane>
|
<template #label>
|
<span>
|
<svg-icon width="18" height="18" name="approval" color=""/>
|
{{ $t('label.MyApproval') }}
|
</span>
|
</template>
|
<LatestApproval/>
|
</el-tab-pane>
|
</el-tabs>
|
</el-card>
|
</el-col>
|
</el-row>
|
</el-col>
|
<el-col :span="8" style="padding: 0 0 0 10px;">
|
<el-row>
|
<el-col :span="24">
|
<el-card>
|
<div style="display: flex;justify-content: space-between">
|
<div>
|
<span style="margin-right: 20px">
|
<svg-icon width="16" height="16" name="menu" color=""/>
|
{{ `${$t('label.QuickNavigation')}` }}
|
</span>
|
</div>
|
<div>
|
|
</div>
|
</div>
|
<el-divider style="margin: 10px 0px"/>
|
<el-scrollbar height="180px">
|
<el-col :span="24" v-for="(operation, i) in operations">
|
<MenuButton v-for="(item, i) in operation.children" :index="i+1+''"
|
style="margin: 2px;" :item="item"
|
height="75px" color="" width="105px"/>
|
</el-col>
|
</el-scrollbar>
|
</el-card>
|
</el-col>
|
</el-row>
|
<el-row style="margin-top: 10px;">
|
<el-col :span="24">
|
<el-card>
|
<div style="display: flex;justify-content: space-between">
|
<div>
|
<span style="margin-right: 20px;">
|
<svg-icon width="18" height="18" name="notification" color=""/>
|
{{ `${$t('label.Latest')}${$t('label.MyNotification')}` }}
|
</span>
|
</div>
|
<div>
|
|
</div>
|
</div>
|
<el-divider style="margin: 10px 0px"/>
|
<LatestNotification/>
|
</el-card>
|
</el-col>
|
</el-row>
|
</el-col>
|
</el-row>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import * as icon from '@element-plus/icons-vue'
|
import {getCurrentInstance, onBeforeUnmount, onMounted, reactive, toRefs, watch} from "vue";
|
import {useBasicInfoStore} from "@/store/basicInfo";
|
import MenuButton from "@/components/common/MenuButton.vue";
|
import {GetEmployeePositionWithOrganizationsByEmployeeId} from "@/api/admin/security";
|
import {GetDashboardData} from "@/api/admin/statistics";
|
import LatestNotification from "@/views/admin/components/LatestNotification.vue";
|
import LatestTask from "@/views/admin/components/LatestTask.vue";
|
import LatestApproval from "@/views/admin/components/LatestApproval.vue";
|
import {
|
formatterDate,
|
formatterDatetime,
|
formatterNumber
|
} from '@/utils/common';
|
|
export default {
|
name: 'Workbench',
|
components: {LatestNotification, LatestTask, LatestApproval, MenuButton},
|
setup() {
|
let {proxy} = getCurrentInstance();
|
const store = useBasicInfoStore();
|
const state = reactive({
|
routes: JSON.parse(localStorage.getItem(`${WGURL.routeKey}-routes`)),
|
user: null,
|
positiontitle: "",
|
organizationStructure: "",
|
operations: [],
|
statisticsdata: {
|
monthlyapprovalrecord: NaN,
|
monthlyactivenotification: NaN,
|
monthlyactivetask: NaN,
|
},
|
});
|
|
onMounted(() => {
|
Init();
|
LoadData();
|
LoadEmployeePositionWithOrganizationsByEmployeeId();
|
LoadDashboardData();
|
});
|
onBeforeUnmount(() => {
|
|
});
|
|
const Init = () => {
|
if (store.$state.user && store.$state.user.employee) {
|
state.user = store.$state.user.employee;
|
} else {
|
state.user = store.$state.user;
|
}
|
};
|
const LoadData = () => {
|
for (let i = 0; i < state.routes.length; i++) {
|
let item = state.routes[i];
|
|
let group = {
|
id: i,
|
icon: item.meta.icon,
|
name: item.name,
|
type: "menu",
|
text: proxy.$t('menu.' + item.meta.languagekey),
|
languagekey: item.meta.languagekey,
|
link: item.path,
|
}
|
|
let children = [];
|
for (let j = 0; j < item.children.length; j++) {
|
let child = item.children[j];
|
children.push({
|
id: i + j,
|
icon: child.meta.icon,
|
name: child.name,
|
type: "menu",
|
text: proxy.$t('menu.' + child.meta.languagekey),
|
languagekey: child.meta.languagekey,
|
link: child.path,
|
});
|
}
|
|
state.operations.push({group: group, children: children, sequence: children.length});
|
|
state.operations = state.operations.sort(function (a, b) {
|
return b.sequence - a.sequence
|
});
|
}
|
};
|
const LoadDashboardData = () => {
|
GetDashboardData({}).then(resp => {
|
if (resp.data) {
|
state.statisticsdata = resp.data.data;
|
}
|
}).catch(err => {
|
console.error(err);
|
});
|
};
|
const LoadEmployeePositionWithOrganizationsByEmployeeId = () => {
|
let emp = store.$state.user.employee;
|
if (emp) {
|
let employeeid = emp.id;
|
GetEmployeePositionWithOrganizationsByEmployeeId(employeeid).then(resp => {
|
if (resp.data) {
|
state.positiontitle = resp.data.data[0].title;
|
state.organizationStructure = resp.data.data[0].organizationStructure
|
}
|
}).catch(err => {
|
console.error(err);
|
});
|
}
|
};
|
|
return {
|
...toRefs(state),
|
icon,
|
formatterDate,
|
formatterDatetime,
|
formatterNumber,
|
}
|
},
|
}
|
</script>
|
|
<style scoped lang="scss">
|
$color: var(--el-color-primary);
|
|
.el-statistic {
|
--el-statistic-content-font-size: 28px;
|
}
|
|
.statistic-card {
|
height: 100%;
|
padding: 20px;
|
border-radius: 4px;
|
background-color: var(--el-bg-color-overlay);
|
}
|
|
.statistic-footer {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
flex-wrap: wrap;
|
font-size: 12px;
|
color: var(--el-text-color-regular);
|
margin-top: 16px;
|
}
|
|
.statistic-footer .footer-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.statistic-footer .footer-item span:last-child {
|
display: inline-flex;
|
align-items: center;
|
margin-left: 4px;
|
}
|
|
.green {
|
color: var(--el-color-success);
|
}
|
|
.red {
|
color: var(--el-color-error);
|
}
|
</style>
|