1
0
forked from dyf/dyf-vue-ui

Compare commits

...

8 Commits

12 changed files with 142 additions and 80 deletions

View File

@ -5,7 +5,7 @@ VITE_APP_TITLE = 物联网管理系统
VITE_APP_ENV = 'development' VITE_APP_ENV = 'development'
# 开发环境 # 开发环境
VITE_APP_BASE_API = 'http://192.168.2.23:8001' VITE_APP_BASE_API = 'http://192.168.2.23:8000'
# 应用访问路径 例如使用前缀 /admin/ # 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/' VITE_APP_CONTEXT_PATH = '/'

View File

@ -2,10 +2,10 @@
VITE_APP_TITLE = 物联网管理系统 VITE_APP_TITLE = 物联网管理系统
# 生产环境配置 # 生产环境配置
VITE_APP_ENV = 'production' VITE_APP_ENV = 'https://fuyuanshen.com/backend'
# 应用访问路径 例如使用前缀 /admin/ # 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/' VITE_APP_CONTEXT_PATH = '/sys/'
# 监控地址 # 监控地址
VITE_APP_MONITOR_ADMIN = '/admin/applications' VITE_APP_MONITOR_ADMIN = '/admin/applications'
@ -14,7 +14,7 @@ VITE_APP_MONITOR_ADMIN = '/admin/applications'
VITE_APP_SNAILJOB_ADMIN = '/snail-job' VITE_APP_SNAILJOB_ADMIN = '/snail-job'
# 生产环境 # 生产环境
VITE_APP_BASE_API = '/prod-api' VITE_APP_BASE_API = '/backend'
# 是否在打包时开启压缩,支持 gzip 和 brotli # 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip VITE_BUILD_COMPRESS = gzip

View File

@ -29,55 +29,4 @@ npm run dev
npm run build:prod npm run build:prod
# 前端访问地址 http://localhost:80 # 前端访问地址 http://localhost:80
```
## 本框架与RuoYi的业务差异
| 业务 | 功能说明 | 本框架 | RuoYi |
| ------------ | ------------------------------------------------------------- | ------ | ----------------------------- |
| 租户管理 | 系统内租户的管理 如:租户套餐、过期时间、用户数量、企业信息等 | 支持 | 无 |
| 租户套餐管理 | 系统内租户所能使用的套餐管理 如:套餐内所包含的菜单等 | 支持 | 无 |
| 用户管理 | 用户的管理配置 如:新增用户、分配用户所属部门、角色、岗位等 | 支持 | 支持 |
| 部门管理 | 配置系统组织机构(公司、部门、小组) 树结构展现支持数据权限 | 支持 | 支持 |
| 岗位管理 | 配置系统用户所属担任职务 | 支持 | 支持 |
| 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等 | 支持 | 支持 |
| 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 | 支持 | 支持 |
| 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | 支持 | 支持 |
| 参数管理 | 对系统动态配置常用参数 | 支持 | 支持 |
| 通知公告 | 系统通知公告信息发布维护 | 支持 | 支持 |
| 操作日志 | 系统正常操作日志记录和查询 系统异常信息日志记录和查询 | 支持 | 支持 |
| 登录日志 | 系统登录日志记录查询包含登录异常 | 支持 | 支持 |
| 文件管理 | 系统文件展示、上传、下载、删除等管理 | 支持 | 无 |
| 文件配置管理 | 系统文件上传、下载所需要的配置信息动态添加、修改、删除等管理 | 支持 | 无 |
| 在线用户管理 | 已登录系统的在线用户信息监控与强制踢出操作 | 支持 | 支持 |
| 定时任务 | 运行报表、任务管理(添加、修改、删除)、日志管理、执行器管理等 | 支持 | 仅支持任务与日志管理 |
| 代码生成 | 多数据源前后端代码的生成java、html、xml、sql支持CRUD下载 | 支持 | 仅支持单数据源 |
| 系统接口 | 根据业务代码自动生成相关的api接口文档 | 支持 | 支持 |
| 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等 | 支持 | 仅支持单机CPU、内存、磁盘监控 |
| 缓存监控 | 对系统的缓存信息查询,命令统计等。 | 支持 | 支持 |
| 在线构建器 | 拖动表单元素生成相应的HTML代码。 | 支持 | 支持 |
| 使用案例 | 系统的一些功能案例 | 支持 | 不支持 |
## 演示图例
| | |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| ![输入图片说明](https://foruda.gitee.com/images/1680077524361362822/270bb429_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077619939771291/989bf9b6_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680077681751513929/1c27c5bd_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077721559267315/74d63e23_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680077765638904515/1b75d4a6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078026375951297/eded7a4b_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078237104531207/0eb1b6a7_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078254306078709/5931e22f_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078287971528493/0b9af60a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078308138770249/8d3b6696_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078352553634393/db5ef880_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078378238393374/601e4357_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078414983206024/2aae27c1_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078446738419874/ecce7d59_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078475971341775/149e8634_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078491666717143/3fadece7_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078558863188826/fb8ced2a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078574561685461/ae68a0b2_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078594932772013/9d8bfec6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078626493093532/fcfe4ff6_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078643608812515/0295bd4f_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078685196286463/d7612c81_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078703877318597/56fce0bc_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078716586545643/b6dbd68f_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078734103217688/eb1e6aa6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078759131415480/73c525d8_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078779416197879/75e3ed02_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078802329118061/77e10915_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078893627848351/34a1c342_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078928175016986/f126ec4a_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078941718318363/b68a0f72_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078963175518631/3bb769a1_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078982294090567/b31c343d_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079000642440444/77ca82a9_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680079020995074177/03b7d52e_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079039367822173/76811806_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680079274333484664/4dfdc7c0_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079290467458224/d6715fcf_1766278.png '屏幕截图') |

View File

@ -68,6 +68,7 @@
"globals": "16.0.0", "globals": "16.0.0",
"prettier": "3.5.2", "prettier": "3.5.2",
"sass": "1.87.0", "sass": "1.87.0",
"terser": "^5.43.1",
"typescript": "~5.8.3", "typescript": "~5.8.3",
"unocss": "66.0.0", "unocss": "66.0.0",
"unplugin-auto-import": "19.1.2", "unplugin-auto-import": "19.1.2",

View File

@ -4,5 +4,44 @@ export interface deviceQuery extends PageQuery {
deviceImei: string; deviceImei: string;
deviceType: string; deviceType: string;
deviceStatus: string; deviceStatus: string;
bluetoothName?: string; // 蓝牙名称查询字段
}
export interface deviceForm {
id?: string | number;
deviceName: string;
deviceMac?: string;
deviceImei?: string;
deviceType: string;
devicePic?: string;
image?: string | File;
remark?: string;
password?: string;
customerId?: string | number;
bluetoothName?: string; // 蓝牙名称字段
}
export interface deviceVO {
id: string | number;
deviceName: string;
deviceMac?: string;
deviceImei?: string;
deviceType: string;
devicePic?: string;
deviceStatus: number;
bindingStatus: number;
remark?: string;
createTime?: string;
createByName?: string;
customerName?: string;
customerId?: string | number;
typeName?: string;
bluetoothName?: string; // 蓝牙名称字段
}
export interface deviceTypeOption {
id: string | number;
typeName: string;
value: string | number;
communicationMode?: string;
} }

View File

@ -20,7 +20,7 @@
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<!-- <img :src="userStore.avatar" class="user-avatar" /> --> <!-- <img :src="userStore.avatar" class="user-avatar" /> -->
<img src="@/assets/images/avatar.png" class="user-avatar" /> <img src="@/assets/images/avatar.png" class="user-avatar" />
<div style="margin-left: 10px;">{{ useUserStore().roles[0] }}</div> <div style="margin-left: 10px;">{{ useUserStore().nickname }}</div>
<el-icon><caret-bottom /></el-icon> <el-icon><caret-bottom /></el-icon>
</div> </div>
<template #dropdown> <template #dropdown>
@ -61,7 +61,7 @@ const newNotice = ref(<number>0);
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const userId = ref(userStore.userId); const userId = ref(userStore.userId);
console.log(useUserStore().roles[0], 'userStoreuserStoreuserStore'); // console.log(useUserStore(), 'userStoreuserStoreuserStore');
const companyName = ref(undefined); const companyName = ref(undefined);
@ -82,7 +82,7 @@ const dynamicTenantEvent = async (tenantId: string) => {
if (companyName.value != null && companyName.value !== '') { if (companyName.value != null && companyName.value !== '') {
await dynamicTenant(tenantId); await dynamicTenant(tenantId);
dynamic.value = true; dynamic.value = true;
await proxy?.$router.push('/'); await router.push('/');
await proxy?.$tab.closeAllPage(); await proxy?.$tab.closeAllPage();
await proxy?.$tab.refreshPage(); await proxy?.$tab.refreshPage();
} }
@ -91,7 +91,7 @@ const dynamicTenantEvent = async (tenantId: string) => {
const dynamicClearEvent = async () => { const dynamicClearEvent = async () => {
await dynamicClear(); await dynamicClear();
dynamic.value = false; dynamic.value = false;
await proxy?.$router.push('/'); await router.push('/');
await proxy?.$tab.closeAllPage(); await proxy?.$tab.closeAllPage();
await proxy?.$tab.refreshPage(); await proxy?.$tab.refreshPage();
}; };

View File

@ -30,14 +30,14 @@ const processResponse = async (res: any) => {
} }
ElMessage.success(res.msg); ElMessage.success(res.msg);
setTimeout(() => { setTimeout(() => {
location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; location.href = (import.meta.env.VITE_APP_CONTEXT_PATH || '/') + 'index';
}, 2000); }, 2000);
}; };
const handleError = (error: any) => { const handleError = (error: any) => {
ElMessage.error(error.message); ElMessage.error(error.message);
setTimeout(() => { setTimeout(() => {
location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; location.href = (import.meta.env.VITE_APP_CONTEXT_PATH || '/') + 'index';
}, 2000); }, 2000);
}; };

View File

@ -100,7 +100,7 @@ export const dynamicRoutes: RouteRecordRaw[] = [
* 创建路由 * 创建路由
*/ */
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH), history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH || '/'),
routes: constantRoutes, routes: constantRoutes,
// 刷新时,滚动条位置还原 // 刷新时,滚动条位置还原
scrollBehavior(to, from, savedPosition) { scrollBehavior(to, from, savedPosition) {

View File

@ -137,10 +137,10 @@ const handleStatusChange = (row: any) => {
getList(); getList();
} }
}).catch(() => { }).catch(() => {
row.status = !row.status getList();
}) })
}).catch(() => { }).catch(() => {
row.status = !row.status getList();
}) })
}; };
onMounted(() => { onMounted(() => {

View File

@ -58,6 +58,8 @@ const queryParams = reactive({
deviceImei: '' deviceImei: ''
}) })
function openDialog(row: OperLogForm) { function openDialog(row: OperLogForm) {
console.log(row,'roe11');
info.value = row; info.value = row;
open.value = true; open.value = true;
getList(); getList();

View File

@ -90,6 +90,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="deviceMac" label="设备MAC" /> <el-table-column prop="deviceMac" label="设备MAC" />
<el-table-column prop="bluetoothName" label="蓝牙名称" />
<el-table-column prop="deviceImei" label="设备IMEI" /> <el-table-column prop="deviceImei" label="设备IMEI" />
<el-table-column prop="typeName" label="设备类型" /> <el-table-column prop="typeName" label="设备类型" />
<el-table-column prop="bindingStatus" label="绑定状态"> <el-table-column prop="bindingStatus" label="绑定状态">
@ -112,22 +113,21 @@
<el-table-column label="操作" fixed="right" width="280" class-name="small-padding fixed-width"> <el-table-column label="操作" fixed="right" width="280" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip v-if="scope.row.id !== 1" content="修改" placement="top"> <el-tooltip v-if="scope.row.id !== 1 && scope.row.deviceStatus == 1" content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip v-if="scope.row.id !== 1" content="删除" placement="top"> <el-tooltip v-if="scope.row.id !== 1" content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button> <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip :disabled="scope.row.deviceStatus === 0" content="分配" placement="top"> <el-tooltip v-if="scope.row.deviceStatus == 1 && !scope.row.customerName" content="分配" placement="top">
<el-button link type="primary" icon="User" @click="handleAssign(scope.row)"></el-button> <el-button link type="primary" icon="User" @click="handleAssign(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip v-if="scope.row.customerName" :disabled="scope.row.deviceStatus === 0" content="撤回" <el-tooltip v-if="scope.row.customerName && scope.row.deviceStatus == 1" content="撤回" placement="top">
placement="top">
<el-button link type="primary" icon="UploadFilled" @click="handleWithdraw(scope.row)"></el-button> <el-button link type="primary" icon="UploadFilled" @click="handleWithdraw(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip v-if="scope.row.bindingStatus == 1" :disabled="scope.row.deviceStatus === 0" content="解绑" <el-tooltip v-if="scope.row.bindingStatus == 1" :disabled="scope.row.deviceStatus === 0" content="解绑"
placement="top"> placement="top">
<el-button link type="primary" icon="UploadFilled" @click="handleUnbind(scope.row)"></el-button> <el-button link type="primary" icon="Refresh" @click="handleUnbind(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
@ -166,6 +166,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row v-if="showMacField">
<el-col :span="24">
<el-form-item label="蓝牙名称" prop="bluetoothName">
<el-input v-model="form.bluetoothName" placeholder="请输入蓝牙名称" />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="showImeiField"> <el-row v-if="showImeiField">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="设备IMEI" prop="deviceImei"> <el-form-item label="设备IMEI" prop="deviceImei">
@ -269,7 +276,7 @@
<script setup name="User" lang="ts"> <script setup name="User" lang="ts">
import api from '@/api/equipmentManagement/device/index'; import api from '@/api/equipmentManagement/device/index';
import { deviceForm, deviceQuery, deviceVO } from '@/api/equipmentManagement/device/types'; import { deviceForm, deviceQuery, deviceVO, deviceTypeOption } from '@/api/equipmentManagement/device/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const deviceDist = ref<deviceVO[]>(); const deviceDist = ref<deviceVO[]>();
import { to } from 'await-to-js'; import { to } from 'await-to-js';
@ -278,7 +285,7 @@ import { getBearerToken } from '@/utils/auth'
const loading = ref(true); const loading = ref(true);
const showSearch = ref(true); const showSearch = ref(true);
const dateRange = ref<[DateModelType, DateModelType]>(['', '']); const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
const ids = ref<Array<number | string>>([]); const ids = ref<deviceVO[]>([]);
const single = ref(true); const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
@ -310,7 +317,8 @@ const initFormData: deviceForm = {
remark: '', remark: '',
id: '', id: '',
deviceType: "", deviceType: "",
image: '' image: '',
bluetoothName: '' // 蓝牙名称字段
}; };
const initData: PageData<deviceForm, deviceQuery> = { const initData: PageData<deviceForm, deviceQuery> = {
@ -334,8 +342,8 @@ const initData: PageData<deviceForm, deviceQuery> = {
], ],
} }
}; };
const data = reactive<PageData<deviceVO, deviceQuery>>(initData); const data = reactive<PageData<deviceForm, deviceQuery>>(initData);
const { queryParams, form, rules } = toRefs<PageData<deviceVO, deviceQuery>>(data); const { queryParams, form, rules } = toRefs<PageData<deviceForm, deviceQuery>>(data);
/** 查询设备列表 */ /** 查询设备列表 */
const getList = async () => { const getList = async () => {
loading.value = true; loading.value = true;
@ -363,7 +371,7 @@ const handleDelete = async (row?: deviceVO) => {
// 批量删除逻辑 // 批量删除逻辑
let arrey = ids.value.map((item) => item.id); let arrey = ids.value.map((item) => item.id);
if (!row) { if (!row) {
const [err] = await to(proxy?.$modal.confirm(`是否确认删除选中的 ${ids.value.length} 条数据?`) as any); const [err] = await to(proxy?.$modal.confirm(`是否确认删除选中的 ${ids.value.length} 条数据?`));
if (!err) { if (!err) {
await api.deleteDevice(arrey); await api.deleteDevice(arrey);
await getList(); await getList();
@ -372,7 +380,7 @@ const handleDelete = async (row?: deviceVO) => {
return; return;
} }
// 单行删除逻辑 // 单行删除逻辑
const [err] = await to(proxy?.$modal.confirm('是否确认删除"' + row.deviceName + '"的数据项?') as any); const [err] = await to(proxy?.$modal.confirm('是否确认删除"' + row.deviceName + '"的数据项?'));
if (!err) { if (!err) {
await api.deleteDevice([row.id]); await api.deleteDevice([row.id]);
await getList(); await getList();
@ -459,6 +467,8 @@ const handleAdd = async () => {
// 新增时默认不显示 // 新增时默认不显示
showMacField.value = false; showMacField.value = false;
showImeiField.value = false; showImeiField.value = false;
// 每次打开弹框时获取最新的设备类型数据
getDeviceType();
}; };
/** 修改按钮操作 */ /** 修改按钮操作 */
@ -466,6 +476,8 @@ const handleUpdate = async (row?: deviceForm) => {
reset(); reset();
dialog.visible = true; dialog.visible = true;
dialog.title = '修改设备'; dialog.title = '修改设备';
// 每次打开弹框时获取最新的设备类型数据
getDeviceType();
try { try {
if (row) { if (row) {
Object.assign(form.value, row); Object.assign(form.value, row);
@ -539,7 +551,9 @@ const handleDeviceTypeChange = async (deviceTypeId: string | number) => {
}; };
// 覆盖默认的上传行为,可以自定义上传的实现 // 覆盖默认的上传行为,可以自定义上传的实现
const httpRequestImg = (parm) => { }; const httpRequestImg = (parm): Promise<any> => {
return Promise.resolve();
};
const beforeUpload = (file) => { const beforeUpload = (file) => {
const isLt2M = file.size / 1024 / 1024 < 2; const isLt2M = file.size / 1024 / 1024 < 2;
const isJPG = file.type === "image/jpeg" || file.type === "image/png"; const isJPG = file.type === "image/jpeg" || file.type === "image/png";
@ -594,6 +608,10 @@ const submitForm = async () => {
if (form.value.deviceImei) { if (form.value.deviceImei) {
formData.append('deviceImei', form.value.deviceImei); formData.append('deviceImei', form.value.deviceImei);
} }
// 添加蓝牙名称字段(仅蓝牙设备)
if (form.value.bluetoothName) {
formData.append('bluetoothName', form.value.bluetoothName);
}
// 根据操作类型设置URL和方法 // 根据操作类型设置URL和方法
const isAdd = !form.value.id; // 注意这里逻辑反了应该是没有id时是新增 const isAdd = !form.value.id; // 注意这里逻辑反了应该是没有id时是新增
const res = await request({ const res = await request({

View File

@ -5,11 +5,22 @@ import path from 'path';
export default defineConfig(({ mode, command }) => { export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd()); const env = loadEnv(mode, process.cwd());
// 参考eladmin-web的部署方式使用相对路径
let basePath = '/';
if (mode === 'production') {
// 生产环境:如果设置了上下文路径则使用,否则使用相对路径
basePath = env.VITE_APP_CONTEXT_PATH || './';
} else {
// 开发环境:使用上下文路径或默认根路径
basePath = env.VITE_APP_CONTEXT_PATH || '/';
}
return { return {
// 部署生产环境和开发环境下的URL。 // 部署生产环境和开发环境下的URL。
// 默认情况下vite 会假设你的应用是被部署在一个域名的根路径上 // 默认情况下vite 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
base: env.VITE_APP_CONTEXT_PATH, base: basePath,
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, './src') '@': path.resolve(__dirname, './src')
@ -24,7 +35,7 @@ export default defineConfig(({ mode, command }) => {
open: true, open: true,
proxy: { proxy: {
[env.VITE_APP_BASE_API]: { [env.VITE_APP_BASE_API]: {
target: 'http://localhost:8001', target: env.VITE_APP_PROXY_TARGET || 'http://localhost:8001',
changeOrigin: true, changeOrigin: true,
ws: true, ws: true,
rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '') rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
@ -54,6 +65,48 @@ export default defineConfig(({ mode, command }) => {
] ]
} }
}, },
// 构建配置
build: {
outDir: 'dist',
assetsDir: 'static',
// 生产环境关闭source map
sourcemap: mode === 'development',
// 构建时清理输出目录
emptyOutDir: true,
// 大文件警告限制
chunkSizeWarningLimit: 2000,
// 代码分割配置
rollupOptions: {
output: {
// 静态资源分类打包
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
// 代码分割
manualChunks: {
// 将 Vue 相关的包打包到一个 chunk 中
vue: ['vue', 'vue-router', 'pinia'],
// 将 Element Plus 相关的包打包到一个 chunk 中
elementPlus: ['element-plus', '@element-plus/icons-vue'],
// 将 ECharts 相关的包打包到一个 chunk 中
echarts: ['echarts'],
// 将工具库打包到一个 chunk 中
utils: ['axios', '@vueuse/core', 'crypto-js', 'js-cookie', 'jsencrypt'],
// 将编辑器相关的包打包到一个 chunk 中
editor: ['@vueup/vue-quill', 'vue-json-pretty']
}
}
},
// 压缩配置
minify: 'terser',
terserOptions: {
compress: {
// 生产环境移除console
drop_console: mode === 'production',
drop_debugger: mode === 'production'
}
}
},
// 预编译 // 预编译
optimizeDeps: { optimizeDeps: {
include: [ include: [