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;
// }
// }
console.log("路由路径<------------------");
console.log("routePath:", routePath);
console.log("fullPath:", fullPath);
console.log("item:", props.item);
console.log("路由路径------------------>");
// console.log("<------------------");
// console.log("routePath:", routePath);
// console.log("fullPath:", fullPath);
// console.log("item:", props.item);
// console.log("------------------>");
return fullPath;
}
</script>

10
src/permission.ts

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

16
src/store/modules/permission.ts

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

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

@ -3,16 +3,142 @@
@ 时间: 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>
<div class="comBox">
<el-card shadow="always">
<template #header>
<div class="card_header">
<div>山东荣信集团</div>
<div>2025年7月公司值班表</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>
</template>
@ -20,75 +146,74 @@
<table>
<tr>
<td></td>
<td align="center">1</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">4</td>
<td align="center">5</td>
<td align="center">6</td>
<td align="center">7</td>
<td align="center">8</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>
<td
align="center"
v-for="(item, index) in initConter.monthAllDay"
:key="index"
style="width: 300px"
>
{{ item }}
</td>
</tr>
<tr>
<td>公司领导</td>
<td>公司领导公司领导公司领导</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
<td>29</td>
<td>30</td>
<td>31</td>
<tr v-for="(item, index) in workManLsit" :key="index">
<td>{{ item.orgInfo.name }}</td>
<td v-for="(us, usi) in item.dutyList" :key="usi">
<div v-if="us.holiday == 1">
<el-divider v-if="us.baiTian">白天</el-divider>
<el-space wrap>
<el-tag v-for="(mItem, mi) in us.baiTian" closable @close="delTag()">{{
mItem.name
}}</el-tag>
</el-space>
<el-divider v-if="us.night">夜间</el-divider>
<el-space wrap>
<el-tag v-for="(mItem, mi) in us.night" closable @close="delTag()">{{
mItem.name
}}</el-tag>
</el-space>
<el-divider v-if="us.allDay">全天</el-divider>
<el-space wrap>
<el-tag v-for="(mItem, mi) in us.allDay" closable @close="delTag()">{{
mItem.name
}}</el-tag>
</el-space>
</div>
<div v-else>
<el-space wrap>
<el-tag v-for="(mItem, mi) in us.allDay" closable @close="delTag()">{{
mItem.name
}}</el-tag>
</el-space>
</div>
<div class="butBox">
<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>
</table>
</div>
</el-card>
<SavePage
v-model:is-open="saveOpen"
:duty-cont="saveInfo"
:cumpany-id="initConter.currentOrg"
@pickRefresh="pickRefresh"
/>
</div>
</template>
<style lang="scss" scoped>
@ -104,7 +229,7 @@
.card_header {
display: flex;
justify-content: space-between;
image-rendering: cs;
image-rendering: css;
align-items: center;
}
.tableBox {
@ -115,7 +240,7 @@
th,
td {
border: 1px solid #ddd;
padding: 10px;
padding: 5px 0 0 0px;
}
th {
background-color: #2196f3;
@ -123,9 +248,15 @@
font-weight: bold;
}
td {
min-width: 120px;
min-width: 160px;
color: #555;
}
}
.butBox {
display: flex;
justify-content: space-between;
border-top: 1px solid #ddd;
margin-top: 5px;
}
}
</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
@ 备注: 行政组织离职率
-->
<script lang='ts' setup>
import * as echarts from 'echarts';
import { zexianStrcut } from '@/api/displayboardapi/types'
import { getDimissionRate } from '@/api/displayboardapi/indexapi'
<script lang="ts" setup>
import * as echarts from "echarts";
import { zexianStrcut } from "@/api/displayboardapi/types";
import { getDimissionRate } from "@/api/displayboardapi/indexapi";
const legendList = new Array
const seriesData = new Array
const legendList = new Array();
const seriesData = new Array();
const props = defineProps({
id: {
type: String,
default: 'barChart'
default: "barChart",
},
className: {
type: String,
default: ''
default: "",
},
width: {
type: String,
default: '100%',
required: true
default: "100%",
required: true,
},
height: {
type: String,
default: '650px',
required: true
default: "650px",
required: true,
},
title: {
type: String,
default: ''
default: "",
},
});
const option = {
title: {
show: false,
text: '离职率(%)',
text: "离职率(%)",
},
tooltip: {
trigger: 'axis'
trigger: "axis",
},
legend: {
right: '10',
right: "10",
data: legendList,
orient: 'vertical',
orient: "vertical",
top: "50",
type: 'scroll',
icon: 'circle',
type: "scroll",
icon: "circle",
itemWidth: 10,
itemHeight: 10
itemHeight: 10,
},
grid: {
left: '20px',
right: '290px',
bottom: '1%',
containLabel: true
left: "20px",
right: "290px",
bottom: "1%",
containLabel: true,
},
toolbox: {
right: '20px',
top: '0',
right: "20px",
top: "0",
feature: {
saveAsImage: {
title: '导出图片',
title: "导出图片",
iconStyle: {
borderWidth: 1,
borderType: 'solid'
}
}
}
borderType: "solid",
},
},
},
},
xAxis: {
type: 'category',
type: "category",
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: {
type: 'value',
type: "value",
splitLine: {
show: true,
lineStyle: {
type: 'dotted'
}
}
type: "dotted",
},
},
},
series: seriesData
series: seriesData,
};
onMounted(() => {
@ -95,40 +107,39 @@ onMounted(() => {
.then((data: any) => {
// console.log(data,data.data.list);
if (data.code == 0) {
data.data.list.forEach((item: { orgname: any; odds: any; }) => {
legendList.push(item.orgname)
data.data.list.forEach((item: { orgname: any; odds: any }) => {
legendList.push(item.orgname);
seriesData.push({
name: item.orgname,
type: 'line',
type: "line",
smooth: true,
data: item.odds,
label: {
show: true
}
})
show: true,
},
});
});
}
})
.finally(() => {
// console.log("legendList--->",legendList)
//
const chart = echarts.init(
document.getElementById(props.id) as HTMLDivElement
);
const chart = echarts.init(document.getElementById(props.id) as HTMLDivElement);
chart.setOption(option);
//
window.addEventListener('resize', () => {
window.addEventListener("resize", () => {
chart.resize();
});
})
});
});
</script>
<template>
<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 }" />
</el-card>
</template>
<style lang='scss' scoped></style>
<style lang="scss" scoped></style>

Loading…
Cancel
Save