From 9715c8755d66b004eaee134e948b9d19c2be0981 Mon Sep 17 00:00:00 2001 From: fengerli <528575642@qq.com> Date: Sat, 5 Jul 2025 14:30:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=AE=A1=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=97=E8=A1=A8=EF=BC=8C=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- .env.production | 2 +- index.html | 2 +- package.json | 5 +- public/favicon.ico | Bin 8131 -> 0 bytes public/favicon.png | Bin 0 -> 19464 bytes src/api/equipmentManagement/device/index.ts | 58 +- src/assets/images/avatar.png | Bin 0 -> 1865 bytes src/assets/images/下载.png | Bin 0 -> 19464 bytes src/assets/logo/logo.png | Bin 8131 -> 19464 bytes src/layout/components/Navbar.vue | 45 +- src/layout/components/Sidebar/Logo.vue | 2 +- src/main.ts | 9 +- src/plugins/modal.ts | 2 +- src/utils/auth.ts | 5 + src/utils/request.ts | 38 +- src/views/customerManagement/index.vue | 17 +- .../equipmentManagement/deviceType/index.vue | 8 +- .../equipmentManagement/devices/index.vue | 581 ++++++++++++++---- src/views/index.vue | 142 ----- src/views/login.vue | 39 +- src/views/system/role/index.vue | 2 +- 22 files changed, 633 insertions(+), 326 deletions(-) delete mode 100644 public/favicon.ico create mode 100644 public/favicon.png create mode 100644 src/assets/images/avatar.png create mode 100644 src/assets/images/下载.png diff --git a/.env.development b/.env.development index 002785a..b492dee 100644 --- a/.env.development +++ b/.env.development @@ -1,5 +1,5 @@ # 页面标题 -VITE_APP_TITLE = RuoYi-Vue-Plus多租户管理系统11 +VITE_APP_TITLE = 物联网管理系统 # 开发环境配置 VITE_APP_ENV = 'development' diff --git a/.env.production b/.env.production index 1109bc6..c5b65c9 100644 --- a/.env.production +++ b/.env.production @@ -1,5 +1,5 @@ # 页面标题 -VITE_APP_TITLE = RuoYi-Vue-Plus多租户管理系统 +VITE_APP_TITLE = 物联网管理系统 # 生产环境配置 VITE_APP_ENV = 'production' diff --git a/index.html b/index.html index aa1c86d..47ca3f6 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - RuoYi-Vue-Plus多租户管理系统 + 物联网管理系统 + +
{{ useUserStore().roles[0] }}
- + - + @@ -122,22 +150,23 @@ - - + + - + - + @@ -151,9 +180,9 @@ :http-request="httpRequestImg" :file-list="fileList" :limit="1"> - + @@ -168,11 +197,73 @@ + + + + + + + + + + + + + +
+

请按照模板文件的格式准备需要导入的数据。

+

模板文件中的表头请勿修改,数据请从第二行开始填写。

+ 下载模板文件 +
+ + 选择文件开始导入 +
+
只能上传模板excel文件
+
+
+ 批量导入完成,共检测到 {{ importResult.total }} + 条数据,导入成功 {{ importResult.succeed }} 条,失败 {{ + importResult.errorSun }} 条。 +

>>> + 上传失败明细下载

+
+
+ +
+ + + + + + + + + + + @@ -182,6 +273,8 @@ import { deviceForm, deviceQuery, deviceVO } from '@/api/equipmentManagement/dev const { proxy } = getCurrentInstance() as ComponentInternalInstance; const deviceDist = ref(); import { to } from 'await-to-js'; +import request from "@/utils/request"; +import { getBearerToken } from '@/utils/auth' const loading = ref(true); const showSearch = ref(true); const dateRange = ref<[DateModelType, DateModelType]>(['', '']); @@ -194,7 +287,17 @@ const queryFormRef = ref(); const userFormRef = ref(); const formDialogRef = ref(); const deviceTypeOptions = ref([]); //设备类型 - +const fileList = ref() +const communicationModeInfo = ref(null); +const showMacField = ref(false); //MAC地址 +const showImeiField = ref(false); //mei地址 +const assignDialogVisible = ref(false); //分配客户 +const importDialogVisible = ref(false);//批量导入 +const batchAssignDialogVisible = ref(false) //批量分配客户 +const loadingIng = ref(false) +const assignCustomerId = ref(); //分配客户id +const batchAssignCustomerId = ref() //批量分配客户id +const customerList = ref() const dialog = reactive({ visible: false, title: '' @@ -207,7 +310,7 @@ const initFormData: deviceForm = { remark: '', id: '', deviceType: "", - image:'' + image: '' }; const initData: PageData = { @@ -229,12 +332,6 @@ const initData: PageData = { deviceType: [ { required: true, message: '请选择设备类型', trigger: 'blur' }, ], - deviceMac: [ - { required: true, message: '请输入设备MAC', trigger: 'blur' }, - ], - deviceImei: [ - { required: true, message: '请输入设备IMEI', trigger: 'blur' }, - ], } }; const data = reactive>(initData); @@ -256,9 +353,9 @@ const handleQuery = () => { }; /** 重置按钮操作 */ const resetQuery = () => { - queryParams.value.pageNum = 1; - getList(); - + queryFormRef.value?.resetFields(); + dateRange.value = ['', '']; + handleQuery() }; /** 删除按钮操作 */ @@ -275,13 +372,63 @@ const handleDelete = async (row?: deviceVO) => { return; } // 单行删除逻辑 - const [err] = await to(proxy?.$modal.confirm('是否确认删除"' + row.nickName + '"的数据项?') as any); + const [err] = await to(proxy?.$modal.confirm('是否确认删除"' + row.deviceName + '"的数据项?') as any); if (!err) { await api.deleteDevice([row.id]); await getList(); proxy?.$modal.msgSuccess('删除成功'); } }; +/** 导出按钮操作 */ +const handleExport = () => { + proxy?.download( + '/api/device/download', + { + ...queryParams.value + }, + `${new Date().getTime()}.xlsx`, + 'get' + ); +}; +// 解绑 +const handleUnbind = (row) => { + proxy?.$modal.confirm(`确定要解绑设备 ${row.deviceName} 吗?`, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + api.deviceUnbind(row).then(res => { + if (res.code === 0) { + proxy?.$modal.msgSuccess('解绑成功') + getList(); // 初始化列表数据 + } else { + proxy?.$modal.msgError(res.msg || '解绑失败') + } + }) + }).catch(() => { + + }) +}; +// 撤回 +const handleWithdraw = (row: any) => { + proxy?.$modal.confirm(`确定要从客户 ${row.customerName} 撤回设备 ${row.deviceName} 吗?`, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + api.withdrawDevice([row.id]).then(res => { + if (res.code === 0) { + proxy?.$modal.msgSuccess('撤回成功') + getList(); // 初始化列表数据 + } else { + proxy?.$modal.msgError(res.msg || '撤回失败') + } + }) + }).catch(() => { + proxy?.$modal.msgError('已取消撤回') + }) +} + /** 选择条数 */ const handleSelectionChange = (selection: deviceVO[]) => { @@ -295,6 +442,7 @@ const handleSelectionChange = (selection: deviceVO[]) => { const reset = () => { form.value = { ...initFormData }; userFormRef.value?.resetFields(); + fileList.value = [] }; /** 取消按钮 */ const cancel = () => { @@ -308,6 +456,9 @@ const handleAdd = async () => { dialog.visible = true; dialog.title = '新增设备'; form.value.password = initPassword.value.toString(); + // 新增时默认不显示 + showMacField.value = false; + showImeiField.value = false; }; /** 修改按钮操作 */ @@ -317,93 +468,163 @@ const handleUpdate = async (row?: deviceForm) => { dialog.title = '修改设备'; try { if (row) { - // 从行内按钮调用,直接使用行数据 Object.assign(form.value, row); + form.value.image = row.devicePic + // 编辑时根据已有值显示字段 + showMacField.value = !!row.deviceMac; + showImeiField.value = !!row.deviceImei; } else { const customerId = ids.value[0]; Object.assign(form.value, customerId); + form.value.image = customerId.devicePic //图片回显 + // 编辑时根据已有值显示字段 + showMacField.value = !!customerId.deviceMac; + showImeiField.value = !!customerId.deviceImei; + } + // 加载设备类型对应的通讯方式 + if (form.value.deviceType) { + await handleDeviceTypeChange(form.value.deviceType); } } catch (error) { dialog.visible = false; } }; - // 覆盖默认的上传行为,可以自定义上传的实现 - const httpRequestImg=(parm)=> { }; - const beforeUpload=(file)=> { - const isLt2M = file.size / 1024 / 1024 < 2; - const isJPG = file.type === "image/jpeg" || file.type === "image/png"; - if (!isJPG) { - ElMessage.warning("请上传jpg、png格式,大小不超过2M的照片"); - return false; +// 设备类型触发事件 +const handleDeviceTypeChange = async (deviceTypeId: string | number) => { + // 重置规则和显示状态 + rules.value.deviceMac = []; + rules.value.deviceImei = []; + showMacField.value = false; + showImeiField.value = false; + communicationModeInfo.value = null; + + // 编辑时如果有值,根据已有值确定显示哪个字段 + if (form.value.id) { + if (form.value.deviceMac) { + showMacField.value = true; + rules.value.deviceMac = [{ required: true, message: '请输入设备MAC', trigger: 'blur' }]; + } else if (form.value.deviceImei) { + showImeiField.value = true; + rules.value.deviceImei = [{ required: true, message: '请输入设备IMEI', trigger: 'blur' }]; + } + return; + } + // 新增或编辑时没有值,根据设备类型获取通讯方式 + try { + userFormRef.value?.clearValidate(['deviceMac', 'deviceImei']); + if (!deviceTypeId) { + return; + } + const res = await api.getCommunicationMode({ id: deviceTypeId }); + if (res.code === 0 && res.data) { + communicationModeInfo.value = res.data; + // 根据通讯方式确定显示哪个字段 + if (res.data.communicationMode === '1') { // 蓝牙设备 - 显示MAC + showMacField.value = true; + showImeiField.value = false; + rules.value.deviceMac = [{ required: true, message: '请输入设备MAC', trigger: 'blur' }]; + form.value.deviceImei = ''; // 清空IMEI + } else if (res.data.communicationMode === '0') { // 4G设备 - 显示IMEI + showMacField.value = false; + showImeiField.value = true; + rules.value.deviceImei = [{ required: true, message: '请输入设备IMEI', trigger: 'blur' }]; + form.value.deviceMac = ''; // 清空MAC } - if (!isLt2M) { - ElMessage.warning("大小不超过2M的照片片"); - return false; - } - return isJPG && isLt2M; - }; - // 文件上传状态改变时触发 - const fileUploadChange=(files, fileList)=> { - console.log(fileList, '5555'); - if (fileList.length > 0) { - form.value.image = fileList[0].raw; // 正确获取File对象 - // 调试:检查是否是真正的 File 对象 - console.log('File对象验证:', form.value.image); - } else { - form.value.image = null; - } - }; + } else { + proxy?.$modal.msgError(res.msg || '获取通讯方式失败'); + } + } catch (error) { + proxy?.$modal.msgError('获取通讯方式失败'); + } +}; + +// 覆盖默认的上传行为,可以自定义上传的实现 +const httpRequestImg = (parm) => { }; +const beforeUpload = (file) => { + const isLt2M = file.size / 1024 / 1024 < 2; + const isJPG = file.type === "image/jpeg" || file.type === "image/png"; + if (!isJPG) { + ElMessage.warning("请上传jpg、png格式,大小不超过2M的照片"); + return false; + } + if (!isLt2M) { + ElMessage.warning("大小不超过2M的照片片"); + return false; + } + return isJPG && isLt2M; +}; +// 文件上传状态改变时触发 +const fileUploadChange = (files, fileList) => { + console.log(fileList, '5555'); + if (fileList.length > 0) { + form.value.image = fileList[0].raw; // 正确获取File对象 + // 调试:检查是否是真正的 File 对象 + console.log('File对象验证:', form.value.image); + } else { + form.value.image = null; + } +}; /** 提交按钮 */ -const submitForm = () => { - userFormRef.value?.validate(async (valid: boolean) => { - if (valid) { - // try { - // const formData = new FormData(); - // // 处理图片字段 - // if (this.form.image instanceof File) { - // formData.append('file', this.form.image); - // } else if (this.form.image && typeof this.form.image === 'string') { - // // 编辑时未修改图片,传递原图片URL - // formData.append('imageUrl', this.form.image); - // } - // // 添加其他必要字段 - // const fields = ['id', 'deviceName', 'deviceType', 'remark']; - // fields.forEach(key => { - // if (this.form[key] !== undefined && this.form[key] !== null) { - // formData.append(key, this.form[key]); - // } - // }); - // // 根据通讯方式,有条件地添加deviceMac或deviceImei - // if (this.form.deviceMac) { - // formData.append('deviceMac', this.form.deviceMac) - // } - // if (this.form.deviceImei) { - // formData.append('deviceImei', this.form.deviceImei) - // } - // // 根据操作类型设置URL和方法 - // const isAdd = this.crud.status.add; - // const res = await request({ // 使用 await 等待结果 - // url: isAdd ? '/api/device/add' : '/api/device/update', - // method: isAdd ? 'post' : 'put', - // data: formData, - // headers: { - // 'Content-Type': 'multipart/form-data' - // } - // }); - // if (res.code == 0) { - // this.$message.success(isAdd ? '添加成功' : '编辑成功'); - // this.crud.cancelCU(); - // this.crud.toQuery(); - // } else { - // this.$message.warning(res.msg); - // } - // } catch (err) { - // this.$message.warning('操作失败'); - // console.error(err); - // } +const submitForm = async () => { + try { + const valid = await userFormRef.value?.validate(); + if (!valid) return; + loadingIng.value = true; + const formData = new FormData(); + // 处理图片字段 + if (form.value.image instanceof File) { + formData.append('file', form.value.image); + } else if (form.value.image && typeof form.value.image === 'string') { + // 如果是URL且需要转换为二进制 + const blob = await urlToBlob(form.value.image); + formData.append('file', blob, 'image.jpg'); // 添加文件名 } - }); + // 添加其他必要字段 + const fields = ['id', 'deviceName', 'deviceType', 'remark']; + fields.forEach(key => { + if (form.value[key] !== undefined && form.value[key] !== null) { + formData.append(key, String(form.value[key])); // 确保所有值都转为字符串 + } + }); + // 根据通讯方式,有条件地添加deviceMac或deviceImei + if (form.value.deviceMac) { + formData.append('deviceMac', form.value.deviceMac); + } + if (form.value.deviceImei) { + formData.append('deviceImei', form.value.deviceImei); + } + // 根据操作类型设置URL和方法 + const isAdd = !form.value.id; // 注意这里逻辑反了,应该是没有id时是新增 + const res = await request({ + url: isAdd ? '/api/device/add' : '/api/device/update', + method: isAdd ? 'post' : 'put', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }); + if (res.code == 0) { + + proxy?.$modal.msgSuccess('操作成功'); + dialog.visible = false; + loadingIng.value = false; + await getList(); + } else { + proxy?.$modal.msgWarning(res.msg) + loadingIng.value = false; + } + } catch (err) { + console.error(err); + loadingIng.value = false; + } +}; + +// URL转Blob的方法函数 +const urlToBlob = async (url: string): Promise => { + const response = await fetch(url); + if (!response.ok) throw new Error('图片加载失败'); + return await response.blob(); }; /** @@ -432,9 +653,161 @@ const getDeviceType = () => { }) }; +// 客户下拉框 +const getAllCustomerAll = () => { + api.userAllCustomerAll().then(res => { + if (res.code == 0) { + customerList.value = res.data + } + }) +}; +// 分配客户 +const assignRow = ref() +const handleAssign = (row: any) => { + getAllCustomerAll() + assignDialogVisible.value = true + assignRow.value = row + assignCustomerId.value = row.customerId +} +const handleAssignConfirm = () => { + if (!assignCustomerId.value) { + return proxy?.$modal.msgError('请选择客户') + } + loadingIng.value = true; + // 这里调用分配API + let data = { + customerId: assignCustomerId.value, + deviceIds: [assignRow.value.id] + } + api.deviceAssignCustomer(data).then((res) => { + if (res.code == 0) { + loadingIng.value = false; + const customer = customerList.value.find(c => c.id === assignCustomerId.value) + const customerName = customer ? customer.nickName : `ID: ${assignCustomerId.value}` + getList(); + assignDialogVisible.value = false + return proxy?.$modal.msgSuccess(`设备已分配给客户: ${customerName}`) + + } else { + loadingIng.value = false; + } + }) +}; +const importUpload = ref() +const importResult = ref() +const handleBatchImport = () => { + importDialogVisible.value = true + importResult.value = { + isShow: false, + total: 0, + succeed: 0, + errorSun: 0, + link: '' + } + nextTick(() => { + if (importUpload.value) { + importUpload.value.clearFiles() + } + }) +}; +const downloadTemplate = () => { + // 这里可用 window.open 或 a 标签下载模板 + const link = document.createElement('a'); + link.href = 'http://fuyuanshen.com:81/images/excel/equipmenttemplate.xlsx'; + link.download = '设备数据导入模板.xlsx'; // 可选:指定下载文件名 + link.style.display = 'none'; // 隐藏标签 + document.body.appendChild(link); + link.click(); // 触发下载 + document.body.removeChild(link); // 移除标签 +}; +const beforeImportUpload = (file: any) => { + const isLt5M = file.size / 1024 / 1024 < 5 + if (!isLt5M) { + proxy?.$modal.msgError('上传文件大小不能超过 5MB!') + } + return isLt5M +}; + +//添加tokenf方法head_upload 直接返回 getBearerToken() +const head_upload = () => getBearerToken(); +const handleImportSuccess = (response: any) => { + if (response.code === 0) { + importResult.value.isShow = true + if (response.data) { + importResult.value.succeed = response.data.successCount || 0 + importResult.value.errorSun = response.data.failureCount || 0 + importResult.value.total = importResult.value.succeed + importResult.value.errorSun + importResult.value.link = response.data.errorExcelUrl || '' + } + getList(); // 初始化列表数据 + } else { + proxy?.$modal.msgError(response.msg || '导入失败') + } +}; +const handleImportError = () => { + proxy?.$modal.msgError('导入失败') +}; +// 批量分配客户 +const handleBatchAssign = () => { + batchAssignDialogVisible.value = true + getAllCustomerAll() +}; +// 批量分配客户确定 +const handleBatchAssignConfirm = () => { + if (!batchAssignCustomerId.value) { + return proxy?.$modal.msgError('请选择客户') + } + // 这里可以调用批量分配API,传递 crud.selections 和 batchAssignCustomerId + // 提取选中设备的 ID 数组 + const selectedIds = ids.value.map((item) => item.id) + // 构造请求数据 + const data = { + customerId: batchAssignCustomerId.value, // 目标客户ID + deviceIds: selectedIds // 选中的设备ID数组 + } + api.deviceAssignCustomer(data).then((res) => { + if (res.code == 0) { + batchAssignDialogVisible.value = false + getList(); + return proxy?.$modal.msgSuccess(`分配成功`) + } + }) +}; + + + +watch(() => form.value.deviceType, (newVal) => { + if (dialog.title === '新增设备') { // Only for add form + handleDeviceTypeChange(newVal); + } +}); onMounted(() => { getList(); // 初始化列表数据 getDeviceType() }); + + diff --git a/src/views/index.vue b/src/views/index.vue index e5c35a6..03c08f4 100644 --- a/src/views/index.vue +++ b/src/views/index.vue @@ -2,92 +2,8 @@
-

RuoYi-Vue-Plus多租户管理系统

-

- RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 分布式集群 场景升级(不兼容原框架) -
- * 前端开发框架 Vue3、TS、Element Plus
- * 后端开发框架 Spring Boot
- * 容器框架 Undertow 基于 Netty 的高性能容器
- * 权限认证框架 Sa-Token 支持多终端认证系统
- * 关系数据库 MySQL 适配 8.X 最低 5.7
- * 缓存数据库 Redis 适配 6.X 最低 4.X
- * 数据库框架 Mybatis-Plus 快速 CRUD 增加开发效率
- * 数据库框架 p6spy 更强劲的 SQL 分析
- * 多数据源框架 dynamic-datasource 支持主从与多种类数据库异构
- * 序列化框架 Jackson 统一使用 jackson 高效可靠
- * Redis客户端 Redisson 性能强劲、API丰富
- * 分布式限流 Redisson 全局、请求IP、集群ID 多种限流
- * 分布式锁 Lock4j 注解锁、工具锁 多种多样
- * 分布式幂等 Lock4j 基于分布式锁实现
- * 分布式链路追踪 SkyWalking 支持链路追踪、网格分析、度量聚合、可视化
- * 分布式任务调度 SnailJob 高性能 高可靠 易扩展
- * 文件存储 Minio 本地存储
- * 文件存储 七牛、阿里、腾讯 云存储
- * 监控框架 SpringBoot-Admin 全方位服务监控
- * 校验框架 Validation 增强接口安全性 严谨性
- * Excel框架 FastExcel(原Alibaba EasyExcel) 性能优异 扩展性强
- * 文档框架 SpringDoc、javadoc 无注解零入侵基于java注释
- * 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性
- * 代码生成器 适配MP、SpringDoc规范化代码 一键生成前后端代码
- * 部署方式 Docker 容器编排 一键部署业务集群
- * 国际化 SpringMessage Spring标准国际化方案
-

-

当前版本: v5.4.0

-

- ¥免费开源 -

-

- 访问码云 - 访问GitHub - 更新日志 -

- -

RuoYi-Cloud-Plus多租户微服务管理系统

-

- RuoYi-Cloud-Plus 微服务通用权限管理系统 重写 RuoYi-Cloud 全方位升级(不兼容原框架) -
- * 前端开发框架 Vue3、TS、Element UI
- * 后端开发框架 Spring Boot
- * 微服务开发框架 Spring Cloud、Spring Cloud Alibaba
- * 容器框架 Undertow 基于 XNIO 的高性能容器
- * 权限认证框架 Sa-Token、Jwt 支持多终端认证系统
- * 关系数据库 MySQL 适配 8.X 最低 5.7
- * 关系数据库 Oracle 适配 11g 12c
- * 关系数据库 PostgreSQL 适配 13 14
- * 关系数据库 SQLServer 适配 2017 2019
- * 缓存数据库 Redis 适配 6.X 最低 5.X
- * 分布式注册中心 Alibaba Nacos 采用2.X 基于GRPC通信高性能
- * 分布式配置中心 Alibaba Nacos 采用2.X 基于GRPC通信高性能
- * 服务网关 Spring Cloud Gateway 响应式高性能网关
- * 负载均衡 Spring Cloud Loadbalancer 负载均衡处理
- * RPC远程调用 Apache Dubbo 原生态使用体验、高性能
- * 分布式限流熔断 Alibaba Sentinel 无侵入、高扩展
- * 分布式事务 Alibaba Seata 无侵入、高扩展 支持 四种模式
- * 分布式消息队列 Apache Kafka 高性能高速度
- * 分布式消息队列 Apache RocketMQ 高可用功能多样
- * 分布式消息队列 RabbitMQ 支持各种扩展插件功能多样性
- * 分布式搜索引擎 ElasticSearch 业界知名
- * 分布式链路追踪 Apache SkyWalking 链路追踪、网格分析、度量聚合、可视化
- * 分布式日志中心 ELK 业界成熟解决方案
- * 分布式监控 Prometheus、Grafana 全方位性能监控
- * 其余与 Vue 版本一致
-

-

当前版本: v2.4.0

-

- ¥免费开源 -

-

- 访问码云 - 访问GitHub - 更新日志 -

@@ -102,64 +18,6 @@ const goTarget = (url: string) => { diff --git a/src/views/login.vue b/src/views/login.vue index f641549..1f554d5 100644 --- a/src/views/login.vue +++ b/src/views/login.vue @@ -6,44 +6,35 @@
- - + + - + - + - + - {{ proxy.$t('login.rememberPassword') }} + {{ proxy.$t('login.login') }} @@ -71,10 +62,6 @@ - - @@ -261,8 +248,10 @@ onMounted(() => { width: 400px; padding: 25px 25px 5px 25px; z-index: 1; + .el-input { height: 40px; + input { height: 40px; } diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index c6d83b4..012a1c7 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -49,7 +49,7 @@ 删除 - 导出 + 导出