feat/单位账号移动球机部分接口对接
This commit is contained in:
parent
16350b70db
commit
05b9e45aa0
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* @Author: 季万俊
|
||||||
|
* @Date: 2026-01-13 19:12:20
|
||||||
|
* @Description: 球机台账相关接口
|
||||||
|
*/
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询相机台账列表
|
||||||
|
export function listCameraLedger(query) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/camera/ledger/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增相机台账
|
||||||
|
export function addCameraLedger(data) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/camera/ledger',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取相机台账详情
|
||||||
|
export function getCameraLedger(cameraId) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/camera/ledger/' + cameraId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改相机台账
|
||||||
|
export function updateCameraLedger(data) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/camera/ledger',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除相机台账
|
||||||
|
export function delCameraLedger(cameraIds) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/camera/ledger/' + cameraIds,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* @Author: 季万俊
|
||||||
|
* @Date: 2026-01-13 19:12:20
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询单位档案列表
|
||||||
|
export function listUnitArchive(query) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增单位档案
|
||||||
|
export function addUnitArchive(data) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取单位档案详情
|
||||||
|
export function getUnitArchive(unitId) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive/' + unitId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改单位档案
|
||||||
|
export function updateUnitArchive(data) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除单位档案
|
||||||
|
export function delUnitArchive(unitIds) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive/' + unitIds,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改单位档案状态
|
||||||
|
export function changeUnitArchiveStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/manage/unit/archive/changeStatus',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* @Author: 季万俊
|
||||||
|
* @Date: 2026-01-13 19:12:20
|
||||||
|
* @Description: 文件上传相关接口
|
||||||
|
*/
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用文件上传
|
||||||
|
* @param {File} file - 要上传的文件对象
|
||||||
|
* @returns {Promise} 返回上传结果
|
||||||
|
*/
|
||||||
|
export function uploadFile(file) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
|
||||||
|
return request({
|
||||||
|
url: '/file/upload',
|
||||||
|
method: 'post',
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
},
|
||||||
|
// 禁用防重复提交,因为文件上传需要特殊处理
|
||||||
|
repeatSubmit: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,11 +3,51 @@
|
||||||
<div class="MainBox">
|
<div class="MainBox">
|
||||||
|
|
||||||
<div class="button-group card-box">
|
<div class="button-group card-box">
|
||||||
<el-button type="primary" size="default">新增球机</el-button>
|
<el-button type="primary" size="default" @click="handleAddCamera">新增球机</el-button>
|
||||||
<el-button type="warning" size="default">批量导入球机</el-button>
|
<el-button type="warning" size="default">批量导入球机</el-button>
|
||||||
<el-button size="default">导出台账</el-button>
|
<el-button size="default">导出台账</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 新增/编辑球机对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑球机' : '新增球机'" width="600px" @close="handleDialogClose">
|
||||||
|
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
|
||||||
|
<el-form-item label="球机编号" prop="cameraNo">
|
||||||
|
<el-input v-model="addForm.cameraNo" placeholder="请输入球机编号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备编号" prop="cameraId">
|
||||||
|
<el-input-number v-model="addForm.cameraId" :min="0" placeholder="请输入设备编号" style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="型号" prop="model">
|
||||||
|
<el-input v-model="addForm.model" placeholder="请输入型号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备状态" prop="status">
|
||||||
|
<el-select v-model="addForm.status" placeholder="请选择设备状态" style="width: 100%">
|
||||||
|
<el-option v-for="item in statusList" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属仓库" prop="warehouse">
|
||||||
|
<el-select v-model="addForm.warehouse" placeholder="请选择所属仓库" style="width: 100%">
|
||||||
|
<el-option label="一号仓库" value="1"></el-option>
|
||||||
|
<el-option label="二号仓库" value="2"></el-option>
|
||||||
|
<el-option label="三号仓库" value="3"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单位名称" prop="ownerUnit">
|
||||||
|
<el-input v-model="addForm.ownerUnit" placeholder="请输入单位名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input type="textarea" v-model="addForm.remark" placeholder="请输入备注" :rows="3"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="submitLoading" @click="handleSubmitAdd">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<el-form :model="queryForm" inline class="card-box mb-4">
|
<el-form :model="queryForm" inline class="card-box mb-4">
|
||||||
<el-form-item label="采购时间">
|
<el-form-item label="采购时间">
|
||||||
<el-date-picker v-model="queryForm.dateRange" type="daterange" value-format="yyyy-MM-dd"
|
<el-date-picker v-model="queryForm.dateRange" type="daterange" value-format="yyyy-MM-dd"
|
||||||
|
|
@ -32,39 +72,40 @@
|
||||||
<el-input v-model="queryForm.unitName" placeholder="请输入单位名称"></el-input>
|
<el-input v-model="queryForm.unitName" placeholder="请输入单位名称"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button size="default">重置</el-button>
|
<el-button size="default" @click="handleReset">重置</el-button>
|
||||||
<el-button type="primary" size="default">查询</el-button>
|
<el-button type="primary" size="default" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="card-box">
|
<div class="card-box">
|
||||||
<el-table :data="tableData">
|
<el-table v-loading="loading" :data="tableData">
|
||||||
<el-table-column prop="ballheadNumber" label="球机编号"></el-table-column>
|
<el-table-column prop="cameraNo" label="球机编号"></el-table-column>
|
||||||
<el-table-column prop="deviceNumber" label="设备编号"></el-table-column>
|
<el-table-column prop="cameraId" label="设备编号"></el-table-column>
|
||||||
<el-table-column prop="purchaseTime" label="采购时间"></el-table-column>
|
<el-table-column prop="createTime" label="采购时间"></el-table-column>
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="scope.row.status === '启用' ? 'success' : 'danger'">
|
<el-tag :type="getStatusType(scope.row.status)">
|
||||||
{{ scope.row.status }}
|
{{ getStatusName(scope.row.status) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="repositoryName" label="所属仓库"></el-table-column>
|
<el-table-column prop="warehouse" label="所属仓库"></el-table-column>
|
||||||
|
<el-table-column prop="ownerUnit" label="单位名称"></el-table-column>
|
||||||
<el-table-column prop="remark" label="备注"></el-table-column>
|
<el-table-column prop="remark" label="备注"></el-table-column>
|
||||||
<el-table-column label="操作" width="280">
|
<el-table-column label="操作" width="280">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" type="text">编辑</el-button>
|
<el-button size="small" type="text" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
<el-button size="small" type="danger" link>删除</el-button>
|
<el-button size="small" type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ pageNum * pageSize }} 条记录,共 {{
|
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ Math.min(pageNum * pageSize, total) }} 条记录,共 {{
|
||||||
total }}
|
total }}
|
||||||
条</span>
|
条</span>
|
||||||
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
||||||
:total="total" layout="prev, pager, next"></el-pagination>
|
:total="total" layout="prev, pager, next" @size-change="handleSizeChange" @current-change="handlePageChange"></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -72,7 +113,16 @@
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { listCameraLedger, addCameraLedger, getCameraLedger, updateCameraLedger, delCameraLedger } from "@/api/camera";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const loading = ref(false); // 加载状态
|
||||||
|
const dialogVisible = ref(false); // 新增/编辑对话框显示状态
|
||||||
|
const submitLoading = ref(false); // 提交加载状态
|
||||||
|
const addFormRef = ref(null); // 新增/编辑表单引用
|
||||||
|
const isEdit = ref(false); // 是否为编辑模式
|
||||||
|
const currentCameraId = ref(null); // 当前编辑的相机ID
|
||||||
|
|
||||||
// 查询表单数据
|
// 查询表单数据
|
||||||
const queryForm = ref({
|
const queryForm = ref({
|
||||||
|
|
@ -82,6 +132,30 @@ const queryForm = ref({
|
||||||
repositoryId: ""
|
repositoryId: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 新增表单数据
|
||||||
|
const addForm = ref({
|
||||||
|
cameraNo: "",
|
||||||
|
cameraId: 0,
|
||||||
|
model: "",
|
||||||
|
status: "",
|
||||||
|
ownerUnit: "",
|
||||||
|
warehouse: "",
|
||||||
|
remark: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
// 新增表单验证规则
|
||||||
|
const addFormRules = {
|
||||||
|
cameraNo: [
|
||||||
|
{ required: true, message: "请输入球机编号", trigger: "blur" }
|
||||||
|
],
|
||||||
|
model: [
|
||||||
|
{ required: true, message: "请输入型号", trigger: "blur" }
|
||||||
|
],
|
||||||
|
status: [
|
||||||
|
{ required: true, message: "请选择设备状态", trigger: "change" }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
// 设备状态列表
|
// 设备状态列表
|
||||||
const statusList = ref([
|
const statusList = ref([
|
||||||
{
|
{
|
||||||
|
|
@ -103,46 +177,248 @@ const statusList = ref([
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref([
|
const tableData = ref([]);
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
ballheadNumber: "B001",
|
|
||||||
deviceNumber: "D001",
|
|
||||||
purchaseTime: "2023-05-12 14:30",
|
|
||||||
status: "启用",
|
|
||||||
repositoryName: "一号仓库",
|
|
||||||
remark: "备注1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
ballheadNumber: "B002",
|
|
||||||
deviceNumber: "D002",
|
|
||||||
purchaseTime: "2023-05-12 14:30",
|
|
||||||
status: "禁用",
|
|
||||||
repositoryName: "二号仓库",
|
|
||||||
remark: "备注2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
ballheadNumber: "B003",
|
|
||||||
deviceNumber: "D003",
|
|
||||||
purchaseTime: "2023-05-12 14:30",
|
|
||||||
status: "启用",
|
|
||||||
repositoryName: "三号仓库",
|
|
||||||
remark: "备注3"
|
|
||||||
},
|
|
||||||
|
|
||||||
]);
|
|
||||||
const pageNum = ref(1); // 当前页码
|
const pageNum = ref(1); // 当前页码
|
||||||
const pageSize = ref(5); // 每页显示条数
|
const pageSize = ref(10); // 每页显示条数
|
||||||
const total = ref(20); // 总记录数
|
const total = ref(0); // 总记录数
|
||||||
|
|
||||||
|
// 获取列表数据
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
pageNum: pageNum.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加查询条件
|
||||||
|
if (queryForm.value.unitName) {
|
||||||
|
params.ownerUnit = queryForm.value.unitName;
|
||||||
|
}
|
||||||
|
if (queryForm.value.status !== "" && queryForm.value.status !== null && queryForm.value.status !== undefined) {
|
||||||
|
params.status = queryForm.value.status;
|
||||||
|
}
|
||||||
|
if (queryForm.value.repositoryId) {
|
||||||
|
params.warehouse = queryForm.value.repositoryId;
|
||||||
|
}
|
||||||
|
// 处理日期范围 - 采购时间
|
||||||
|
if (queryForm.value.dateRange && queryForm.value.dateRange.length === 2) {
|
||||||
|
// 开始时间:当天 00:00:00
|
||||||
|
params.createTime = queryForm.value.dateRange[0] + 'T00:00:00';
|
||||||
|
// 结束时间:当天 23:59:59(如果需要,可以添加 endTime 或 updateTime 参数)
|
||||||
|
// 如果后端支持日期范围查询,可能需要传递 endTime 参数
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await listCameraLedger(params);
|
||||||
|
if (response.code === 200) {
|
||||||
|
tableData.value = response.rows || response.data || [];
|
||||||
|
total.value = response.total || 0;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取数据失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取列表数据失败:", error);
|
||||||
|
ElMessage.error("获取数据失败,请稍后重试");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 跳转到账号管理
|
// 查询
|
||||||
const handleAccountManagement = (row) => {
|
const handleQuery = () => {
|
||||||
console.log("账号管理", row);
|
pageNum.value = 1;
|
||||||
router.push(`/accountManagement?enterpriseName=${row.name}`);
|
getList();
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
queryForm.value = {
|
||||||
|
dateRange: [],
|
||||||
|
unitName: "",
|
||||||
|
status: "",
|
||||||
|
repositoryId: ""
|
||||||
|
};
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页大小改变
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
pageSize.value = val;
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页码改变
|
||||||
|
const handlePageChange = (val) => {
|
||||||
|
pageNum.value = val;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据状态值获取状态名称
|
||||||
|
const getStatusName = (status) => {
|
||||||
|
const statusMap = {
|
||||||
|
"0": "闲置",
|
||||||
|
"1": "已分配",
|
||||||
|
"2": "待回收",
|
||||||
|
"3": "已入库"
|
||||||
|
};
|
||||||
|
return statusMap[status] || status || "未知";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据状态值获取标签类型
|
||||||
|
const getStatusType = (status) => {
|
||||||
|
const typeMap = {
|
||||||
|
"0": "info",
|
||||||
|
"1": "success",
|
||||||
|
"2": "warning",
|
||||||
|
"3": ""
|
||||||
|
};
|
||||||
|
return typeMap[status] || "";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开新增对话框
|
||||||
|
const handleAddCamera = () => {
|
||||||
|
isEdit.value = false;
|
||||||
|
currentCameraId.value = null;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开编辑对话框
|
||||||
|
const handleEdit = async (row) => {
|
||||||
|
isEdit.value = true;
|
||||||
|
currentCameraId.value = row.cameraId || row.id;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
|
||||||
|
// 加载详情数据
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const response = await getCameraLedger(currentCameraId.value);
|
||||||
|
if (response.code === 200) {
|
||||||
|
const data = response.data || response;
|
||||||
|
// 填充表单数据
|
||||||
|
addForm.value = {
|
||||||
|
cameraNo: data.cameraNo || "",
|
||||||
|
cameraId: data.cameraId || 0,
|
||||||
|
model: data.model || "",
|
||||||
|
status: data.status || "",
|
||||||
|
ownerUnit: data.ownerUnit || "",
|
||||||
|
warehouse: data.warehouse || "",
|
||||||
|
remark: data.remark || ""
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取详情失败");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取详情失败:", error);
|
||||||
|
ElMessage.error("获取详情失败,请稍后重试");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭对话框
|
||||||
|
const handleDialogClose = () => {
|
||||||
|
addFormRef.value?.resetFields();
|
||||||
|
addForm.value = {
|
||||||
|
cameraNo: "",
|
||||||
|
cameraId: 0,
|
||||||
|
model: "",
|
||||||
|
status: "",
|
||||||
|
ownerUnit: "",
|
||||||
|
warehouse: "",
|
||||||
|
remark: ""
|
||||||
|
};
|
||||||
|
isEdit.value = false;
|
||||||
|
currentCameraId.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交新增/编辑
|
||||||
|
const handleSubmitAdd = async () => {
|
||||||
|
if (!addFormRef.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await addFormRef.value.validate();
|
||||||
|
submitLoading.value = true;
|
||||||
|
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData = {
|
||||||
|
cameraNo: addForm.value.cameraNo,
|
||||||
|
cameraId: addForm.value.cameraId || 0,
|
||||||
|
model: addForm.value.model,
|
||||||
|
status: addForm.value.status,
|
||||||
|
ownerUnit: addForm.value.ownerUnit || "",
|
||||||
|
warehouse: addForm.value.warehouse || "",
|
||||||
|
remark: addForm.value.remark || "",
|
||||||
|
delFlag: "0" // 默认未删除
|
||||||
|
};
|
||||||
|
|
||||||
|
let response;
|
||||||
|
if (isEdit.value) {
|
||||||
|
// 编辑模式,需要添加 cameraId
|
||||||
|
submitData.cameraId = currentCameraId.value;
|
||||||
|
response = await updateCameraLedger(submitData);
|
||||||
|
} else {
|
||||||
|
// 新增模式
|
||||||
|
response = await addCameraLedger(submitData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(isEdit.value ? "编辑球机成功" : "新增球机成功");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
// 刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || (isEdit.value ? "编辑球机失败" : "新增球机失败"));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== false) { // 表单验证失败会返回 false,不需要处理
|
||||||
|
console.error(isEdit.value ? "编辑球机失败:" : "新增球机失败:", error);
|
||||||
|
ElMessage.error(isEdit.value ? "编辑球机失败,请稍后重试" : "新增球机失败,请稍后重试");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除球机
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
const cameraId = row.cameraId || row.id;
|
||||||
|
const cameraNo = row.cameraNo || '该球机';
|
||||||
|
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除"${cameraNo}"吗?删除后无法恢复。`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
const response = await delCameraLedger(cameraId);
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
// 删除成功后刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '删除失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error);
|
||||||
|
ElMessage.error('删除失败,请稍后重试');
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时获取数据
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.MainBox {
|
.MainBox {
|
||||||
|
|
|
||||||
|
|
@ -37,115 +37,586 @@
|
||||||
<el-input v-model="queryForm.keyword" placeholder="账号名/姓名/手机号"></el-input>
|
<el-input v-model="queryForm.keyword" placeholder="账号名/姓名/手机号"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button size="default">重置</el-button>
|
<el-button size="default" @click="handleReset">重置</el-button>
|
||||||
<el-button type="primary" size="default">查询</el-button>
|
<el-button type="primary" size="default" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="card-box">
|
<div class="card-box">
|
||||||
<el-table :data="tableData">
|
<el-table v-loading="loading" :data="tableData">
|
||||||
<el-table-column type="selection" width="55"></el-table-column>
|
<el-table-column type="selection" width="55"></el-table-column>
|
||||||
<el-table-column prop="accountName" label="账号名"></el-table-column>
|
<el-table-column prop="userName" label="账号名"></el-table-column>
|
||||||
<el-table-column prop="contactName" label="姓名"></el-table-column>
|
<el-table-column prop="nickName" label="姓名"></el-table-column>
|
||||||
<el-table-column prop="roleType" label="角色"></el-table-column>
|
<el-table-column prop="roleName" label="角色"></el-table-column>
|
||||||
<el-table-column prop="contactPhone" label="手机号"></el-table-column>
|
<el-table-column prop="phonenumber" label="手机号"></el-table-column>
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="scope.row.status === '启用' ? 'success' : 'danger'">
|
<el-tag :type="(scope.row.status === '0' || scope.row.status === 0) ? 'success' : 'danger'">
|
||||||
{{ scope.row.status }}
|
{{ (scope.row.status === '0' || scope.row.status === 0) ? '启用' : '禁用' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" label="创建时间"></el-table-column>
|
<el-table-column prop="createTime" label="创建时间"></el-table-column>
|
||||||
<el-table-column label="操作" width="280">
|
<el-table-column label="操作" width="350">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" type="text" @click="handleEditRole(scope.row)">编辑角色</el-button>
|
<el-button size="small" type="text" @click="handleEditRole(scope.row)">编辑</el-button>
|
||||||
<el-button size="small" type="text" :type="scope.row.status === '启用' ? 'danger' : 'success'">
|
<el-button size="small" type="text" @click="handleResetPwd(scope.row)">重置密码</el-button>
|
||||||
{{ scope.row.status === '启用' ? '禁用' : '启用' }}
|
<el-button size="small" type="text" :type="(scope.row.status === '0' || scope.row.status === 0) ? 'danger' : 'success'" @click="handleStatusChange(scope.row)">
|
||||||
|
{{ (scope.row.status === '0' || scope.row.status === 0) ? '禁用' : '启用' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" type="danger" link>删除</el-button>
|
<el-button size="small" type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ pageNum * pageSize }} 条记录,共 {{
|
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ Math.min(pageNum * pageSize, total) }} 条记录,共 {{
|
||||||
total }}
|
total }}
|
||||||
条</span>
|
条</span>
|
||||||
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
||||||
:total="total" layout="prev, pager, next"></el-pagination>
|
:total="total" layout="prev, pager, next" @size-change="handleSizeChange" @current-change="handlePageChange"></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 创建/编辑账号对话框 -->
|
||||||
|
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑账号' : '创建账号'" width="600px" @close="handleDialogClose">
|
||||||
|
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="80px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户昵称" prop="nickName">
|
||||||
|
<el-input v-model="addForm.nickName" placeholder="请输入用户昵称" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="归属部门" prop="deptId">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="addForm.deptId"
|
||||||
|
:data="deptOptions"
|
||||||
|
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||||
|
value-key="id"
|
||||||
|
placeholder="请选择归属部门"
|
||||||
|
:disabled="true"
|
||||||
|
check-strictly
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="手机号码" prop="phonenumber">
|
||||||
|
<el-input v-model="addForm.phonenumber" placeholder="请输入手机号码" maxlength="11" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="addForm.email" placeholder="请输入邮箱" maxlength="50" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户名称" prop="userName">
|
||||||
|
<el-input v-model="addForm.userName" :disabled="isEdit" placeholder="请输入用户名称" maxlength="30" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="isEdit ? '用户密码(留空不修改)' : '用户密码'" :prop="isEdit ? '' : 'password'">
|
||||||
|
<el-input v-model="addForm.password" :placeholder="isEdit ? '留空则不修改密码' : '请输入用户密码'" type="password" maxlength="20" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="用户性别">
|
||||||
|
<el-select v-model="addForm.sex" placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-radio-group v-model="addForm.status">
|
||||||
|
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="岗位">
|
||||||
|
<el-select v-model="addForm.postIds" multiple placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="角色">
|
||||||
|
<el-select v-model="addForm.roleIds" multiple placeholder="请选择" style="width: 100%">
|
||||||
|
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model="addForm.remark" type="textarea" placeholder="请输入内容"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="submitLoading" @click="handleSubmitAdd">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
import { ref, onBeforeMount } from "vue";
|
import { ref, computed, onMounted, getCurrentInstance } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { listUser, addUser, getUser, updateUser, delUser, changeUserStatus, resetUserPwd, deptTreeSelect } from "@/api/system/user";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const loading = ref(false); // 加载状态
|
||||||
|
const unitId = ref(null); // 单位ID
|
||||||
|
const deptId = ref(null); // 部门ID
|
||||||
|
const dialogVisible = ref(false); // 创建/编辑账号对话框显示状态
|
||||||
|
const submitLoading = ref(false); // 提交加载状态
|
||||||
|
const addFormRef = ref(null); // 表单引用
|
||||||
|
const isEdit = ref(false); // 是否为编辑模式
|
||||||
|
const currentUserId = ref(null); // 当前编辑的用户ID
|
||||||
|
|
||||||
|
// 获取字典数据
|
||||||
|
const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable", "sys_user_sex");
|
||||||
|
|
||||||
|
// 部门选项
|
||||||
|
const deptOptions = ref([]);
|
||||||
|
// 岗位选项
|
||||||
|
const postOptions = ref([]);
|
||||||
|
// 角色选项
|
||||||
|
const roleOptions = ref([]);
|
||||||
|
|
||||||
// 单位数据
|
// 单位数据
|
||||||
const enterpriseData = ref({
|
const enterpriseData = ref({
|
||||||
enterpriseType: '',
|
enterpriseName: ''
|
||||||
enterpriseName: '',
|
|
||||||
area: '',
|
|
||||||
creditCode: '',
|
|
||||||
contactName: '',
|
|
||||||
contactPhone: ''
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 查询表单数据
|
// 查询表单数据
|
||||||
const queryForm = ref({
|
const queryForm = ref({
|
||||||
dateRange: "",
|
dateRange: [],
|
||||||
status: "",
|
status: "",
|
||||||
roleType: "",
|
roleType: "",
|
||||||
keyword: ""
|
keyword: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref([
|
const tableData = ref([]);
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
accountName: "admin",
|
|
||||||
contactName: "张三",
|
|
||||||
roleType: "监理工程师",
|
|
||||||
contactPhone: "13800000000",
|
|
||||||
status: "启用",
|
|
||||||
createTime: "2023-05-12 14:30"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
accountName: "user123",
|
|
||||||
contactName: "李四",
|
|
||||||
roleType: "项目经理",
|
|
||||||
contactPhone: "13900000000",
|
|
||||||
status: "禁用",
|
|
||||||
createTime: "2023-05-13 10:20"
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const pageNum = ref(1); // 当前页码
|
const pageNum = ref(1); // 当前页码
|
||||||
const pageSize = ref(5); // 每页显示条数
|
const pageSize = ref(10); // 每页显示条数
|
||||||
|
const total = ref(0); // 总记录数
|
||||||
|
|
||||||
const total = ref(20); // 总记录数
|
// 获取用户列表
|
||||||
|
const getList = async () => {
|
||||||
onBeforeMount(() => {
|
if (!unitId.value) {
|
||||||
// 从路由参数中获取单位类型
|
ElMessage.warning('缺少单位ID参数');
|
||||||
const enterpriseName = router.currentRoute.value.query.enterpriseName;
|
return;
|
||||||
if (enterpriseName) {
|
|
||||||
enterpriseData.value.enterpriseName = enterpriseName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
unitId: unitId.value,
|
||||||
|
pageNum: pageNum.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加查询条件
|
||||||
|
if (queryForm.value.keyword) {
|
||||||
|
params.keyword = queryForm.value.keyword;
|
||||||
|
}
|
||||||
|
if (queryForm.value.status !== "" && queryForm.value.status !== null && queryForm.value.status !== undefined) {
|
||||||
|
params.status = queryForm.value.status;
|
||||||
|
}
|
||||||
|
if (queryForm.value.roleType) {
|
||||||
|
params.roleType = queryForm.value.roleType;
|
||||||
|
}
|
||||||
|
// 处理日期范围
|
||||||
|
if (queryForm.value.dateRange && queryForm.value.dateRange.length === 2) {
|
||||||
|
params.beginTime = queryForm.value.dateRange[0];
|
||||||
|
params.endTime = queryForm.value.dateRange[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await listUser(params);
|
||||||
|
if (response.code === 200) {
|
||||||
|
tableData.value = response.rows || response.data || [];
|
||||||
|
total.value = response.total || 0;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取数据失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取用户列表失败:", error);
|
||||||
|
ElMessage.error("获取数据失败,请稍后重试");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const handleQuery = () => {
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
queryForm.value = {
|
||||||
|
dateRange: [],
|
||||||
|
status: "",
|
||||||
|
roleType: "",
|
||||||
|
keyword: ""
|
||||||
|
};
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页大小改变
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
pageSize.value = val;
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页码改变
|
||||||
|
const handlePageChange = (val) => {
|
||||||
|
pageNum.value = val;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增表单数据
|
||||||
|
const addForm = ref({
|
||||||
|
userName: '',
|
||||||
|
nickName: '',
|
||||||
|
password: '',
|
||||||
|
deptId: '',
|
||||||
|
phonenumber: '',
|
||||||
|
email: '',
|
||||||
|
sex: '',
|
||||||
|
status: '0',
|
||||||
|
postIds: [],
|
||||||
|
roleIds: [],
|
||||||
|
remark: '',
|
||||||
|
unitId: '' // 单位ID
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 表单验证规则(动态)
|
||||||
|
const getFormRules = () => {
|
||||||
|
const rules = {
|
||||||
|
userName: [
|
||||||
|
{ required: true, message: "用户名称不能为空", trigger: "blur" },
|
||||||
|
{ min: 2, max: 20, message: "用户名称长度必须介于 2 和 20 之间", trigger: "blur" }
|
||||||
|
],
|
||||||
|
nickName: [
|
||||||
|
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }
|
||||||
|
],
|
||||||
|
phonenumber: [
|
||||||
|
{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// 只有新增模式才需要密码验证
|
||||||
|
if (!isEdit.value) {
|
||||||
|
rules.password = [
|
||||||
|
{ required: true, message: "用户密码不能为空", trigger: "blur" },
|
||||||
|
{ min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
|
||||||
|
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// 编辑模式下,如果填写了密码才验证
|
||||||
|
rules.password = [
|
||||||
|
{ min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
|
||||||
|
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rules;
|
||||||
|
};
|
||||||
|
|
||||||
// 编辑角色
|
const addFormRules = computed(() => getFormRules());
|
||||||
const handleEditRole = (row) => {
|
|
||||||
console.log("编辑角色", row);
|
// 获取部门树
|
||||||
}
|
const getDeptTree = async () => {
|
||||||
|
try {
|
||||||
|
const response = await deptTreeSelect();
|
||||||
|
if (response.code === 200) {
|
||||||
|
deptOptions.value = response.data || [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取部门树失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开创建账号对话框
|
||||||
|
const handleAddEnterprise = async () => {
|
||||||
|
isEdit.value = false;
|
||||||
|
currentUserId.value = null;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
|
||||||
|
// 获取岗位和角色选项
|
||||||
|
try {
|
||||||
|
const response = await getUser();
|
||||||
|
if (response.code === 200) {
|
||||||
|
postOptions.value = response.posts || [];
|
||||||
|
roleOptions.value = response.roles || [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取岗位和角色失败:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置部门ID和单位ID
|
||||||
|
addForm.value.deptId = deptId.value;
|
||||||
|
addForm.value.unitId = unitId.value;
|
||||||
|
addForm.value.password = ''; // 新增时清空密码
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭对话框
|
||||||
|
const handleDialogClose = () => {
|
||||||
|
addFormRef.value?.resetFields();
|
||||||
|
addForm.value = {
|
||||||
|
userName: '',
|
||||||
|
nickName: '',
|
||||||
|
password: '',
|
||||||
|
deptId: deptId.value,
|
||||||
|
phonenumber: '',
|
||||||
|
email: '',
|
||||||
|
sex: '',
|
||||||
|
status: '0',
|
||||||
|
postIds: [],
|
||||||
|
roleIds: [],
|
||||||
|
remark: '',
|
||||||
|
unitId: unitId.value
|
||||||
|
};
|
||||||
|
isEdit.value = false;
|
||||||
|
currentUserId.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交创建/编辑账号
|
||||||
|
const handleSubmitAdd = async () => {
|
||||||
|
if (!addFormRef.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await addFormRef.value.validate();
|
||||||
|
submitLoading.value = true;
|
||||||
|
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData = { ...addForm.value };
|
||||||
|
|
||||||
|
// 如果是编辑模式且密码为空,则不传递密码字段
|
||||||
|
if (isEdit.value && !submitData.password) {
|
||||||
|
delete submitData.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是编辑模式,添加 userId
|
||||||
|
if (isEdit.value) {
|
||||||
|
submitData.userId = currentUserId.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = isEdit.value
|
||||||
|
? await updateUser(submitData)
|
||||||
|
: await addUser(submitData);
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(isEdit.value ? "编辑账号成功" : "创建账号成功");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
// 刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || (isEdit.value ? "编辑账号失败" : "创建账号失败"));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== false) { // 表单验证失败会返回 false,不需要处理
|
||||||
|
console.error(isEdit.value ? "编辑账号失败:" : "创建账号失败:", error);
|
||||||
|
ElMessage.error(isEdit.value ? "编辑账号失败,请稍后重试" : "创建账号失败,请稍后重试");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑角色(打开编辑对话框)
|
||||||
|
const handleEditRole = async (row) => {
|
||||||
|
isEdit.value = true;
|
||||||
|
currentUserId.value = row.userId;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
|
||||||
|
// 获取用户详情和岗位、角色选项
|
||||||
|
try {
|
||||||
|
const response = await getUser(row.userId);
|
||||||
|
if (response.code === 200) {
|
||||||
|
const data = response.data;
|
||||||
|
// 填充表单数据
|
||||||
|
addForm.value = {
|
||||||
|
userName: data.userName || '',
|
||||||
|
nickName: data.nickName || '',
|
||||||
|
password: '', // 编辑时密码留空
|
||||||
|
deptId: data.deptId || deptId.value,
|
||||||
|
phonenumber: data.phonenumber || '',
|
||||||
|
email: data.email || '',
|
||||||
|
sex: data.sex || '',
|
||||||
|
status: data.status || '0',
|
||||||
|
postIds: response.postIds || [],
|
||||||
|
roleIds: response.roleIds || [],
|
||||||
|
remark: data.remark || '',
|
||||||
|
unitId: unitId.value
|
||||||
|
};
|
||||||
|
// 获取岗位和角色选项
|
||||||
|
postOptions.value = response.posts || [];
|
||||||
|
roleOptions.value = response.roles || [];
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取用户详情失败");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取用户详情失败:", error);
|
||||||
|
ElMessage.error("获取用户详情失败,请稍后重试");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 用户状态修改(启用/禁用)
|
||||||
|
const handleStatusChange = (row) => {
|
||||||
|
const text = (row.status === '0' || row.status === 0) ? "禁用" : "启用";
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确认要"${text}""${row.userName}"用户吗?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
const newStatus = (row.status === '0' || row.status === 0) ? '1' : '0';
|
||||||
|
const response = await changeUserStatus(row.userId, newStatus);
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(`${text}成功`);
|
||||||
|
// 刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || `${text}失败`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`${text}失败:`, error);
|
||||||
|
ElMessage.error(`${text}失败,请稍后重试`);
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消操作
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除用户
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
const userId = row.userId;
|
||||||
|
const userName = row.userName || row.nickName || '该用户';
|
||||||
|
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`是否确认删除用户"${userName}"?`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
const response = await delUser(userId);
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
// 删除成功后刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '删除失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error);
|
||||||
|
ElMessage.error('删除失败,请稍后重试');
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置密码
|
||||||
|
const handleResetPwd = (row) => {
|
||||||
|
ElMessageBox.prompt(
|
||||||
|
`请输入"${row.userName}"的新密码`,
|
||||||
|
'重置密码',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPattern: /^.{5,20}$/,
|
||||||
|
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
|
||||||
|
inputValidator: (value) => {
|
||||||
|
if (/<|>|"|'|\||\\/.test(value)) {
|
||||||
|
return "不能包含非法字符:< > \" ' \\\ |";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
).then(({ value }) => {
|
||||||
|
resetUserPwd(row.userId, value).then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success("修改成功,新密码是:" + value);
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "重置密码失败");
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error("重置密码失败:", error);
|
||||||
|
ElMessage.error("重置密码失败,请稍后重试");
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 处理返回按钮点击事件
|
// 处理返回按钮点击事件
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
router.go(-1);
|
router.go(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 组件挂载时获取数据
|
||||||
|
onMounted(() => {
|
||||||
|
const route = router.currentRoute.value;
|
||||||
|
// 从路由参数中获取单位ID、部门ID和单位名称
|
||||||
|
const id = route.query.unitId;
|
||||||
|
const deptIdParam = route.query.deptId;
|
||||||
|
const enterpriseName = route.query.enterpriseName;
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
unitId.value = id;
|
||||||
|
if (deptIdParam) {
|
||||||
|
deptId.value = deptIdParam;
|
||||||
|
}
|
||||||
|
if (enterpriseName) {
|
||||||
|
enterpriseData.value.enterpriseName = enterpriseName;
|
||||||
|
}
|
||||||
|
// 获取部门树
|
||||||
|
getDeptTree();
|
||||||
|
// 获取用户列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('缺少单位ID参数');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
<!-- 物业模块-单位与账号管理-新增单位建档 -->
|
<!-- 物业模块-单位与账号管理-新增单位建档 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="MainBox">
|
<div class="MainBox">
|
||||||
|
<h2 class="page-title">{{ isEdit ? '编辑单位建档' : '新增单位建档' }}</h2>
|
||||||
<div class="CardBox">
|
<div class="CardBox">
|
||||||
<div class="FormBox">
|
<div class="FormBox">
|
||||||
<div class="LeftBox">
|
<div class="LeftBox">
|
||||||
<h2>基础信息</h2>
|
<h2>基础信息</h2>
|
||||||
<el-form :model="basicsForm" ref="formRef" label-position="top">
|
<el-form :model="basicsForm" :rules="basicsRules" ref="basicsFormRef" label-position="top">
|
||||||
<el-form-item label="单位类型" prop="enterpriseType">
|
<el-form-item label="单位类型" prop="enterpriseType">
|
||||||
<el-select v-model="basicsForm.enterpriseType" placeholder="请选择单位类型">
|
<el-select v-model="basicsForm.enterpriseType" placeholder="请选择单位类型">
|
||||||
<el-option label="施工单位" value="1" />
|
<el-option label="施工单位" value="1" />
|
||||||
|
|
@ -16,8 +17,17 @@
|
||||||
<el-form-item label="单位名称" prop="enterpriseName">
|
<el-form-item label="单位名称" prop="enterpriseName">
|
||||||
<el-input v-model="basicsForm.enterpriseName" placeholder="请输入单位名称" />
|
<el-input v-model="basicsForm.enterpriseName" placeholder="请输入单位名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属区域" prop="area">
|
<el-form-item label="所属区域" prop="deptId">
|
||||||
<el-input v-model="basicsForm.area" placeholder="请输入所属区域" />
|
<el-tree-select
|
||||||
|
v-model="basicsForm.deptId"
|
||||||
|
:data="deptOptions"
|
||||||
|
:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
|
||||||
|
value-key="deptId"
|
||||||
|
placeholder="请选择所属区域"
|
||||||
|
check-strictly
|
||||||
|
@change="handleAreaChange"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="统一社会信用代码" prop="creditCode">
|
<el-form-item label="统一社会信用代码" prop="creditCode">
|
||||||
<el-input v-model="basicsForm.creditCode" placeholder="请输入统一社会信用代码" />
|
<el-input v-model="basicsForm.creditCode" placeholder="请输入统一社会信用代码" />
|
||||||
|
|
@ -38,13 +48,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="RightBox">
|
<div class="RightBox">
|
||||||
<h2>拓展信息</h2>
|
<h2>拓展信息</h2>
|
||||||
<el-form :model="expandForm" ref="formRef" label-position="top">
|
<el-form :model="expandForm" ref="expandFormRef" label-position="top">
|
||||||
<el-form-item label="单位地址" prop="enterpriseAddress">
|
<el-form-item label="单位地址" prop="enterpriseAddress">
|
||||||
<el-input type="textarea" v-model="expandForm.enterpriseAddress" placeholder="请输入单位地址" />
|
<el-input type="textarea" v-model="expandForm.enterpriseAddress" placeholder="请输入单位地址" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="资质文件上传" prop="qualificationFile">
|
<el-form-item label="资质文件上传" prop="qualificationFile">
|
||||||
<el-upload class="avatar-uploader" drag :action="uploadUrl" :show-file-list="false"
|
<el-upload class="avatar-uploader" drag :http-request="handleFileUpload"
|
||||||
:on-success="handleAvatarSuccess">
|
:show-file-list="false" :before-upload="handleBeforeUpload">
|
||||||
<div class="UploadBox">
|
<div class="UploadBox">
|
||||||
<el-icon class="iconBox">
|
<el-icon class="iconBox">
|
||||||
<UploadFilled />
|
<UploadFilled />
|
||||||
|
|
@ -53,6 +63,10 @@
|
||||||
<p>支持PDF/JPG/PNG格式,最大10mb</p>
|
<p>支持PDF/JPG/PNG格式,最大10mb</p>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
<div v-if="qualFileUrl" class="uploaded-file">
|
||||||
|
<el-link :href="qualFileUrl" target="_blank" type="primary">已上传文件</el-link>
|
||||||
|
<el-button size="small" type="danger" link @click="handleRemoveFile">删除</el-button>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="expandForm.remark" placeholder="请输入备注" />
|
<el-input v-model="expandForm.remark" placeholder="请输入备注" />
|
||||||
|
|
@ -63,23 +77,33 @@
|
||||||
</div>
|
</div>
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<div class="ButtonBox">
|
<div class="ButtonBox">
|
||||||
<el-button>暂存草稿</el-button>
|
|
||||||
<el-button @click="handleBack">返回</el-button>
|
<el-button @click="handleBack">返回</el-button>
|
||||||
<el-button type="primary">保存建档</el-button>
|
<el-button type="primary" :loading="submitLoading" @click="handleSave">保存建档</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { UploadFilled } from '@element-plus/icons-vue'
|
||||||
|
import { addUnitArchive, updateUnitArchive, getUnitArchive } from "@/api/unit";
|
||||||
|
import { listDept } from "@/api/system/dept";
|
||||||
|
import { uploadFile } from "@/api/upload";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
// 部门列表数据
|
||||||
|
const deptOptions = ref([]);
|
||||||
|
|
||||||
// 基础表单
|
// 基础表单
|
||||||
const basicsForm = ref({
|
const basicsForm = ref({
|
||||||
enterpriseType: '',
|
enterpriseType: '',
|
||||||
enterpriseName: '',
|
enterpriseName: '',
|
||||||
area: '',
|
deptId: '', // 部门ID
|
||||||
|
deptName: '', // 部门名称
|
||||||
creditCode: '',
|
creditCode: '',
|
||||||
contactName: '',
|
contactName: '',
|
||||||
contactPhone: ''
|
contactPhone: ''
|
||||||
|
|
@ -91,20 +115,246 @@ const expandForm = ref({
|
||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// 从路由参数中获取单位类型
|
// 表单引用
|
||||||
|
const basicsFormRef = ref(null);
|
||||||
|
const expandFormRef = ref(null);
|
||||||
|
|
||||||
|
// 提交加载状态
|
||||||
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
|
// 是否为编辑模式
|
||||||
|
const isEdit = ref(false);
|
||||||
|
const unitId = ref(null);
|
||||||
|
|
||||||
|
// 资质文件URL
|
||||||
|
const qualFileUrl = ref('');
|
||||||
|
const uploadLoading = ref(false);
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const basicsRules = ref({
|
||||||
|
enterpriseType: [
|
||||||
|
{ required: true, message: '请选择单位类型', trigger: 'change' }
|
||||||
|
],
|
||||||
|
enterpriseName: [
|
||||||
|
{ required: true, message: '请输入单位名称', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
deptId: [
|
||||||
|
{ required: true, message: '请选择所属区域', trigger: 'change' }
|
||||||
|
],
|
||||||
|
creditCode: [
|
||||||
|
{ required: true, message: '请输入统一社会信用代码', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
contactName: [
|
||||||
|
{ required: true, message: '请输入联系人', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
contactPhone: [
|
||||||
|
{ required: true, message: '请输入联系电话', trigger: 'blur' },
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取部门列表
|
||||||
|
const getDeptList = async () => {
|
||||||
|
try {
|
||||||
|
const response = await listDept();
|
||||||
|
if (response.code === 200) {
|
||||||
|
// 将部门数据转换为树形结构
|
||||||
|
deptOptions.value = proxy.handleTree(response.data, "deptId");
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取部门列表失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取部门列表失败:", error);
|
||||||
|
ElMessage.error("获取部门列表失败,请稍后重试");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 区域选择变化处理
|
||||||
|
const handleAreaChange = (value) => {
|
||||||
|
// 根据选择的部门ID,找到对应的部门信息
|
||||||
|
const findDept = (depts, deptId) => {
|
||||||
|
for (const dept of depts) {
|
||||||
|
if (dept.deptId === deptId) {
|
||||||
|
return dept;
|
||||||
|
}
|
||||||
|
if (dept.children && dept.children.length > 0) {
|
||||||
|
const found = findDept(dept.children, deptId);
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedDept = findDept(deptOptions.value, value);
|
||||||
|
if (selectedDept) {
|
||||||
|
basicsForm.value.deptName = selectedDept.deptName;
|
||||||
|
basicsForm.value.deptId = selectedDept.deptId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取详情数据
|
||||||
|
const getDetail = async (id) => {
|
||||||
|
try {
|
||||||
|
// 确保部门列表已加载
|
||||||
|
if (deptOptions.value.length === 0) {
|
||||||
|
await getDeptList();
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await getUnitArchive(id);
|
||||||
|
if (response.code === 200) {
|
||||||
|
const data = response.data;
|
||||||
|
// 填充表单数据
|
||||||
|
basicsForm.value = {
|
||||||
|
enterpriseType: data.unitType || '',
|
||||||
|
enterpriseName: data.unitName || '',
|
||||||
|
deptId: data.deptId || data.areaCode || '',
|
||||||
|
deptName: data.deptName || data.areaName || '',
|
||||||
|
creditCode: data.creditCode || '',
|
||||||
|
contactName: data.contactName || '',
|
||||||
|
contactPhone: data.contactPhone || ''
|
||||||
|
};
|
||||||
|
expandForm.value = {
|
||||||
|
enterpriseAddress: data.address || '',
|
||||||
|
remark: data.remark || ''
|
||||||
|
};
|
||||||
|
qualFileUrl.value = data.qualFileUrl || '';
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '获取详情失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取详情失败:', error);
|
||||||
|
ElMessage.error('获取详情失败,请稍后重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从路由参数中获取单位类型或单位ID
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const enterpriseType = router.currentRoute.value.query.enterpriseType;
|
// 先获取部门列表
|
||||||
if (enterpriseType) {
|
getDeptList();
|
||||||
|
|
||||||
|
const route = router.currentRoute.value;
|
||||||
|
const enterpriseType = route.query.enterpriseType;
|
||||||
|
const id = route.query.unitId;
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
// 编辑模式
|
||||||
|
isEdit.value = true;
|
||||||
|
unitId.value = id;
|
||||||
|
console.log(isEdit.value);
|
||||||
|
getDetail(id);
|
||||||
|
} else if (enterpriseType) {
|
||||||
|
// 新增模式,设置单位类型
|
||||||
basicsForm.value.enterpriseType = enterpriseType;
|
basicsForm.value.enterpriseType = enterpriseType;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 上传前验证
|
||||||
|
const handleBeforeUpload = (file) => {
|
||||||
|
const isValidType = ['pdf', 'jpg', 'jpeg', 'png'].includes(file.name.split('.').pop().toLowerCase());
|
||||||
|
const isLt10M = file.size / 1024 / 1024 < 10;
|
||||||
|
|
||||||
|
if (!isValidType) {
|
||||||
|
ElMessage.error('只能上传 PDF/JPG/PNG 格式的文件!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isLt10M) {
|
||||||
|
ElMessage.error('文件大小不能超过 10MB!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义文件上传
|
||||||
|
const handleFileUpload = async (options) => {
|
||||||
|
const { file } = options;
|
||||||
|
uploadLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await uploadFile(file);
|
||||||
|
if (response.code === 200) {
|
||||||
|
// 根据实际返回的数据结构获取文件URL
|
||||||
|
qualFileUrl.value = response.data?.url || response.data?.fileUrl || response.url || response.data;
|
||||||
|
ElMessage.success('文件上传成功');
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '文件上传失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('文件上传失败:', error);
|
||||||
|
ElMessage.error('文件上传失败,请稍后重试');
|
||||||
|
} finally {
|
||||||
|
uploadLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除文件
|
||||||
|
const handleRemoveFile = () => {
|
||||||
|
qualFileUrl.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
// 处理返回按钮点击事件
|
// 处理返回按钮点击事件
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
router.go(-1);
|
router.go(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 保存建档
|
||||||
|
const handleSave = async () => {
|
||||||
|
// 验证基础表单
|
||||||
|
if (!basicsFormRef.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await basicsFormRef.value.validate();
|
||||||
|
} catch (error) {
|
||||||
|
// 表单验证失败
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
submitLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建请求参数
|
||||||
|
const params = {
|
||||||
|
unitType: basicsForm.value.enterpriseType, // 单位类型:1=施工单位, 2=监理单位, 3=业主单位
|
||||||
|
unitName: basicsForm.value.enterpriseName, // 单位名称
|
||||||
|
deptName: basicsForm.value.deptName, // 所属区域名称(部门名称)
|
||||||
|
deptId: basicsForm.value.deptId, // 所属区域代码(部门ID)
|
||||||
|
creditCode: basicsForm.value.creditCode, // 统一社会信用代码
|
||||||
|
contactName: basicsForm.value.contactName, // 联系人
|
||||||
|
contactPhone: basicsForm.value.contactPhone, // 联系电话
|
||||||
|
address: expandForm.value.enterpriseAddress || '', // 单位地址
|
||||||
|
remark: expandForm.value.remark || '', // 备注
|
||||||
|
qualFileUrl: qualFileUrl.value || '', // 资质文件URL
|
||||||
|
// 以下字段根据实际情况设置,如果后端不需要可以删除
|
||||||
|
archiveStatus: '0', // 建档状态,可根据业务需求设置
|
||||||
|
status: '0', // 状态,可根据业务需求设置
|
||||||
|
delFlag: '0' // 删除标志,0=未删除
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果是编辑模式,添加 unitId
|
||||||
|
if (isEdit.value && unitId.value) {
|
||||||
|
params.unitId = unitId.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据是新增还是编辑调用不同的接口
|
||||||
|
const response = isEdit.value
|
||||||
|
? await updateUnitArchive(params)
|
||||||
|
: await addUnitArchive(params);
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(isEdit.value ? '编辑成功' : '单位建档成功,可前往创建账号');
|
||||||
|
// 保存成功后返回上一页
|
||||||
|
setTimeout(() => {
|
||||||
|
router.go(-1);
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '保存建档失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存建档失败:', error);
|
||||||
|
ElMessage.error('保存建档失败,请稍后重试');
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
@ -123,6 +373,13 @@ const handleBack = () => {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #1F2937;
|
||||||
|
}
|
||||||
|
|
||||||
.FormBox {
|
.FormBox {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -160,6 +417,12 @@ const handleBack = () => {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.uploaded-file {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ButtonBox {
|
.ButtonBox {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!-- 物业模块-单位与账号管理-列表页 -->
|
<!-- 物业模块-单位与账号管理-列表页 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="MainBox">
|
<div class="MainBox">
|
||||||
<el-tabs v-model="activeTab" class="mb-4">
|
<el-tabs v-model="activeTab" class="mb-4" @tab-change="handleTabChange">
|
||||||
<el-tab-pane label="施工单位" name="1"></el-tab-pane>
|
<el-tab-pane label="施工单位" name="1"></el-tab-pane>
|
||||||
<el-tab-pane label="监理单位" name="2"></el-tab-pane>
|
<el-tab-pane label="监理单位" name="2"></el-tab-pane>
|
||||||
<el-tab-pane label="业主单位" name="3"></el-tab-pane>
|
<el-tab-pane label="业主单位" name="3"></el-tab-pane>
|
||||||
|
|
@ -15,47 +15,54 @@
|
||||||
<el-button size="default">导出账号</el-button>
|
<el-button size="default">导出账号</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button size="default" class="float-right" icon="Refresh">刷新</el-button>
|
<el-button size="default" class="float-right" icon="Refresh" @click="handleRefresh">刷新</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form :model="queryForm" inline class="card-box mb-4">
|
<el-form :model="queryForm" inline class="card-box mb-4">
|
||||||
<el-form-item label="单位名称">
|
<el-form-item label="单位名称">
|
||||||
<el-input v-model="queryForm.name" placeholder="请输入单位名称"></el-input>
|
<el-input v-model="queryForm.unitName" placeholder="请输入单位名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属区域">
|
||||||
|
<el-input v-model="queryForm.areaName" placeholder="请输入所属区域"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
<el-select v-model="queryForm.status" placeholder="全部">
|
<el-select v-model="queryForm.status" placeholder="全部" clearable>
|
||||||
<el-option label="全部" value=""></el-option>
|
<el-option label="全部" value=""></el-option>
|
||||||
<el-option label="启用" value="enabled"></el-option>
|
<el-option label="启用" :value="0"></el-option>
|
||||||
<el-option label="禁用" value="disabled"></el-option>
|
<el-option label="禁用" :value="1"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button size="default">重置</el-button>
|
<el-button size="default" @click="handleReset">重置</el-button>
|
||||||
<el-button type="primary" size="default">查询</el-button>
|
<el-button type="primary" size="default" @click="handleQuery">查询</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="card-box">
|
<div class="card-box">
|
||||||
<el-table :data="tableData" >
|
<el-table v-loading="loading" :data="tableData" >
|
||||||
<el-table-column prop="name" label="单位名称"></el-table-column>
|
<el-table-column prop="unitName" label="单位名称"></el-table-column>
|
||||||
<el-table-column prop="type" label="单位类型"></el-table-column>
|
<el-table-column prop="unitType" label="单位类型">
|
||||||
<el-table-column prop="area" label="所属区域"></el-table-column>
|
<template #default="scope">
|
||||||
|
{{ getUnitTypeName(scope.row.unitType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="areaName" label="所属区域"></el-table-column>
|
||||||
<el-table-column prop="createTime" label="建档时间"></el-table-column>
|
<el-table-column prop="createTime" label="建档时间"></el-table-column>
|
||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="scope.row.status === '启用' ? 'success' : 'danger'">
|
<el-tag :type="(scope.row.status === 0 || scope.row.status === '0') ? 'success' : 'danger'">
|
||||||
{{ scope.row.status }}
|
{{ (scope.row.status === 0 || scope.row.status === '0') ? '启用' : '禁用' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="280">
|
<el-table-column label="操作" width="280">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" type="text" @click="handleAccountManagement(scope.row)">账号管理</el-button>
|
<el-button size="small" type="text" @click="handleAccountManagement(scope.row)">账号管理</el-button>
|
||||||
<el-button size="small" type="text">编辑</el-button>
|
<el-button size="small" type="text" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
<el-button size="small" type="text" :type="scope.row.status === '启用' ? 'danger' : 'success'">
|
<el-button size="small" type="text" :type="(scope.row.status === 0 || scope.row.status === '0') ? 'danger' : 'success'" @click="handleChangeStatus(scope.row)">
|
||||||
{{ scope.row.status === '启用' ? '禁用' : '启用' }}
|
{{ (scope.row.status === 0 || scope.row.status === '0') ? '禁用' : '启用' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" type="danger" link>删除</el-button>
|
<el-button size="small" type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -63,7 +70,7 @@
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ pageNum * pageSize }} 条记录,共 {{ total }} 条</span>
|
<span class="total-count">显示第 {{ (pageNum - 1) * pageSize + 1 }} 到 {{ pageNum * pageSize }} 条记录,共 {{ total }} 条</span>
|
||||||
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[5, 10, 20]"
|
||||||
:total="total" layout="prev, pager, next"></el-pagination>
|
:total="total" layout="prev, pager, next" @size-change="handleSizeChange" @current-change="handlePageChange"></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -71,68 +78,194 @@
|
||||||
<script setup name="Index">
|
<script setup name="Index">
|
||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { listUnitArchive, delUnitArchive, changeUnitArchiveStatus } from "@/api/unit";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const activeTab = ref("1"); // 当前选中的tab
|
const activeTab = ref("1"); // 当前选中的tab
|
||||||
|
const loading = ref(false); // 加载状态
|
||||||
|
|
||||||
// 查询表单数据
|
// 查询表单数据
|
||||||
const queryForm = ref({
|
const queryForm = ref({
|
||||||
name: "",
|
unitName: "",
|
||||||
|
areaName: "",
|
||||||
status: ""
|
status: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
// 表格数据
|
// 表格数据
|
||||||
const tableData = ref([
|
const tableData = ref([]);
|
||||||
{
|
|
||||||
name: "北京建设集团有限公司",
|
|
||||||
type: "施工单位",
|
|
||||||
area: "北京市朝阳区",
|
|
||||||
createTime: "2023-05-12 14:30",
|
|
||||||
status: "启用"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "上海监理咨询公司",
|
|
||||||
type: "监理单位",
|
|
||||||
area: "上海市浦东新区",
|
|
||||||
createTime: "2023-04-28 09:15",
|
|
||||||
status: "禁用"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "广州房地产开发有限公司",
|
|
||||||
type: "业主单位",
|
|
||||||
area: "广州市天河区",
|
|
||||||
createTime: "2023-03-22 16:45",
|
|
||||||
status: "启用"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "深圳智能科技有限公司",
|
|
||||||
type: "施工单位",
|
|
||||||
area: "深圳市南山区",
|
|
||||||
createTime: "2023-02-18 11:20",
|
|
||||||
status: "启用"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "杭州园林设计院",
|
|
||||||
type: "监理单位",
|
|
||||||
area: "杭州市西湖区",
|
|
||||||
createTime: "2023-01-30 13:50",
|
|
||||||
status: "禁用"
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
const pageNum = ref(1); // 当前页码
|
const pageNum = ref(1); // 当前页码
|
||||||
const pageSize = ref(5); // 每页显示条数
|
const pageSize = ref(10); // 每页显示条数
|
||||||
|
const total = ref(0); // 总记录数
|
||||||
|
|
||||||
const total = ref(20); // 总记录数
|
// 获取列表数据
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const params = {
|
||||||
|
unitType: parseInt(activeTab.value),
|
||||||
|
pageNum: pageNum.value,
|
||||||
|
pageSize: pageSize.value
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加查询条件
|
||||||
|
if (queryForm.value.unitName) {
|
||||||
|
params.unitName = queryForm.value.unitName;
|
||||||
|
}
|
||||||
|
if (queryForm.value.areaName) {
|
||||||
|
params.areaName = queryForm.value.areaName;
|
||||||
|
}
|
||||||
|
if (queryForm.value.status !== "" && queryForm.value.status !== null && queryForm.value.status !== undefined) {
|
||||||
|
params.status = queryForm.value.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await listUnitArchive(params);
|
||||||
|
if (response.code === 200) {
|
||||||
|
tableData.value = response.rows || response.data || [];
|
||||||
|
total.value = response.total || 0;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || "获取数据失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取列表数据失败:", error);
|
||||||
|
ElMessage.error("获取数据失败,请稍后重试");
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tab切换事件
|
||||||
|
const handleTabChange = () => {
|
||||||
|
pageNum.value = 1; // 切换tab时重置页码
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const handleQuery = () => {
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
queryForm.value = {
|
||||||
|
unitName: "",
|
||||||
|
areaName: "",
|
||||||
|
status: ""
|
||||||
|
};
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const handleRefresh = () => {
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 分页大小改变
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
|
pageSize.value = val;
|
||||||
|
pageNum.value = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页码改变
|
||||||
|
const handlePageChange = (val) => {
|
||||||
|
pageNum.value = val;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
// 跳转到新增单位建档
|
// 跳转到新增单位建档
|
||||||
const handleAddEnterprise = () => {
|
const handleAddEnterprise = () => {
|
||||||
console.log("新增单位建档",router);
|
console.log("新增单位建档", router);
|
||||||
router.push(`/Tenement/newEnterprise?enterpriseType=${activeTab.value}`);
|
router.push(`/Tenement/newEnterprise?enterpriseType=${activeTab.value}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 跳转到账号管理
|
// 跳转到账号管理
|
||||||
const handleAccountManagement = (row) => {
|
const handleAccountManagement = (row) => {
|
||||||
console.log("账号管理", row);
|
console.log("账号管理", row);
|
||||||
router.push(`/Tenement/accountManagement?enterpriseName=${row.name}`);
|
router.push(`/Tenement/accountManagement?enterpriseName=${row.unitName || row.name}&unitId=${row.unitId || row.id}&deptId=${row.deptId}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// 跳转到编辑单位建档
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
router.push(`/Tenement/newEnterprise?unitId=${row.unitId || row.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改单位档案状态
|
||||||
|
const handleChangeStatus = async (row) => {
|
||||||
|
const unitId = row.unitId || row.id;
|
||||||
|
const unitName = row.name || row.unitName || '该单位';
|
||||||
|
// 当前状态:0=启用,1=禁用
|
||||||
|
const currentStatus = row.status === 0 || row.status === '0' ? 0 : 1;
|
||||||
|
const newStatus = currentStatus === 0 ? 1 : 0;
|
||||||
|
const statusText = newStatus === 0 ? '启用' : '禁用';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await changeUnitArchiveStatus({
|
||||||
|
unitId: unitId,
|
||||||
|
status: newStatus
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success(`${statusText}成功`);
|
||||||
|
// 修改成功后刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || `${statusText}失败`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('修改状态失败:', error);
|
||||||
|
ElMessage.error(`${statusText}失败,请稍后重试`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除单位档案
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
const unitId = row.unitId || row.id;
|
||||||
|
const unitName = row.name || row.unitName || '该单位';
|
||||||
|
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
`确定要删除"${unitName}"吗?删除后无法恢复。`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
const response = await delUnitArchive(unitId);
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
// 删除成功后刷新列表
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(response.msg || '删除失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error);
|
||||||
|
ElMessage.error('删除失败,请稍后重试');
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据unitType获取单位类型名称
|
||||||
|
const getUnitTypeName = (unitType) => {
|
||||||
|
const typeMap = {
|
||||||
|
1: '施工单位',
|
||||||
|
2: '监理单位',
|
||||||
|
3: '业主单位'
|
||||||
|
};
|
||||||
|
return typeMap[unitType] || '未知类型';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时获取数据
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.MainBox {
|
.MainBox {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue