冰雪专题PC端 人员管理调整 跟养护站管理合并

This commit is contained in:
huangchenhao 2025-11-11 11:22:47 +08:00
parent 3d8312a62d
commit 680149a6c0
6 changed files with 602 additions and 12 deletions

View File

@ -27,11 +27,6 @@ const routes = [
name: 'yhzwz',
component: () => import('../views/MaterialManagement/index.vue')
},
{
path: '/yhzry/:data?',
name: 'yhzry',
component: () => import('../views/PersonManagement/index.vue')
},
{
path: '/yhzevent',
name: 'yhzevent',

View File

@ -8,7 +8,7 @@ const service = axios.create({
// 请求拦截器
service.interceptors.request.use(config => {
// 暂时先写死token 实际项目中再调整token的获取位置
const token = 'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjE5ODY2ODgzMjY1MjAwNTc4NTcsImFjY291bnQiOiJieHp0IiwidXVpZCI6ImMyY2E5OGU4LTIyYzItNGZmZi1hZWE0LTBiNWNiZmE4YjNlMSIsInJlbWVtYmVyTWUiOnRydWUsImV4cGlyYXRpb25EYXRlIjoxNzYyNzgzOTkwMzUxLCJvdGhlcnMiOm51bGwsInN1YiI6IjE5ODY2ODgzMjY1MjAwNTc4NTciLCJpYXQiOjE3NjI3NTUxOTAsImV4cCI6MTc2Mjc4Mzk5MH0.zqQcAE08fr2jQd7HcQ9Y3i-gWb2TrCWuUxSzl1kXOoJe2rp1Yly0ffrY6_1jY0ybHJwihONChqiSc-8jRTKYKw'
const token = 'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjE5ODY2ODgzMjY1MjAwNTc4NTcsImFjY291bnQiOiJieHp0IiwidXVpZCI6Ijc5Zjk5NWE0LTAyNGEtNDA3My04YjVhLTIxNGI4MDBmNmQ1YyIsInJlbWVtYmVyTWUiOnRydWUsImV4cGlyYXRpb25EYXRlIjoxNzYyODUxOTg2OTI1LCJvdGhlcnMiOm51bGwsInN1YiI6IjE5ODY2ODgzMjY1MjAwNTc4NTciLCJpYXQiOjE3NjI4MjMxODYsImV4cCI6MTc2Mjg1MTk4Nn0.nZziqdUarLN1uRfs1pBRrBt-HxqBOGJy67HwaAbIiY7uSv-q9kzfiec7Djd1jkV_OnzhW3jN8h-pl8ILCFl0HA'
// const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `${token}`;

View File

@ -0,0 +1,97 @@
<template>
<div class="detail-container">
<el-form
ref="formRef"
label-position="right"
label-width="150px"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px"
>
<el-form-item label="人员:">
<el-select
v-model="ryxx"
filterable
remote
reserve-keyword
placeholder="输入人员名称 / 联系方式 查询"
:remote-method="remoteMethod"
:loading="loading"
@change="handleSelect"
value-key="userId"
>
<el-option
v-for="item in selectOptions"
:key="item.userId"
:label="item.realName"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="岗位:">
<el-input v-model="form.gw" />
</el-form-item>
<el-form-item label="养护站:">
<el-input disabled v-model="yhzdata.mc" />
</el-form-item>
<el-form-item label="人员角色:">
<el-select v-model="form.ryjs" placeholder="请选择人员角色">
<el-option label="负责人" value="1"></el-option>
<el-option label="普通工作人员" value="2"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from "vue";
const formRef = ref(null);
defineExpose({ formRef });
const props = defineProps({
form: {
type: Object,
default: () => ({}),
},
getUserList: {
type: Function,
default: () => () => {},
},
yhzdata: {
type: Object,
default: () => ({}),
}
});
const ryxx = ref("");
const loading = ref(false);
const selectOptions = ref([]);
//
const remoteMethod = async (query) => {
loading.value = true;
const res = await props.getUserList(query);
if (res) {
selectOptions.value = res;
}
loading.value = false;
};
//
const handleSelect = (value) => {
props.form.xm = value.realName;
props.form.sjhm = value.phone;
props.form.userId = value.userId;
};
onMounted(async () => {
const res = await props.getUserList();
if (res) {
selectOptions.value = res;
}
props.form.yhzid = props.yhzdata.id
});
</script>
<style>
</style>

View File

@ -0,0 +1,37 @@
<template>
<div class="detail-container">
<el-form
label-position="right"
label-width="150px"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px"
>
<el-form-item label="人员名称:">
<el-input disabled v-model="detailData.xm" />
</el-form-item>
<el-form-item label="岗位:">
<el-input disabled v-model="detailData.gw" />
</el-form-item>
<el-form-item label="手机号码:">
<el-input disabled v-model="detailData.sjhm" />
</el-form-item>
<el-form-item label="人员角色:">
<el-input disabled :value="detailData.ryjs === 1 ? '管理员' : '普通用户'" />
</el-form-item>
<el-form-item label="创建时间:">
<el-input disabled v-model="detailData.cjsj" />
</el-form-item>
</el-form>
</div>
</template>
<script setup>
const props = defineProps({
detailData: {
type: Object,
default: () => ({}),
},
});
</script>
<style>
</style>

View File

@ -0,0 +1,45 @@
<template>
<div class="detail-container">
<el-form
ref="formRef"
label-position="right"
label-width="150px"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px"
>
<el-form-item label="人员名称:">
<el-input disabled v-model="form.xm" />
</el-form-item>
<el-form-item label="岗位:">
<el-input v-model="form.gw" />
</el-form-item>
<el-form-item label="手机号码:">
<el-input disabled v-model="form.sjhm" />
</el-form-item>
<el-form-item label="人员角色:" prop="ryjs">
<el-select v-model="form.ryjs" placeholder="请选择角色">
<el-option label="负责人" :value="1" />
<el-option label="普通工作人员" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="创建时间:">
<el-input disabled v-model="form.cjsj" />
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref } from "vue";
const formRef = ref(null);
defineExpose({ formRef });
const props = defineProps({
form: {
type: Object,
default: () => ({}),
},
});
</script>
<style>
</style>

View File

@ -1,9 +1,54 @@
<template>
<div>1145141919810</div>
<div class="root">
<div class="event-box">
<div class="inline-flex">
<label>人员姓名:</label>
<el-input v-model="filterData.xm"></el-input>
</div>
<div class="inline-flex">
<el-button type="primary" size="large" @click="openAddModel"
>新增人员</el-button
>
<el-button type="info" size="large" @click="handelExport"
>导出</el-button
>
</div>
</div>
<div class="form-box">
<div class="form-content">
<DynamicTable
:dataSource="yhzryList"
:columns="columns"
:autoHeight="true"
:pagination="pagination"
></DynamicTable>
</div>
</div>
<div class="model-box">
<MyDialog
v-model="modelVisible"
:title="model?.title"
:dynamicComponent="model?.content"
:component-props="model?.props"
:onConfirm="model?.onConfirm"
:onCancel="model?.onCancel"
ref="dialogRef"
:width="model?.width"
>
</MyDialog>
</div>
</div>
</template>
<script lang="ts" setup>
import { h, ref, onMounted, reactive, watch, toRaw } from "vue";
import DynamicTable from "../../component/DynamicTable";
import { request } from "@/utils/request";
import MyDialog from "../../component/MyDialog";
import AddDialog from "./component/addDialog.vue";
import EditDialog from "./component/editDialog.vue";
import DetailDialog from "./component/detailDialog.vue";
const props = defineProps({
yhzData: {
@ -31,19 +76,390 @@ const pagination = reactive({
},
}); //
//
const yhzryList = ref([]);
//
const getDetailData = async (row) => {
try {
const res = await request({
url: `/snow-ops-platform/yhzry/getById?id=${row.id}`,
method: "GET",
});
if (!res || res.code !== "00000") {
throw new Error("获取人员详情失败");
}
if (res.code === "00000") {
if (dialogType.value === "detail") {
model.title = `人员详情`;
model.content = DetailDialog;
model.props = {
detailData: res.data,
};
model.onCancel = () => {
dialogType.value = "";
modelVisible.value = false;
};
model.onConfirm = () => {
dialogType.value = "";
modelVisible.value = false;
};
model.width = "30%";
modelVisible.value = true;
}
if (dialogType.value === "edit") {
model.title = `编辑人员`;
model.content = EditDialog;
Object.assign(form, res.data);
model.props = {
detailData: res.data,
form: form,
};
model.onCancel = () => {
dialogType.value = "";
modelVisible.value = false;
};
model.onConfirm = async () => {
await handleEdit();
};
model.width = "30%";
modelVisible.value = true;
}
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error.message);
console.log(error);
}
};
const handleEdit = async () => {
try {
await dialogRef?.value?.dynamicComponentRef?.formRef.validate();
console.log("form", toRaw(form));
const res = await request({
url: "/snow-ops-platform/yhzry/update",
method: "POST",
data: toRaw(form),
});
if (res.code === "00000") {
ElMessage.success("编辑成功");
dialogType.value = "";
modelVisible.value = false;
getyhzryList(filterData);
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error.message);
console.log("error", error);
}
};
const columns = [
{
prop: "xm",
label: "姓名",
width: 100,
},
{
prop: "gw",
label: "岗位",
width: 100,
},
{
prop: "sjhm",
label: "手机号码",
},
{
prop: "cjsj",
label: "创建时间",
render: (row) => () => {
// ISO
const date = new Date(row.cjsj);
// YYYY-MM-DD HH:mm:ss
const format = (n) => n.toString().padStart(2, "0");
return h(
"div",
`${date.getFullYear()}-${format(date.getMonth() + 1)}-${format(
date.getDate()
)}
${format(date.getHours())}:${format(
date.getMinutes()
)}:${format(date.getSeconds())}`
);
},
},
{
prop: "ryjs",
label: "人员角色",
width: 150,
render: (row) => () => {
const roleConfig = {
1: { label: "负责人", color: "#f56c6c" },
2: { label: "普通工作人员", color: "#409eff" },
};
const config = roleConfig[row.ryjs] || {
label: "未知角色",
color: "#909399",
};
return h(
ElTag,
{
style: { "margin-right": "5px" },
effect: "dark",
type: row.ryjs === 1 ? "danger" : "primary",
},
() => config.label
);
},
},
{
label: "操作",
fixed: "right",
width: 150,
render: (row) => () =>
h("div", { class: "action-btns" }, [
h(
ElButton,
{
type: "primary",
link: true,
onClick: async () => {
dialogType.value = "detail";
await getDetailData(row);
},
},
() => "详情"
),
h(
ElButton,
{
type: "primary",
link: true,
onClick: async () => {
dialogType.value = "edit";
await getDetailData(row);
},
},
() => "编辑"
),
h(
ElButton,
{
type: "danger",
link: true,
onClick: async () => {
try {
await ElMessageBox.confirm("确定要删除该人员吗?", "删除确认", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
});
const res = await request({
url: `/snow-ops-platform/yhzry/delete`,
method: "POST",
data: {
id: row.id,
},
});
if (res.code === "00000") {
ElMessage.success("删除成功");
getyhzryList(filterData);
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error.message);
console.log(error);
}
},
},
() => "删除"
),
]),
},
];
//
const getyhzryList = async (filterData) => {
try {
const data = {
yhzid: yhzId.value,
xm: filterData?.xm || "",
pageNum: pagination.current,
pageSize: pagination.pageSize,
};
const res = await request({
url: "/snow-ops-platform/yhzry/list",
method: "GET",
params: data,
});
if (res.code === "00000") {
yhzryList.value = res.data.records;
pagination.total = res.data.total;
} else {
throw new Error(res.msg);
}
} catch (error) {
ElMessage.error(error.message);
console.log(error);
}
};
//
onMounted(() => {});
console.log("养护站id", yhzId.value);
//
onMounted(async () => {
await getyhzryList();
});
//
watch(
[() => filterData],
([newFilterData]) => {
getyhzryList(newFilterData);
},
{ deep: true }
);
//
const modelVisible = ref(false);
const dialogType = ref(""); //
const dialogRef = ref(null); //
//
const model = reactive({
title: "",
content: null,
props: {},
onConfirm: () => {},
onCancel: () => {},
width: "30%",
});
const INIT_FORM = {
xm: "",
sjhm: "",
gw: "",
cjsj: "",
yhzid: "",
ryjs: null, // 1- 2-
userId: "",
}; //
const form = reactive({ ...INIT_FORM }); //
//
const getUserList = async (key) => {
try {
const keyword = key;
let url = "";
if (keyword) {
url = `/snow-ops-platform/yhzry/getUserByKey?key=${keyword}`;
} else {
url = `/snow-ops-platform/yhzry/getUserByKey?key=`;
}
const res = await request({
url: url,
method: "GET",
});
if (res.code === "00000") {
return res.data;
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error.message);
console.log(error);
}
};
//
const openAddModel = () => {
model.title = `新增人员`;
model.content = AddDialog;
model.width = "30%";
Object.assign(form, INIT_FORM);
model.props = {
form: form,
getUserList: getUserList,
yhzdata: props.yhzData,
};
model.onCancel = () => {
dialogType.value = "";
modelVisible.value = false;
};
model.onConfirm = async () => {
try {
form.cjsj = new Date()
.toLocaleString("sv-SE", { hour12: false })
.replace("T", " ");
console.log("form", toRaw(form));
const res = await request({
url: "/snow-ops-platform/yhzry/add",
method: "POST",
data: toRaw(form),
});
if (res.code === "00000") {
ElMessage.success("新增人员成功");
dialogType.value = "";
modelVisible.value = false;
getyhzryList(filterData);
} else {
throw new Error(res.message);
}
} catch (error) {
ElMessage.error(error.message);
console.log("error", error);
}
};
modelVisible.value = true;
};
</script>
<style scoped>
.root {
width: 100%;
height: 100%;
padding: 10px;
display: flex;
gap: 20px;
flex-direction: column;
}
.inline-flex {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
}
.inline-flex label {
white-space: nowrap; /* 禁止换行 */
}
.form-box {
width: 100%;
height: calc(100% - 60px);
overflow: auto;
display: flex;
flex-direction: column;
}
.event-box {
width: 100%;
height: 60px;
display: flex;
flex-direction: row;
align-items: center;
gap: 20px;
justify-content: space-between;
}
.form-content {
width: 100%;
height: calc(100% - 60px);
}
.model-box {
position: absolute;
}
</style>