diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f71b978 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +node_modules/ +.DS_Store +.idea/ +.vscode/ +.env +.env.local + + +package-lock.json +yarn.lock diff --git a/pc/.gitignore b/pc/.gitignore new file mode 100644 index 0000000..f71b978 --- /dev/null +++ b/pc/.gitignore @@ -0,0 +1,10 @@ +node_modules/ +.DS_Store +.idea/ +.vscode/ +.env +.env.local + + +package-lock.json +yarn.lock diff --git a/pc/package.json b/pc/package.json new file mode 100644 index 0000000..491d5d5 --- /dev/null +++ b/pc/package.json @@ -0,0 +1,77 @@ +{ + "name": "yoaf-web", + "version": "1.1.2", + "description": "智慧教育平台", + "author": "front-end", + "license": "MIT", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview" + }, + "keywords": [ + "vue", + "admin", + "dashboard", + "element-ui", + "boilerplate", + "admin-template", + "management-system" + ], + "dependencies": { + "@riophae/vue-treeselect": "^0.4.0", + "axios": "0.24.0", + "clipboard": "2.0.8", + "core-js": "3.19.1", + "dayjs": "^1.11.10", + "echarts": "4.9.0", + "element-ui": "^2.15.6", + "file-saver": "2.0.5", + "fuse.js": "6.4.3", + "highlight.js": "9.18.5", + "html2canvas": "^1.4.1", + "js-beautify": "1.13.0", + "js-cookie": "3.0.1", + "jszip": "^3.10.1", + "moment": "^2.30.1", + "nprogress": "0.2.0", + "qrcode": "^1.5.3", + "quill": "1.3.7", + "screenfull": "5.0.2", + "sm-crypto": "^0.3.12", + "sortablejs": "1.10.2", + "tui-image-editor": "^3.15.3", + "vue": "^2.7.14", + "vue-count-to": "1.0.13", + "vue-cropper": "0.5.5", + "vue-meta": "2.4.0", + "vue-router": "3.4.9", + "vuedraggable": "^2.24.3", + "vuex": "3.6.0", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "4.4.6", + "@vue/cli-service": "4.4.6", + "babel-plugin-dynamic-import-node": "2.3.3", + "chalk": "4.1.0", + "compression-webpack-plugin": "5.0.2", + "connect": "3.6.6", + "mockjs": "^1.0.1-beta3", + "runjs": "4.4.2", + "sass": "1.32.13", + "sass-loader": "10.1.1", + "script-ext-html-webpack-plugin": "2.1.5", + "svg-sprite-loader": "5.1.1", + "vue-template-compiler": "2.6.14" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + ">1%", + "last 2 versions" + ] +} \ No newline at end of file diff --git a/pc/public/index.html b/pc/public/index.html new file mode 100644 index 0000000..a66625c --- /dev/null +++ b/pc/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + 智慧教育平台 + + + +
+ + + \ No newline at end of file diff --git a/pc/src/App.vue b/pc/src/App.vue new file mode 100644 index 0000000..4194d3c --- /dev/null +++ b/pc/src/App.vue @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/pc/src/api/asset/classification.js b/pc/src/api/asset/classification.js new file mode 100644 index 0000000..e4e2fdb --- /dev/null +++ b/pc/src/api/asset/classification.js @@ -0,0 +1,96 @@ +import request from '@/utils/request' + +// 查询资产分类列表 +export function listClassification(query) { + return request({ + url: '/asset/classification/list', + method: 'get', + params: query + }) +} + +// 查询资产分类详情 +export function getClassification(id) { + return request({ + url: '/asset/classification/' + id, + method: 'get' + }) +} + +// 新增资产分类 +export function addClassification(data) { + return request({ + url: '/asset/classification', + method: 'post', + data: data + }) +} + +// 修改资产分类 +export function updateClassification(data) { + return request({ + url: '/asset/classification', + method: 'put', + data: data + }) +} + +// 删除资产分类 +export function delClassification(id) { + return request({ + url: '/asset/classification/' + id, + method: 'delete' + }) +} + +// 禁用资产分类 +export function disableClassification(id, lastModUserId) { + return request({ + url: '/asset/classification/disable/' + id, + method: 'put', + params: { lastModUserId } + }) +} + +// 启用资产分类 +export function enableClassification(id, lastModUserId) { + return request({ + url: '/asset/classification/enable/' + id, + method: 'put', + params: { lastModUserId } + }) +} + +// 批量删除资产分类 +export function delClassificationBatch(ids, lastModUserId) { + return request({ + url: '/asset/classification/batch/' + ids, + method: 'delete', + params: { lastModUserId } + }) +} + +// 获取资产分类树形结构 +export function getClassificationTree() { + return request({ + url: '/asset/classification/tree', + method: 'get' + }) +} + +// 检查分类是否被使用 +export function checkClassificationInUse(id) { + return request({ + url: '/asset/classification/' + id + '/check', + method: 'get' + }) +} + +// 导出资产分类 +export function exportClassification(query) { + return request({ + url: '/asset/classification/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/pc/src/api/asset/location.js b/pc/src/api/asset/location.js new file mode 100644 index 0000000..0b2db40 --- /dev/null +++ b/pc/src/api/asset/location.js @@ -0,0 +1,96 @@ +import request from '@/utils/request' + +// 查询资产位置列表 +export function listLocation(query) { + return request({ + url: '/asset/location/list', + method: 'get', + params: query + }) +} + +// 查询资产位置详情 +export function getLocation(id) { + return request({ + url: '/asset/location/' + id, + method: 'get' + }) +} + +// 新增资产位置 +export function addLocation(data) { + return request({ + url: '/asset/location', + method: 'post', + data: data + }) +} + +// 修改资产位置 +export function updateLocation(data) { + return request({ + url: '/asset/location', + method: 'put', + data: data + }) +} + +// 删除资产位置 +export function delLocation(id) { + return request({ + url: '/asset/location/' + id, + method: 'delete' + }) +} + +// 禁用资产位置 +export function disableLocation(id, lastModUserId) { + return request({ + url: '/asset/location/disable/' + id, + method: 'put', + params: { lastModUserId } + }) +} + +// 启用资产位置 +export function enableLocation(id, lastModUserId) { + return request({ + url: '/asset/location/enable/' + id, + method: 'put', + params: { lastModUserId } + }) +} + +// 批量删除资产位置 +export function delLocationBatch(ids, lastModUserId) { + return request({ + url: '/asset/location/batch/' + ids, + method: 'delete', + params: { lastModUserId } + }) +} + +// 获取资产位置树形结构 +export function getLocationTree() { + return request({ + url: '/asset/location/tree', + method: 'get' + }) +} + +// 检查位置是否被使用 +export function checkLocationInUse(id) { + return request({ + url: '/asset/location/' + id + '/check', + method: 'get' + }) +} + +// 导出资产位置 +export function exportLocation(query) { + return request({ + url: '/asset/location/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/pc/src/api/building.js b/pc/src/api/building.js new file mode 100644 index 0000000..27997f3 --- /dev/null +++ b/pc/src/api/building.js @@ -0,0 +1,133 @@ +import request from '@/utils/request' + +// 查询楼宇列表 +export function getBuildingList(query) { + return request({ + url: '/room/building/list', + method: 'get', + params: query + }) +} + +// 查询楼宇详细 +export function getBuildingDetail(id) { + return request({ + url: `/room/building/${id}`, + method: 'get' + }) +} + +// 新增楼宇 +export function addBuilding(data) { + // 处理字段名映射,确保前端驼峰命名与后端下划线命名正确对应 + const processedData = { + ...data, + buildingTags: data.buildingTags, + isHot: data.isHot, + imageUrl: data.buildingImage, + } + + // 删除undefined的属性 + Object.keys(processedData).forEach(key => { + if (processedData[key] === undefined) { + delete processedData[key] + } + }) + + return request({ + url: '/room/building', + method: 'post', + data: processedData + }) +} + +// 修改楼宇 +export function updateBuilding(data) { + // 处理字段名映射,确保前端驼峰命名与后端下划线命名正确对应 + const processedData = { + ...data, + buildingTags: data.buildingTags, + isHot: data.isHot, + imageUrl: data.buildingImage + } + + // 删除undefined的属性 + Object.keys(processedData).forEach(key => { + if (processedData[key] === undefined) { + delete processedData[key] + } + }) + + return request({ + url: '/room/building', + method: 'put', + data: processedData + }) +} + +// 删除楼宇 +export function deleteBuilding(ids) { + return request({ + url: `/room/building/${ids}`, + method: 'delete' + }) +} + +// 获取楼宇统计信息 +export function getBuildingStatistics(id) { + return request({ + url: `/room/building/${id}/statistics`, + method: 'get' + }) +} + +// 查询楼层列表 +export function getFloorList(query) { + return request({ + url: '/room/floor/list', + method: 'get', + params: query + }) +} + +// 获取楼层详情 +export function getFloorDetail(id) { + return request({ + url: `/room/floor/${id}`, + method: 'get' + }) +} + +// 新增楼层 +export function addFloor(data) { + return request({ + url: '/room/floor', + method: 'post', + data: data + }) +} + +// 修改楼层 +export function updateFloor(data) { + return request({ + url: '/room/floor', + method: 'put', + data: data + }) +} + +// 删除楼层 +export function deleteFloor(ids) { + return request({ + url: `/room/floor/${ids}`, + method: 'delete' + }) +} + +// 根据楼宇ID获取楼层列表 +export function getFloorListByBuilding(buildingId) { + return request({ + url: `/room/floor/building/${buildingId}`, + method: 'get' + }) +} \ No newline at end of file diff --git a/pc/src/api/project.js b/pc/src/api/project.js new file mode 100644 index 0000000..37ba84d --- /dev/null +++ b/pc/src/api/project.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 获取项目列表 +export function getProjectList(query) { + return request({ + url: '/room/project/list', + method: 'get', + params: query + }) +} + +// 获取项目详情 +export function getProjectDetail(id) { + return request({ + url: `/room/project/${id}`, + method: 'get' + }) +} + +// 新增项目 +export function addProject(data) { + return request({ + url: '/room/project', + method: 'post', + data: data + }) +} + +// 修改项目 +export function updateProject(id, data) { + const updateData = { ...data, id } + return request({ + url: '/room/project', + method: 'put', + data: updateData + }) +} + +// 删除项目 +export function deleteProject(id) { + return request({ + url: `/room/project/${id}`, + method: 'delete' + }) +} + +// 获取项目统计数据 +export function getProjectStatistics(id) { + return request({ + url: `/room/project/${id}/statistics`, + method: 'get' + }) +} + +// 获取所有项目统计数据(整体概况) +export function getAllProjectStatistics() { + return request({ + url: '/room/project/statistics', + method: 'get' + }) +} \ No newline at end of file diff --git a/pc/src/assets/styles/index.scss b/pc/src/assets/styles/index.scss new file mode 100644 index 0000000..2856549 --- /dev/null +++ b/pc/src/assets/styles/index.scss @@ -0,0 +1,24 @@ +html, body { + margin: 0; + padding: 0; + height: 100%; + font-family: Avenir, Helvetica, Arial, sans-serif; +} + +* { + box-sizing: border-box; +} + +.el-container { + height: 100%; +} + +.el-header { + padding: 0; + height: 60px; +} + +.el-main { + background-color: #f0f2f5; + padding: 20px; +} \ No newline at end of file diff --git a/pc/src/layout/index.vue b/pc/src/layout/index.vue new file mode 100644 index 0000000..6768b29 --- /dev/null +++ b/pc/src/layout/index.vue @@ -0,0 +1,112 @@ + + + + + \ No newline at end of file diff --git a/pc/src/main.js b/pc/src/main.js new file mode 100644 index 0000000..301bdd2 --- /dev/null +++ b/pc/src/main.js @@ -0,0 +1,16 @@ +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store' +import ElementUI from 'element-ui' +import 'element-ui/lib/theme-chalk/index.css' +import './assets/styles/index.scss' + +Vue.use(ElementUI) +Vue.config.productionTip = false + +new Vue({ + router, + store, + render: h => h(App) +}).$mount('#app') \ No newline at end of file diff --git a/pc/src/router/index.js b/pc/src/router/index.js new file mode 100644 index 0000000..49d5014 --- /dev/null +++ b/pc/src/router/index.js @@ -0,0 +1,59 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' +import Layout from '@/layout/index' +import systemRoutes from './modules/system' +import projectRoutes from './modules/project' + +Vue.use(VueRouter) + +const routes = [ + { + path: '/', + component: () => import('@/layout/index'), + redirect: '/home', + hidden: true + }, + { + path: '/home', + component: () => import('@/layout/index'), + children: [ + { + path: '', + name: 'Home', + component: () => import('../views/Home.vue'), + meta: { title: '首页', icon: 'el-icon-s-home' } + } + ], + meta: { title: '首页', icon: 'el-icon-s-home' } + }, + systemRoutes, + projectRoutes, + { + path: '/asset', + component: Layout, + name: 'Asset', + meta: { title: '资产管理', icon: 'el-icon-s-management' }, + children: [ + { + path: 'location', + component: () => import('@/views/asset/location/index'), + name: 'AssetLocation', + meta: { title: '资产位置设置', icon: 'el-icon-location' } + }, + { + path: 'classification', + component: () => import('@/views/asset/classification/index'), + name: 'AssetClassification', + meta: { title: '资产分类设置', icon: 'el-icon-folder' } + } + ] + } +] + +const router = new VueRouter({ + mode: 'history', + base: process.env.BASE_URL, + routes +}) + +export default router \ No newline at end of file diff --git a/pc/src/router/modules/project.js b/pc/src/router/modules/project.js new file mode 100644 index 0000000..4af4c1c --- /dev/null +++ b/pc/src/router/modules/project.js @@ -0,0 +1,21 @@ +export default { + path: '/project', + component: () => import('@/layout/index'), + redirect: '/project/list', + name: 'Project', + meta: { title: '项目管理', icon: 'el-icon-office-building' }, + children: [ + { + path: 'list', + name: 'ProjectList', + component: () => import('@/views/project/index'), + meta: { title: '项目列表' } + }, + { + path: 'building', + name: 'BuildingList', + component: () => import('@/views/project/building/index'), + meta: { title: '楼宇列表' } + } + ] +} \ No newline at end of file diff --git a/pc/src/router/modules/system.js b/pc/src/router/modules/system.js new file mode 100644 index 0000000..d610e93 --- /dev/null +++ b/pc/src/router/modules/system.js @@ -0,0 +1,15 @@ +export default { + path: '/system', + component: () => import('@/layout/index'), + redirect: '/system/department-member', + name: 'System', + meta: { title: '系统管理', icon: 'el-icon-s-tools' }, + children: [ + { + path: 'department-member', + component: () => import('@/views/system/department-member/index'), + name: 'DepartmentMember', + meta: { title: '部门成员管理', icon: 'el-icon-office-building' } + } + ] +} \ No newline at end of file diff --git a/pc/src/store/index.js b/pc/src/store/index.js new file mode 100644 index 0000000..3a7f2d7 --- /dev/null +++ b/pc/src/store/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +Vue.use(Vuex) + +export default new Vuex.Store({ + state: { + }, + mutations: { + }, + actions: { + }, + modules: { + } +}) \ No newline at end of file diff --git a/pc/src/utils/request.js b/pc/src/utils/request.js new file mode 100644 index 0000000..d10724c --- /dev/null +++ b/pc/src/utils/request.js @@ -0,0 +1,51 @@ +import axios from 'axios' +import { Message } from 'element-ui' + +// 创建axios实例 +const service = axios.create({ + // baseURL: '/api', // 修改为相对路径,使用代理 + baseURL: 'http://192.168.137.38:8080/api', // 接口地址 + + timeout: 10000 // 请求超时时间 +}) + +// 请求拦截器 +service.interceptors.request.use( + config => { + // 可以在这里添加请求头等信息 + return config + }, + error => { + console.log(error) + return Promise.reject(error) + } +) + +// 响应拦截器 +service.interceptors.response.use( + response => { + const res = response.data + // 如果返回的状态码不是200,则判断为错误 + if (res.code !== '000000') { + Message({ + message: res.message || '系统错误', + type: 'error', + duration: 5 * 1000 + }) + return Promise.reject(new Error(res.message || '系统错误')) + } else { + return res + } + }, + error => { + console.log('err' + error) + Message({ + message: error.message, + type: 'error', + duration: 5 * 1000 + }) + return Promise.reject(error) + } +) + +export default service \ No newline at end of file diff --git a/pc/src/views/Home.vue b/pc/src/views/Home.vue new file mode 100644 index 0000000..d53bc9c --- /dev/null +++ b/pc/src/views/Home.vue @@ -0,0 +1,84 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/asset/classification/index.vue b/pc/src/views/asset/classification/index.vue new file mode 100644 index 0000000..2f94d8b --- /dev/null +++ b/pc/src/views/asset/classification/index.vue @@ -0,0 +1,416 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/asset/location/index.vue b/pc/src/views/asset/location/index.vue new file mode 100644 index 0000000..1bd437e --- /dev/null +++ b/pc/src/views/asset/location/index.vue @@ -0,0 +1,416 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/project/building/index.vue b/pc/src/views/project/building/index.vue new file mode 100644 index 0000000..d92771d --- /dev/null +++ b/pc/src/views/project/building/index.vue @@ -0,0 +1,1802 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/project/index.vue b/pc/src/views/project/index.vue new file mode 100644 index 0000000..ce50770 --- /dev/null +++ b/pc/src/views/project/index.vue @@ -0,0 +1,537 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/system/department-member/index.vue b/pc/src/views/system/department-member/index.vue new file mode 100644 index 0000000..9f843fb --- /dev/null +++ b/pc/src/views/system/department-member/index.vue @@ -0,0 +1,946 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/system/department/index.vue b/pc/src/views/system/department/index.vue new file mode 100644 index 0000000..c9d8699 --- /dev/null +++ b/pc/src/views/system/department/index.vue @@ -0,0 +1,203 @@ + + + + + \ No newline at end of file diff --git a/pc/src/views/system/index.vue b/pc/src/views/system/index.vue new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/pc/src/views/system/index.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pc/src/views/system/member/index.vue b/pc/src/views/system/member/index.vue new file mode 100644 index 0000000..a9ded78 --- /dev/null +++ b/pc/src/views/system/member/index.vue @@ -0,0 +1,285 @@ + + + + + \ No newline at end of file diff --git a/pc/vue.config.js b/pc/vue.config.js new file mode 100644 index 0000000..d2a95fb --- /dev/null +++ b/pc/vue.config.js @@ -0,0 +1,23 @@ +module.exports = { + publicPath: '/', + outputDir: 'dist', + assetsDir: 'static', + productionSourceMap: false, + devServer: { + port: 8080, + open: true, + overlay: { + warnings: false, + errors: true + }, + proxy: { + '/api': { + target: 'http://localhost:8080', + changeOrigin: true, + pathRewrite: { + '^/api': '/api' + } + } + } + } +} \ No newline at end of file