Browse Source

公司排班

qin_24
herenshan112 3 months ago
parent
commit
6a5823e150
  1. 65
      src/api/hr/paiban/index.ts
  2. 10
      src/layout/components/Sidebar/SidebarItem.vue
  3. 10
      src/permission.ts
  4. 16
      src/store/modules/permission.ts
  5. 273
      src/views/hr/company/companyduty.vue
  6. 232
      src/views/hr/company/savePage.vue
  7. 117
      src/views/hr/displayboards/dimissionrate.vue

65
src/api/hr/paiban/index.ts

@ -0,0 +1,65 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
/**
*
*/
export function companyDutyInit(data?: any){
return request({
url: '/systemapi/app/companyDutyInit',
method: 'post',
data: data
});
}
/**
*
*/
export function getYearMonthWorkMan(data?: any){
return request({
url: '/systemapi/app/getYearMonthWorkMan',
method: 'post',
data: data
});
}
/**
*
*/
export function geiOrgAllPeople(data?: any){
return request({
url: '/systemapi/app/geiOrgAllPeople',
method: 'post',
data: data
});
}
/**
*
*/
export function saveEditDutyInfo(data?: any){
return request({
url: '/systemapi/app/saveEditDutyInfo',
method: 'post',
data: data
});
}
/**
*
*/
export function delOneDayDuty(data?: any){
return request({
url: '/systemapi/app/delOneDayDuty',
method: 'post',
data: data
});
}
/**
*
*/
export function getDutyCont(data?: any){
return request({
url: '/systemapi/app/getDutyCont',
method: 'post',
data: data
});
}

10
src/layout/components/Sidebar/SidebarItem.vue

@ -79,11 +79,11 @@ function resolvePath(routePath: string) {
// fullPath = fullPath + "&table_id=" + props.item.tableId; // fullPath = fullPath + "&table_id=" + props.item.tableId;
// } // }
// } // }
console.log("路由路径<------------------"); // console.log("<------------------");
console.log("routePath:", routePath); // console.log("routePath:", routePath);
console.log("fullPath:", fullPath); // console.log("fullPath:", fullPath);
console.log("item:", props.item); // console.log("item:", props.item);
console.log("路由路径------------------>"); // console.log("------------------>");
return fullPath; return fullPath;
} }
</script> </script>

10
src/permission.ts

@ -16,9 +16,9 @@ const whiteList = ["/login","/login/silentlogin","/aiurl"];
router.beforeEach(async (to:any, from:any, next:any) => { router.beforeEach(async (to:any, from:any, next:any) => {
NProgress.start(); NProgress.start();
console.log("白名单路由----》"); // console.log("白名单路由----》");
const hasToken = localStorage.getItem(appTokenKey); const hasToken = localStorage.getItem(appTokenKey);
console.log("白名单路由----》",hasToken,"--->",to.path); // console.log("白名单路由----》",hasToken,"--->",to.path);
if (hasToken) { if (hasToken) {
// console.log("白名单路由--22--》",hasToken,to.path); // console.log("白名单路由--22--》",hasToken,to.path);
if (to.path === "/login") { if (to.path === "/login") {
@ -43,11 +43,11 @@ router.beforeEach(async (to:any, from:any, next:any) => {
try { try {
// const { roles } = await userStore.getInfo(); // const { roles } = await userStore.getInfo();
const { perms } = await userStore.getInfo(); const { perms } = await userStore.getInfo();
console.log("路由权限---》",perms); // console.log("路由权限---》",perms);
const accessRoutes = await permissionStore.generateRoutes(perms); const accessRoutes = await permissionStore.generateRoutes(perms);
console.log("路由权限--perms--》",accessRoutes); // console.log("路由权限--perms--》",accessRoutes);
accessRoutes.forEach((route:any) => { accessRoutes.forEach((route:any) => {
console.log("路由权限--addRoutecessRoutes",route); // console.log("路由权限--addRoutecessRoutes",route);
router.addRoute(route); router.addRoute(route);
}); });
next({ ...to, replace: true }); next({ ...to, replace: true });

16
src/store/modules/permission.ts

@ -61,10 +61,10 @@ const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
tmpRoute.component = Layout; tmpRoute.component = Layout;
// console.log(); // console.log();
} else { } else {
console.log("判断用户-251->",tmpRoute.component); // console.log("判断用户-251->",tmpRoute.component);
const component = modules[`../../views/${tmpRoute.component}.vue`]; const component = modules[`../../views/${tmpRoute.component}.vue`];
// const component = modules[`${tmpRoute.component}.vue`]; // const component = modules[`${tmpRoute.component}.vue`];
console.log("判断用户-1111111111111111->",component); // console.log("判断用户-1111111111111111->",component);
if (component) { if (component) {
tmpRoute.component = component; tmpRoute.component = component;
} else { } else {
@ -104,12 +104,12 @@ export const usePermissionStore = defineStore("permission", () => {
listRoutes() listRoutes()
.then(({ data: asyncRoutes }) => { .then(({ data: asyncRoutes }) => {
// 根据角色获取有访问权限的路由 // 根据角色获取有访问权限的路由
console.log("获取到的路由---->",asyncRoutes); // console.log("获取到的路由---->",asyncRoutes);
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles); const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
console.log("获取到的路由--1-->",accessedRoutes); // console.log("获取到的路由--1-->",accessedRoutes);
console.log("获取到的路由--2-->",roles); // console.log("获取到的路由--2-->",roles);
setRoutes(accessedRoutes); setRoutes(accessedRoutes);
resolve(accessedRoutes); resolve(accessedRoutes);
@ -119,9 +119,9 @@ export const usePermissionStore = defineStore("permission", () => {
}); });
}); });
} }
console.log("获取到的路由--3->",routes) // console.log("获取到的路由--3->",routes)
console.log("获取到的路由--4->",setRoutes) // console.log("获取到的路由--4->",setRoutes)
console.log("获取到的路由--5->",generateRoutes) // console.log("获取到的路由--5->",generateRoutes)
return { routes, setRoutes, generateRoutes }; return { routes, setRoutes, generateRoutes };
}); });

273
src/views/hr/company/companyduty.vue

@ -3,16 +3,142 @@
@ 时间: 2025-08-11 14:11:11 @ 时间: 2025-08-11 14:11:11
@ 备注: 公司值班 @ 备注: 公司值班
--> -->
<script lang="ts" setup></script> <script lang="ts" setup>
import {
companyDutyInit,
getYearMonthWorkMan,
delOneDayDuty,
} from "@/api/hr/paiban/index";
import SavePage from "@/views/hr/company/savePage.vue";
const pickMonth = ref("");
const initConter = ref("");
const isSelect = ref(false);
const saveOpen = ref(false);
const workManLsit = ref([]);
const saveInfo = reactive({
id: 0,
orgid: 0,
orgname: "",
allDay: [],
baiTian: [],
days: 1,
holiday: 2,
month: 1,
night: [],
years: 2025,
isCompany: 0,
});
const initInfo = () => {
companyDutyInit().then((res: any) => {
console.log("初始化数据:", res.data);
initConter.value = res.data;
getOrgList(res.data.currentOrg, res.data.year, res.data.month);
});
};
//
const getOrgList = (orgid: any, years: any, months: any) => {
getYearMonthWorkMan({
orgId: orgid,
years: years,
month: months,
}).then((resData) => {
console.log("排班数据数据:", resData);
workManLsit.value = resData.data.list;
initConter.value.titlePc = resData.data.title;
});
};
onMounted(() => {
initInfo();
});
//
const delTag = () => {
console.log("删除一设定人员");
};
//
const pickOrg = (val: any) => {
getOrgList(val, initConter.value.year, initConter.value.month);
};
//
const saveData = (ord: any, val: any) => {
console.log("编辑数据", ord, val);
saveInfo.id = val.id;
saveInfo.orgid = ord.id ? ord.id : "";
saveInfo.orgname = ord.name ? ord.name : "";
saveInfo.allDay = val.allDay ? val.allDay : [];
saveInfo.baiTian = val.baiTian ? val.baiTian : [];
saveInfo.days = val.days ? val.days : 1;
saveInfo.holiday = val.holiday ? val.holiday : 2;
saveInfo.month = val.month ? val.month : 1;
saveInfo.night = val.night ? val.night : [];
saveInfo.years = val.years ? val.years : 2025;
saveInfo.isCompany = ord.isCompany ? ord.isCompany : 0;
saveOpen.value = true;
console.log("编辑数据", saveInfo);
};
//
const delOrgDuty = (ord: any, val: any) => {
console.log("清空值班人员", initConter.value, val);
delOneDayDuty({ id: val.id }).then(() => {
getOrgList(initConter.value.currentOrg, val.years, val.month);
});
};
//
const pickRefresh = (ordId: any, years: any, months: any) => {
console.log("数据刷新", ordId, years, months);
getOrgList(ordId, years, months);
};
//
watch(
() => pickMonth.value,
(val: any) => {
let newDay = new Date(val);
let yearVal = val.getFullYear();
let monthVal = val.getMonth() + 1;
getOrgList(initConter.value.currentOrg, yearVal, monthVal);
},
{
deep: true,
}
);
</script>
<template> <template>
<div class="comBox"> <div class="comBox">
<el-card shadow="always"> <el-card shadow="always">
<template #header> <template #header>
<div class="card_header"> <div class="card_header">
<div>山东荣信集团</div>
<div>2025年7月公司值班表</div>
<div> <div>
<el-button type="primary">添加值班信息</el-button> <el-select
v-if="initConter.orgLevel == 5"
v-model="initConter.currentOrg"
placeholder="请选择行政组织"
style="width: 300px"
@change="pickOrg($event)"
>
<el-option
v-for="item in initConter.orgList"
:key="item.id"
:label="item.name + '(' + item.id + ')'"
:value="item.id"
/>
</el-select>
<div v-else>
<div v-for="item in initConter.orgList">
<span v-if="item.id == initConter.currentOrg"
>{{ item.name }}({{ item.id }})</span
>
</div>
</div>
</div>
<div>{{ initConter.titlePc }}</div>
<div>
<!-- <el-button type="primary">添加值班信息</el-button> -->
<el-date-picker v-model="pickMonth" type="month" placeholder="请选择月份" />
</div> </div>
</div> </div>
</template> </template>
@ -20,75 +146,74 @@
<table> <table>
<tr> <tr>
<td></td> <td></td>
<td align="center">1</td> <td
<td align="center">2</td> align="center"
<td align="center">3</td> v-for="(item, index) in initConter.monthAllDay"
<td align="center">4</td> :key="index"
<td align="center">5</td> style="width: 300px"
<td align="center">6</td> >
<td align="center">7</td> {{ item }}
<td align="center">8</td> </td>
<td align="center">9</td>
<td align="center">10</td>
<td align="center">11</td>
<td align="center">12</td>
<td align="center">13</td>
<td align="center">14</td>
<td align="center">15</td>
<td align="center">16</td>
<td align="center">17</td>
<td align="center">18</td>
<td align="center">19</td>
<td align="center">20</td>
<td align="center">21</td>
<td align="center">22</td>
<td align="center">23</td>
<td align="center">24</td>
<td align="center">25</td>
<td align="center">26</td>
<td align="center">27</td>
<td align="center">28</td>
<td align="center">29</td>
<td align="center">30</td>
<td align="center">31</td>
</tr> </tr>
<tr> <tr v-for="(item, index) in workManLsit" :key="index">
<td>公司领导</td> <td>{{ item.orgInfo.name }}</td>
<td>公司领导公司领导公司领导</td> <td v-for="(us, usi) in item.dutyList" :key="usi">
<td>2</td> <div v-if="us.holiday == 1">
<td>3</td> <el-divider v-if="us.baiTian">白天</el-divider>
<td>4</td> <el-space wrap>
<td>5</td> <el-tag v-for="(mItem, mi) in us.baiTian" closable @close="delTag()">{{
<td>6</td> mItem.name
<td>7</td> }}</el-tag>
<td>8</td> </el-space>
<td>9</td> <el-divider v-if="us.night">夜间</el-divider>
<td>10</td> <el-space wrap>
<td>11</td> <el-tag v-for="(mItem, mi) in us.night" closable @close="delTag()">{{
<td>12</td> mItem.name
<td>13</td> }}</el-tag>
<td>14</td> </el-space>
<td>15</td> <el-divider v-if="us.allDay">全天</el-divider>
<td>16</td> <el-space wrap>
<td>17</td> <el-tag v-for="(mItem, mi) in us.allDay" closable @close="delTag()">{{
<td>18</td> mItem.name
<td>19</td> }}</el-tag>
<td>20</td> </el-space>
<td>21</td> </div>
<td>22</td> <div v-else>
<td>23</td> <el-space wrap>
<td>24</td> <el-tag v-for="(mItem, mi) in us.allDay" closable @close="delTag()">{{
<td>25</td> mItem.name
<td>26</td> }}</el-tag>
<td>27</td> </el-space>
<td>28</td> </div>
<td>29</td>
<td>30</td> <div class="butBox">
<td>31</td> <el-button
type="primary"
text
size="small"
@click="saveData(item.orgInfo, us)"
>编辑</el-button
>
<el-button
:disabled="us.id == 0"
type="danger"
text
size="small"
@click="delOrgDuty(item.orgInfo, us)"
>清空</el-button
>
</div>
</td>
</tr> </tr>
</table> </table>
</div> </div>
</el-card> </el-card>
<SavePage
v-model:is-open="saveOpen"
:duty-cont="saveInfo"
:cumpany-id="initConter.currentOrg"
@pickRefresh="pickRefresh"
/>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -104,7 +229,7 @@
.card_header { .card_header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
image-rendering: cs; image-rendering: css;
align-items: center; align-items: center;
} }
.tableBox { .tableBox {
@ -115,7 +240,7 @@
th, th,
td { td {
border: 1px solid #ddd; border: 1px solid #ddd;
padding: 10px; padding: 5px 0 0 0px;
} }
th { th {
background-color: #2196f3; background-color: #2196f3;
@ -123,9 +248,15 @@
font-weight: bold; font-weight: bold;
} }
td { td {
min-width: 120px; min-width: 160px;
color: #555; color: #555;
} }
} }
.butBox {
display: flex;
justify-content: space-between;
border-top: 1px solid #ddd;
margin-top: 5px;
}
} }
</style> </style>

232
src/views/hr/company/savePage.vue

@ -0,0 +1,232 @@
<!--
@ 作者: 秦东
@ 时间: 2025-08-12 15:48:52
@ 备注: 编辑排班记录
-->
<script lang="ts" setup>
import { geiOrgAllPeople, saveEditDutyInfo, getDutyCont } from "@/api/hr/paiban/index";
import { get_org } from "@/api/opk/zxy/news/api";
const props = defineProps({
isOpen: {
type: Boolean,
default: false,
},
cumpanyId: {
type: Number,
default: "",
},
dutyCont: {
type: Object,
default() {
return {};
},
},
});
const loading = ref(false);
const emits = defineEmits(["update:isOpen", "pickRefresh"]);
const isShow = computed({
get() {
// console.log("",props.isOpen);
return props.isOpen;
},
set(val: boolean) {
// console.log("",props.isOpen);
emits("update:isOpen", val);
},
});
const currtOrg = ref(props.cumpanyId);
const saveInfo = ref(props.dutyCont);
const orgPeopleList = ref([]);
//
const closeSavePage = () => {
emits("update:isOpen", false);
};
//
watch(
() => props.isOpen,
(val: boolean) => {
if (val) {
getOrgPeople();
}
},
{
deep: true,
}
);
//
const getOrgPeople = () => {
loading.value = true;
getDutyCont({ id: saveInfo.value.id.toString() }).then((res) => {
console.log("获取单一排版信息", res);
saveInfo.value.allDay = res.data.allDayAry;
saveInfo.value.baiTian = res.data.baiTianAry;
saveInfo.value.night = res.data.nightAry;
});
if (saveInfo.value.isCompany == 1) {
get_org({
id: currtOrg.value.toString(),
all: 1,
})
.then((res: any) => {
console.log("获取行政组织人员信息get_org", res);
orgPeopleList.value = res.data;
loading.value = false;
})
.finally(() => {
loading.value = false;
});
} else {
geiOrgAllPeople({
orgId: saveInfo.value.orgid * 1,
companyId: currtOrg.value * 1,
isAll: saveInfo.value.isCompany * 1,
})
.then((res: any) => {
console.log("获取行政组织人员信息geiOrgAllPeople", res);
orgPeopleList.value = res.data;
loading.value = false;
})
.finally(() => {
loading.value = false;
});
}
};
//
const saveCenter = () => {
console.log("提交数据", saveInfo.value);
saveInfo.value.holiday = saveInfo.value.holiday.toString();
saveEditDutyInfo(saveInfo.value).then((res: any) => {
closeSavePage();
emits(
"pickRefresh",
props.cumpanyId,
saveInfo.value.years,
saveInfo.value.month,
saveInfo.value.orgid
);
});
};
const orgTreeProps = {
children: "child",
label: "name",
}; //
</script>
<template>
<el-dialog
v-model="isShow"
:title="
saveInfo.years + '年' + saveInfo.month + '月' + saveInfo.days + '日编辑值班信息'
"
width="500"
:before-close="closeSavePage"
>
<el-form ref="ruleFormRef" :model="saveInfo">
<el-form-item label="行政组织" prop="orgname">
<el-input v-model="saveInfo.orgname" disabled />
</el-form-item>
<el-form-item label="节假日" prop="holiday">
<el-switch
v-model="saveInfo.holiday"
active-value="1"
inline-prompt
inactive-value="2"
active-text="是"
inactive-text="否"
/>
</el-form-item>
<el-form-item v-if="saveInfo.holiday == 1" label="白天" prop="baiTian">
<el-tree-select
v-if="saveInfo.isCompany == 1"
v-model="saveInfo.baiTian"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="id"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
<el-tree-select
v-else
v-model="saveInfo.baiTian"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="userKey"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
</el-form-item>
<el-form-item v-if="saveInfo.holiday == 1" label="夜晚" prop="night">
<el-tree-select
v-if="saveInfo.isCompany == 1"
v-model="saveInfo.night"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="id"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
<el-tree-select
v-else
v-model="saveInfo.night"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="userKey"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
</el-form-item>
<el-form-item v-else label="值班" prop="allDay">
<el-tree-select
v-if="saveInfo.isCompany == 1"
v-model="saveInfo.allDay"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="id"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
<el-tree-select
v-else
v-model="saveInfo.allDay"
:data="orgPeopleList"
multiple
clearable
filterable
:props="orgTreeProps"
node-key="userKey"
:render-after-expand="false"
style="width: 300px"
v-loading="loading"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeSavePage">取消</el-button>
<el-button type="primary" @click="saveCenter"> 确定 </el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped></style>

117
src/views/hr/displayboards/dimissionrate.vue

@ -3,91 +3,103 @@
@ 时间: 2023-06-30 16:03:33 @ 时间: 2023-06-30 16:03:33
@ 备注: 行政组织离职率 @ 备注: 行政组织离职率
--> -->
<script lang='ts' setup> <script lang="ts" setup>
import * as echarts from 'echarts'; import * as echarts from "echarts";
import { zexianStrcut } from '@/api/displayboardapi/types' import { zexianStrcut } from "@/api/displayboardapi/types";
import { getDimissionRate } from '@/api/displayboardapi/indexapi' import { getDimissionRate } from "@/api/displayboardapi/indexapi";
const legendList = new Array const legendList = new Array();
const seriesData = new Array const seriesData = new Array();
const props = defineProps({ const props = defineProps({
id: { id: {
type: String, type: String,
default: 'barChart' default: "barChart",
}, },
className: { className: {
type: String, type: String,
default: '' default: "",
}, },
width: { width: {
type: String, type: String,
default: '100%', default: "100%",
required: true required: true,
}, },
height: { height: {
type: String, type: String,
default: '650px', default: "650px",
required: true required: true,
}, },
title: { title: {
type: String, type: String,
default: '' default: "",
}, },
}); });
const option = { const option = {
title: { title: {
show: false, show: false,
text: '离职率(%)', text: "离职率(%)",
}, },
tooltip: { tooltip: {
trigger: 'axis' trigger: "axis",
}, },
legend: { legend: {
right: '10', right: "10",
data: legendList, data: legendList,
orient: 'vertical', orient: "vertical",
top: "50", top: "50",
type: 'scroll', type: "scroll",
icon: 'circle', icon: "circle",
itemWidth: 10, itemWidth: 10,
itemHeight: 10 itemHeight: 10,
}, },
grid: { grid: {
left: '20px', left: "20px",
right: '290px', right: "290px",
bottom: '1%', bottom: "1%",
containLabel: true containLabel: true,
}, },
toolbox: { toolbox: {
right: '20px', right: "20px",
top: '0', top: "0",
feature: { feature: {
saveAsImage: { saveAsImage: {
title: '导出图片', title: "导出图片",
iconStyle: { iconStyle: {
borderWidth: 1, borderWidth: 1,
borderType: 'solid' borderType: "solid",
} },
} },
} },
}, },
xAxis: { xAxis: {
type: 'category', type: "category",
boundaryGap: false, boundaryGap: false,
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'] data: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
}, },
yAxis: { yAxis: {
type: 'value', type: "value",
splitLine: { splitLine: {
show: true, show: true,
lineStyle: { lineStyle: {
type: 'dotted' type: "dotted",
} },
} },
}, },
series: seriesData series: seriesData,
}; };
onMounted(() => { onMounted(() => {
@ -95,40 +107,39 @@ onMounted(() => {
.then((data: any) => { .then((data: any) => {
// console.log(data,data.data.list); // console.log(data,data.data.list);
if (data.code == 0) { if (data.code == 0) {
data.data.list.forEach((item: { orgname: any; odds: any; }) => { data.data.list.forEach((item: { orgname: any; odds: any }) => {
legendList.push(item.orgname) legendList.push(item.orgname);
seriesData.push({ seriesData.push({
name: item.orgname, name: item.orgname,
type: 'line', type: "line",
smooth: true, smooth: true,
data: item.odds, data: item.odds,
label: { label: {
show: true show: true,
} },
}) });
}); });
} }
}) })
.finally(() => { .finally(() => {
// console.log("legendList--->",legendList) // console.log("legendList--->",legendList)
// //
const chart = echarts.init( const chart = echarts.init(document.getElementById(props.id) as HTMLDivElement);
document.getElementById(props.id) as HTMLDivElement
);
chart.setOption(option); chart.setOption(option);
// //
window.addEventListener('resize', () => { window.addEventListener("resize", () => {
chart.resize(); chart.resize();
}); });
}) });
}); });
</script> </script>
<template> <template>
<el-card shadow="never" class="w-full"> <el-card shadow="never" class="w-full">
<div class="glm-title" v-if="!!title"><span class="bt">{{ title }}</span></div> <div class="glm-title" v-if="!!title">
<span class="bt">{{ title }}</span>
</div>
<div :id="id" :class="className" :style="{ height, width }" /> <div :id="id" :class="className" :style="{ height, width }" />
</el-card> </el-card>
</template> </template>
<style lang='scss' scoped></style> <style lang="scss" scoped></style>

Loading…
Cancel
Save