first commit
This commit is contained in:
330
src/views/materials/appointment/index.vue
Normal file
330
src/views/materials/appointment/index.vue
Normal file
@ -0,0 +1,330 @@
|
||||
<template>
|
||||
<div class="p-6 bg-gray-50 main">
|
||||
<div class="appWidth mx-auto mt-38 bg-white rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md">
|
||||
<!-- 表单标题区域 -->
|
||||
<div class="bg-gradient-to-r from-blue-500 to-blue-600 text-white p-6">
|
||||
<h2 class="text-2xl font-bold flex items-center"><i class="el-icon-user-circle mr-3"></i>人员配置</h2>
|
||||
<p class="text-blue-100 mt-2 opacity-90">请配置采购专员信息</p>
|
||||
<!-- ,带 <span class="text-red-300">*</span> 为必填项 -->
|
||||
<el-button
|
||||
@click="isDisabled = false"
|
||||
class="px-8 py-2.5 transition-all duration-300 font-medium"
|
||||
v-if="isDisabled"
|
||||
v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']"
|
||||
>
|
||||
点击编辑
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 表单内容区域 -->
|
||||
<el-form ref="leaveFormRef" :model="form" :rules="rules" label-width="120px" class="p-6 pt30 space-y-6 h75" :disabled="isDisabled">
|
||||
<!-- 设计负责人 -->
|
||||
<div class="fonts w60% ma">
|
||||
<el-form-item label="采购专员" prop="userId" class="mb-4">
|
||||
<el-select
|
||||
v-model="form.userId"
|
||||
placeholder="请选择采购专员"
|
||||
class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400"
|
||||
>
|
||||
<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- 提交按钮区域 -->
|
||||
<div class="flex justify-center space-x-6 mt-8 pt-6 border-t border-gray-100" v-if="!isDisabled">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitForm"
|
||||
icon="Check"
|
||||
class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium"
|
||||
v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']"
|
||||
>
|
||||
确认提交
|
||||
</el-button>
|
||||
<el-button @click="resetForm" icon="Refresh" class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium">
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PersonnelForm" lang="ts">
|
||||
import { ref, reactive, computed, onMounted, toRefs } from 'vue';
|
||||
import { getCurrentInstance } from 'vue';
|
||||
import type { ComponentInternalInstance } from 'vue';
|
||||
import { useUserStoreHook } from '@/store/modules/user';
|
||||
import { listUserByDeptId } from '@/api/system/user';
|
||||
import { ElMessage, ElLoading } from 'element-plus';
|
||||
import { Delete } from '@element-plus/icons-vue';
|
||||
import { designUserAdd, designUserDetail, systemUserList } from '@/api/materials/appointment';
|
||||
|
||||
// 获取当前实例
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
// 获取用户 store
|
||||
const userStore = useUserStoreHook();
|
||||
// 从 store 中获取当前选中的项目
|
||||
const currentProject = computed(() => userStore.selectedProject);
|
||||
// 专业字典数据
|
||||
const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major'));
|
||||
const isDisabled = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: null,
|
||||
projectId: currentProject.value?.id,
|
||||
userId: null // 设计负责人
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive({
|
||||
userId: [{ required: true, message: '请选择采购专员', trigger: 'change' }]
|
||||
});
|
||||
|
||||
// 用户列表
|
||||
const userList = ref([]);
|
||||
|
||||
// 表单引用
|
||||
const leaveFormRef = ref();
|
||||
|
||||
/** 查询当前部门的所有用户 */
|
||||
const getDeptAllUser = async (deptId: any) => {
|
||||
try {
|
||||
const res = await systemUserList({ deptId });
|
||||
// 实际项目中使用接口返回的数据
|
||||
userList.value = res.rows;
|
||||
} catch (error) {
|
||||
ElMessage.error('获取用户列表失败');
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询当前表单数据并回显 */
|
||||
const designUser = async () => {
|
||||
if (!currentProject.value?.id) return;
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '加载配置数据中...',
|
||||
background: 'rgba(255, 255, 255, 0.7)'
|
||||
});
|
||||
try {
|
||||
const res = await designUserDetail(currentProject.value?.id);
|
||||
if (res.code == 200) {
|
||||
if (!res.data) {
|
||||
resetForm();
|
||||
form.id = null;
|
||||
isDisabled.value = false;
|
||||
|
||||
return;
|
||||
}
|
||||
Object.assign(form, res.data);
|
||||
isDisabled.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取配置数据失败');
|
||||
// 添加默认空项
|
||||
} finally {
|
||||
loading.close();
|
||||
}
|
||||
};
|
||||
|
||||
/** 提交表单 */
|
||||
const submitForm = async () => {
|
||||
if (!leaveFormRef.value) return;
|
||||
try {
|
||||
// 表单验证
|
||||
await leaveFormRef.value.validate();
|
||||
let userName = userList.value.find((item) => item.userId === form.userId)?.nickName;
|
||||
const data = {
|
||||
projectId: currentProject.value?.id,
|
||||
userId: form.userId,
|
||||
userName,
|
||||
id: form.id
|
||||
};
|
||||
|
||||
// 提交到后端
|
||||
const res = await designUserAdd(data);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('提交成功');
|
||||
isDisabled.value = true;
|
||||
} else {
|
||||
ElMessage.error(res.msg || '提交失败');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('请完善表单信息后再提交');
|
||||
} finally {
|
||||
// 关闭加载状态
|
||||
ElLoading.service().close();
|
||||
}
|
||||
};
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
if (leaveFormRef.value) {
|
||||
leaveFormRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
// 页面挂载时初始化数据
|
||||
onMounted(() => {
|
||||
console.log(userStore.deptId);
|
||||
// 先获取用户列表,再加载表单数据
|
||||
getDeptAllUser(userStore.deptId).then(() => {
|
||||
designUser();
|
||||
});
|
||||
});
|
||||
|
||||
//监听项目id刷新数据
|
||||
const listeningProject = watch(
|
||||
() => currentProject.value?.id,
|
||||
(nid, oid) => {
|
||||
getDeptAllUser(userStore.deptId).then(() => {
|
||||
designUser();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
listeningProject();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.main {
|
||||
height: calc(100vh - 90px);
|
||||
}
|
||||
.appWidth {
|
||||
width: 50vw;
|
||||
max-width: 1200px;
|
||||
.el-select__wrapper {
|
||||
width: 16vw !important;
|
||||
}
|
||||
.el-button--small {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.fonts {
|
||||
.el-form-item--default .el-form-item__label {
|
||||
font-size: 18px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义动画
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fadeIn {
|
||||
animation: fadeIn 0.3s ease-out forwards;
|
||||
}
|
||||
|
||||
// 表单样式优化
|
||||
::v-deep .el-form {
|
||||
--el-form-item-margin-bottom: 0;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 0;
|
||||
|
||||
&__label {
|
||||
font-weight: 500;
|
||||
color: #4e5969;
|
||||
padding: 0 0 8px 0;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-select {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover .el-input__inner {
|
||||
border-color: #66b1ff;
|
||||
}
|
||||
|
||||
&.el-select-focus .el-input__inner {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
border-radius: 6px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&--primary {
|
||||
background-color: #409eff;
|
||||
border-color: #409eff;
|
||||
|
||||
&:hover {
|
||||
background-color: #66b1ff;
|
||||
border-color: #66b1ff;
|
||||
}
|
||||
}
|
||||
|
||||
&--danger {
|
||||
background-color: #f56c6c;
|
||||
border-color: #f56c6c;
|
||||
|
||||
&:hover {
|
||||
background-color: #f78989;
|
||||
border-color: #f78989;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: #ffcccc;
|
||||
border-color: #ffbbbb;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式网格布局
|
||||
.grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.grid-cols-1 {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.md\:grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
// 适配小屏幕
|
||||
@media (max-width: 768px) {
|
||||
.appWidth {
|
||||
width: 95vw;
|
||||
}
|
||||
|
||||
::v-deep .el-form {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__label {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user