diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..6dfe757 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "exclude": ["node_modules"] +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index b338faf..55912ca 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -203,3 +203,8 @@ aside { .mt-10 { margin-top: 10px; } + +.cursor-blue { + color: #409EFF; + cursor: pointer; +} diff --git a/src/components/DialogModel/index.vue b/src/components/DialogModel/index.vue index 28d65e0..12b42a5 100644 --- a/src/components/DialogModel/index.vue +++ b/src/components/DialogModel/index.vue @@ -24,6 +24,10 @@ v-if="dialogConfig.innerVisible" :before-close="handleCloseInner" :visible.sync="dialogConfig.innerVisible" + :style="{ + '--el-dialog-min-height': dialogConfig.minHeight, + '--el-dialog-max-height': dialogConfig.maxHeight, + }" > @@ -67,12 +71,14 @@ export default { top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; - max-height: var(--el-dialog-max-height) !important; + height: var(--el-dialog-max-height) !important; min-height: var(--el-dialog-min-height) !important; + max-height: var(--el-dialog-max-height) !important; .el-dialog__body { flex: 1 !important; overflow-y: scroll !important; - padding: 10px 20px !important; + padding: 20px 20px !important; + box-sizing: border-box !important; } } diff --git a/src/components/FilterQueryModel/index.vue b/src/components/FilterQueryModel/index.vue new file mode 100644 index 0000000..b6ae64b --- /dev/null +++ b/src/components/FilterQueryModel/index.vue @@ -0,0 +1,595 @@ + + + + + diff --git a/src/components/TableModel/index.vue b/src/components/TableModel/index.vue index f23363d..cd863da 100644 --- a/src/components/TableModel/index.vue +++ b/src/components/TableModel/index.vue @@ -52,7 +52,7 @@ handleCasAdd( $event, item.f_model, - cascaderFunc, + cascadeFunc, extraTableProp, ) " @@ -98,7 +98,6 @@ type="primary" icon="el-icon-search" @click="handleQuery" - v-if="showSearchBtn" > 查询 @@ -204,83 +203,64 @@ import ToolbarModel from '../ToolbarModel' export default { components: { ToolbarModel }, props: { - /** 表单查询条件 */ + // 表单查询条件 formLabel: { type: Array, default: () => [], }, - /** 列表请求接口 */ + // 列表请求接口 requestApi: { type: Function, default: () => function () {}, }, - /** 列表配置项 */ + // 列表配置项 columnsList: { type: Array, default: () => [], }, - /** 是否显示选择框 */ - showSel: { - type: Boolean, - default: true, - }, - /** 传递参数 */ + // 传递参数 sendParams: { type: Object, default: () => null, }, - sendId: { - type: Number, - default: () => null, - }, - /** 是否显示查询按钮 */ - showSearchBtn: { - type: Boolean, - default: true, - }, + // 是否显示查询按钮 默认显示 showBtnCrews: { type: Boolean, default: true, }, - cascaderFunc: { + // 级联选择 + cascadeFunc: { type: Function, default: () => null, }, + // 级联选择 额外参数 extraTableProp: { type: Object, default: () => null, }, - /** 是否显示操作列 */ + // 是否显示操作列 默认不显示 showOperation: { type: Boolean, - default: true, + default: false, }, - /** 是否显示右侧工具栏 */ + // 是否显示右侧工具栏 默认不显示 showRightTools: { type: Boolean, - default: true, + default: false, }, + // 复选框是否勾选 selectable: { type: Function, default: () => { return true }, }, - selSingle: { + // 是否显示复选框 由父组件传递 默认不显示 + isSelectShow: { type: Boolean, default: false, }, - showIndex: { - type: Boolean, - default: true, - }, - // 是否显示复选框 由父组件传递 - isSelectShow: { - type: Boolean, - default: true, - }, - - // 测试时使用 + // 测试时使用的数据源 testTableList: { type: Array, default: () => [], diff --git a/src/utils/request.js b/src/utils/request.js index 7d2be68..df0500f 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -8,8 +8,12 @@ import cache from '@/plugins/cache' import { saveAs } from 'file-saver' import { decryptWithSM4, encryptWithSM4, hashWithSM3AndSalt } from '@/utils/sm' const systemConfig = JSON.parse(localStorage.getItem('systemConfig')) || { - requestConfig: { encryptRequest: false, checkIntegrity: false, encryptResponse: false } -}; + requestConfig: { + encryptRequest: false, + checkIntegrity: false, + encryptResponse: false, + }, +} let downloadLoadingInstance // 是否显示重新登录 @@ -19,169 +23,224 @@ axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 创建axios实例 const service = axios.create({ - // axios中请求配置有baseURL选项,表示请求URL公共部分 - baseURL: process.env.VUE_APP_BASE_API, - // 超时 - timeout: 10000 + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: process.env.VUE_APP_BASE_API, + // 超时 + timeout: 100, }) // request 拦截器 -service.interceptors.request.use(config => { - // 提取 headers 和方法 - const headers = config.headers || {} - const { - isToken = true, - encryptRequest = true, - checkIntegrity = true, - encryptResponse = true, - repeatSubmit = false - } = headers +service.interceptors.request.use( + (config) => { + // 提取 headers 和方法 + const headers = config.headers || {} + const { + isToken = true, + encryptRequest = true, + checkIntegrity = true, + encryptResponse = true, + repeatSubmit = false, + } = headers - // 设置请求头 - //入参加密 - config.headers['encryptRequest'] = systemConfig.requestConfig.encryptRequest && encryptRequest ? 'true' : 'false' - // 数据完整性校验 - config.headers['checkIntegrity'] = systemConfig.requestConfig.checkIntegrity && checkIntegrity ? 'true' : 'false' - //回参是否加密 - config.headers['encryptResponse'] = systemConfig.requestConfig.encryptResponse && encryptResponse ? 'true' : 'false' + // 设置请求头 + //入参加密 + config.headers['encryptRequest'] = + systemConfig.requestConfig.encryptRequest && encryptRequest + ? 'true' + : 'false' + // 数据完整性校验 + config.headers['checkIntegrity'] = + systemConfig.requestConfig.checkIntegrity && checkIntegrity + ? 'true' + : 'false' + //回参是否加密 + config.headers['encryptResponse'] = + systemConfig.requestConfig.encryptResponse && encryptResponse + ? 'true' + : 'false' - const isRepeatSubmit = repeatSubmit - // 处理 Token - if (getToken() && isToken) { - config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义 token - } + const isRepeatSubmit = repeatSubmit + // 处理 Token + if (getToken() && isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义 token + } - // get请求映射params参数 - if (config.method === 'get' && config.params) { - let url = config.url + '?' + tansParams(config.params); - url = url.slice(0, -1); - config.params = {}; - config.url = url; - } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params) + url = url.slice(0, -1) + config.params = {} + config.url = url + } - if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { - let data = typeof config.data === 'object' ? JSON.stringify(config.data) : config.data - let contentType = config.headers['Content-Type'] - if (contentType.includes('application/json') && typeof data !== 'undefined') { - // 加密数据 - if (systemConfig.requestConfig.encryptRequest && encryptRequest) { - console.log(data); - console.log(hashWithSM3AndSalt(data)); - config.data = encryptWithSM4(data+"|"+hashWithSM3AndSalt(data)) - } - } - // 检查请求数据大小 - const requestSize = JSON.stringify({ url: config.url, data: data, time: Date.now() }).length - const limitSize = 1000 * 1024 * 1024 // 限制存放数据 5MB + if ( + !isRepeatSubmit && + (config.method === 'post' || config.method === 'put') + ) { + let data = + typeof config.data === 'object' + ? JSON.stringify(config.data) + : config.data + let contentType = config.headers['Content-Type'] + if ( + contentType.includes('application/json') && + typeof data !== 'undefined' + ) { + // 加密数据 + if ( + systemConfig.requestConfig.encryptRequest && + encryptRequest + ) { + console.log(data) + console.log(hashWithSM3AndSalt(data)) + config.data = encryptWithSM4( + data + '|' + hashWithSM3AndSalt(data), + ) + } + } + // 检查请求数据大小 + const requestSize = JSON.stringify({ + url: config.url, + data: data, + time: Date.now(), + }).length + const limitSize = 1000 * 1024 * 1024 // 限制存放数据 5MB - if (requestSize >= limitSize) { - console.warn(`[${config.url}]: 请求数据大小超出允许的5MB限制,无法进行防重复提交验证。`) - return config - } - // 防止重复提交 - const sessionObj = cache.session.getJSON('sessionObj') || {} - const requestObj = { url: config.url, data: data, time: Date.now() } + if (requestSize >= limitSize) { + console.warn( + `[${config.url}]: 请求数据大小超出允许的5MB限制,无法进行防重复提交验证。`, + ) + return config + } + // 防止重复提交 + const sessionObj = cache.session.getJSON('sessionObj') || {} + const requestObj = { url: config.url, data: data, time: Date.now() } - if (sessionObj.data === requestObj.data && requestObj.time - sessionObj.time < 0 && sessionObj.url === requestObj.url) { - console.warn(`[${sessionObj.url}]: 数据正在处理,请勿重复提交`) - return Promise.reject(new Error('数据正在处理,请勿重复提交')) - } - cache.session.setJSON('sessionObj', requestObj) - } - return config -}, error => { - console.error(error) - return Promise.reject(error) -}) + if ( + sessionObj.data === requestObj.data && + requestObj.time - sessionObj.time < 0 && + sessionObj.url === requestObj.url + ) { + console.warn(`[${sessionObj.url}]: 数据正在处理,请勿重复提交`) + return Promise.reject(new Error('数据正在处理,请勿重复提交')) + } + cache.session.setJSON('sessionObj', requestObj) + } + return config + }, + (error) => { + console.error(error) + return Promise.reject(error) + }, +) // 响应拦截器 -service.interceptors.response.use(res => { - if (res.headers.encryptresponse && !res.data.hasOwnProperty('code')) { - res.data = JSON.parse(decryptWithSM4(res.data)) - } - // 未设置状态码则默认成功状态 - const code = res.data.code || 200 - // 获取错误信息 - const msg = errorCode[code] || res.data.msg || errorCode['default'] - // 二进制数据则直接返回 - if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { - return res.data - } - if (code === 401) { - if (!isRelogin.show) { - isRelogin.show = true - MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - }).then(() => { - isRelogin.show = false - store.dispatch('LogOut').then(() => { - location.href = '/index' - }) - }).catch(() => { - isRelogin.show = false - }) - } - return Promise.reject('无效的会话,或者会话已过期,请重新登录。') - } else if (code === 500) { - Message({ message: msg, type: 'error' }) - return Promise.reject(new Error(msg)) - } else if (code === 601) { - Message({ message: msg, type: 'warning' }) - return Promise.reject('error') - } else if (code !== 200) { - Notification.error({ title: msg }) - return Promise.reject('error') - } else { - return res.data - } - }, - error => { - let { message } = error - if (message == 'Network Error') { - message = '后端接口连接异常' - } else if (message.includes('timeout')) { - message = '系统接口请求超时' - } else if (message.includes('Request failed with status code')) { - message = '系统接口' + message.substr(message.length - 3) + '异常' - } - Message({ message: message, type: 'error', duration: 5 * 1000 }) - return Promise.reject(error) - } +service.interceptors.response.use( + (res) => { + if (res.headers.encryptresponse && !res.data.hasOwnProperty('code')) { + res.data = JSON.parse(decryptWithSM4(res.data)) + } + // 未设置状态码则默认成功状态 + const code = res.data.code || 200 + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default'] + // 二进制数据则直接返回 + if ( + res.request.responseType === 'blob' || + res.request.responseType === 'arraybuffer' + ) { + return res.data + } + if (code === 401) { + if (!isRelogin.show) { + isRelogin.show = true + MessageBox.confirm( + '登录状态已过期,您可以继续留在该页面,或者重新登录', + '系统提示', + { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning', + }, + ) + .then(() => { + isRelogin.show = false + store.dispatch('LogOut').then(() => { + location.href = '/index' + }) + }) + .catch(() => { + isRelogin.show = false + }) + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + Message({ message: msg, type: 'error' }) + return Promise.reject(new Error(msg)) + } else if (code === 601) { + Message({ message: msg, type: 'warning' }) + return Promise.reject('error') + } else if (code !== 200) { + Notification.error({ title: msg }) + return Promise.reject('error') + } else { + return res.data + } + }, + (error) => { + let { message } = error + if (message == 'Network Error') { + message = '后端接口连接异常' + } else if (message.includes('timeout')) { + message = '系统接口请求超时' + } else if (message.includes('Request failed with status code')) { + message = '系统接口' + message.substr(message.length - 3) + '异常' + } + Message({ message: message, type: 'error', duration: 5 * 1000 }) + return Promise.reject(error) + }, ) // 通用下载方法 export function download(url, params, filename, config) { - downloadLoadingInstance = Loading.service({ - text: '正在下载数据,请稍候', - spinner: 'el-icon-loading', - background: 'rgba(0, 0, 0, 0.7)' - }) - return service.post(url, params, { - transformRequest: [(params) => { - return tansParams(params) - }], - headers: { 'Content-Type': 'application/x-www-form-urlencoded', encryptResponse: false}, - responseType: 'blob', - ...config - }).then(async(data) => { - const isBlob = blobValidate(data) - if (isBlob) { - const blob = new Blob([data]) - saveAs(blob, filename) - } else { - const resText = await data.text() - const rspObj = JSON.parse(resText) - const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] - Message.error(errMsg) - } - downloadLoadingInstance.close() - }).catch((r) => { - console.error(r) - Message.error('下载文件出现错误,请联系管理员!') - downloadLoadingInstance.close() - }) + downloadLoadingInstance = Loading.service({ + text: '正在下载数据,请稍候', + spinner: 'el-icon-loading', + background: 'rgba(0, 0, 0, 0.7)', + }) + return service + .post(url, params, { + transformRequest: [ + (params) => { + return tansParams(params) + }, + ], + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + encryptResponse: false, + }, + responseType: 'blob', + ...config, + }) + .then(async (data) => { + const isBlob = blobValidate(data) + if (isBlob) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text() + const rspObj = JSON.parse(resText) + const errMsg = + errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + Message.error(errMsg) + } + downloadLoadingInstance.close() + }) + .catch((r) => { + console.error(r) + Message.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close() + }) } export default service diff --git a/src/views/home-index/components/dataOverviewProject/components/common-table-slots.vue b/src/views/home-index/components/dataOverviewProject/components/common-table-slots.vue new file mode 100644 index 0000000..51029a4 --- /dev/null +++ b/src/views/home-index/components/dataOverviewProject/components/common-table-slots.vue @@ -0,0 +1,55 @@ + + + diff --git a/src/views/home-index/components/dataOverviewProject/components/config.js b/src/views/home-index/components/dataOverviewProject/components/config.js new file mode 100644 index 0000000..59f22bd --- /dev/null +++ b/src/views/home-index/components/dataOverviewProject/components/config.js @@ -0,0 +1,329 @@ +// 总工程列表子项目概况列表上方查询条件 + +// 总工程列表和分包信息列表公共字段 +const commonColumnsList = [ + { + t_props: 'onSiteCount', + t_label: '在场/固定/临时人数', + t_slot: 'onSiteCount', + }, + { + t_props: 'todayAttendanceCount', + t_label: '今日考勤人数', + t_slot: 'todayAttendanceCount', + }, + { + t_props: 'redLightCount', + t_label: '红绿灯人员', + t_slot: 'redLightCount', + }, +] +// 总工程列表和分包信息列表公共字段 +const commonColumnsListTwo = [ + { t_props: 'projectCount', t_label: '所在工程' }, + { t_props: 'projectCount', t_label: '所属分公司' }, +] + +export const allProjectFormLabel = [ + { + f_label: '工程名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, +] + +// 总工程列表字段 +export const allProjectColumnsList = [ + { t_props: 'projectName', t_label: '总工程名称' }, + { + t_props: 'projectCount', + t_label: '标段工程数量', + t_slot: 'projectCount', + }, +] + +// 子项目概况列表字段 +export const childColumnsList = [ + { t_props: 'projectName', t_label: '分公司' }, + { t_props: 'projectCount', t_label: '工程名称' }, + { + t_props: 'subCount', + t_label: '分包数量', + t_slot: 'subCount', + }, + { + t_props: 'teamCount', + t_label: '班组数量', + t_slot: 'teamCount', + }, + ...commonColumnsList, + { t_props: 'projectCount', t_label: '电压等级' }, + { t_props: 'projectCount', t_label: '工程类型' }, + { t_props: 'projectCount', t_label: '工程状态' }, +] + +// 分包信息列表上方查询条件 +export const subFormLabel = [ + { + f_label: '分包名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '工程名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '分公司名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, +] + +// 分包信息列表字段 +export const subColumnsList = [ + { t_props: 'projectName', t_label: '分包名称' }, + + { + t_props: 'teamCount', + t_label: '在场班组数量', + t_slot: 'teamCount', + }, + ...commonColumnsList, + ...commonColumnsListTwo, +] + +// 班组信息列表上方查询条件 +export const teamFormLabel = [ + { + f_label: '班组名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '分包名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '工程名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '分公司名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, +] + +// 班组信息列表字段 +export const teamColumnsList = [ + { t_props: 'projectName', t_label: '班组名称' }, + ...commonColumnsList, + { t_props: 'projectCount', t_label: '所属分包商' }, + ...commonColumnsListTwo, +] + +// 人员信息列表上方查询条件 +export const personFormLabel = [ + { + f_label: '姓名', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '分包工程', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, + { + f_label: '工程名称', + f_model: 'projectName', + f_type: 'ipt', + isShow: false, // 是否展示label + }, +] + +// 人员信息列表字段 +export const personColumnsList = [ + { t_props: 'userName', t_label: '姓名', t_slot: 'userName' }, + { t_props: 'projectName', t_label: '工种' }, + { + t_props: 'redLightStatus', + t_label: '红绿灯状态', + t_slot: 'redLightStatus', + }, + { t_props: 'projectName', t_label: '考勤状态' }, + { t_props: 'projectName', t_label: '性别' }, + { t_props: 'projectName', t_label: '年龄' }, + { t_props: 'projectName', t_label: '联系方式' }, + { t_props: 'projectName', t_label: '所属分包' }, + { t_props: 'projectName', t_label: '所属工程' }, +] + +// 弹框公共配置 +const dialogCommonConfig = { + outerVisible: false, + outerTitle: '', + minHeight: '90vh', + maxHeight: '90vh', +} + +// 子项目概况弹框配置 +export const dialogConfig = { + outerWidth: '90%', + ...dialogCommonConfig, +} +// 分包弹框配置 +export const dialogConfigTwo = { + outerWidth: '80%', + ...dialogCommonConfig, +} +// 班组弹框配置 +export const dialogConfigThree = { + outerWidth: '80%', + ...dialogCommonConfig, +} +// 人员弹框配置 +export const dialogConfigFour = { + outerWidth: '80%', + ...dialogCommonConfig, +} + +// 人员详情弹框配置 +export const dialogConfigFive = { + outerWidth: '75%', + ...dialogCommonConfig, +} + +// 总工程列表测试数据 +export const allProjectTestTableList = [ + { + projectName: '测试工程1', + projectCount: 10, + }, + { + projectName: '测试工程2', + projectCount: 20, + }, + { + projectName: '测试工程3', + projectCount: 20, + }, +] + +// 子项目概况列表测试数据 +export const childTestTableList = [ + { + projectName: '测试工程1', + projectCount: 10, + subCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, + { + projectName: '测试工程2', + projectCount: 10, + subCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, +] + +// 分包信息列表测试数据 +export const subTestTableList = [ + { + projectName: '测试工程1', + projectCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, +] + +// 班组信息列表测试数据 +export const teamTestTableList = [ + { + projectName: '测试工程1', + projectCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, +] + +// 人员信息列表测试数据 +export const personTestTableList = [ + { + userName: '张三', + redLightStatus: '红灯', + projectCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, + { + userName: '李思思', + redLightStatus: '绿灯', + projectCount: 10, + teamCount: 10, + onSiteCount: 10, + todayAttendanceCount: 10, + redLightCount: 10, + line: 12, + fixed: 13, + temporary: 14, + redCount: 15, + yellowCount: 16, + greenCount: 17, + }, +] diff --git a/src/views/home-index/components/dataOverviewProject/components/item-one.vue b/src/views/home-index/components/dataOverviewProject/components/item-one.vue index 1bf2d50..2f20bf2 100644 --- a/src/views/home-index/components/dataOverviewProject/components/item-one.vue +++ b/src/views/home-index/components/dataOverviewProject/components/item-one.vue @@ -2,14 +2,11 @@
- - diff --git a/src/views/home-index/components/dataOverviewProject/components/person-details.vue b/src/views/home-index/components/dataOverviewProject/components/person-details.vue new file mode 100644 index 0000000..a4c077f --- /dev/null +++ b/src/views/home-index/components/dataOverviewProject/components/person-details.vue @@ -0,0 +1,501 @@ + + + + + diff --git a/src/views/home-index/components/oftenUse/index.vue b/src/views/home-index/components/oftenUse/index.vue index a9b686f..146b506 100644 --- a/src/views/home-index/components/oftenUse/index.vue +++ b/src/views/home-index/components/oftenUse/index.vue @@ -2,11 +2,9 @@
-
- - - -
+ + +