Browse Source

feat: "页面"

pull/1/head
xuesinan 4 years ago
parent
commit
ada472b626
  1. 2
      .env.development
  2. 1
      .eslintrc.js
  3. 2
      index.html
  4. 85
      package-lock.json
  5. 80
      src/App.vue
  6. 4
      src/apis/index.js
  7. 191
      src/components/tall/center/ProjectDetail.vue
  8. 22
      src/components/tall/left/Calendar.vue
  9. 33
      src/components/tall/left/Index.vue
  10. 142
      src/components/tall/left/Projects.vue
  11. 24
      src/components/tall/top/Navbar.vue
  12. 33
      src/components/tall/top/TopNavbar.vue
  13. 1
      src/main.js
  14. 82
      src/store/tall/projects/projects.js
  15. 24
      src/views/home/Index.vue
  16. 4
      src/views/user/SignIn.vue
  17. 8552
      yarn.lock

2
.env.development

@ -1 +1 @@
VITE_API_URL=http://localhost:4001
VITE_API_URL=http://localhost:3000

1
.eslintrc.js

@ -26,6 +26,7 @@ module.exports = {
'no-unused-expressions': 'off',
'vue/no-mutating-props': 'off',
'vue/no-multiple-template-root': 'off',
"no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [] }],
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-param-reassign': 'off',

2
index.html

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>智能大气腐蚀监测云平台</title>
<title>山大实验室管理平台</title>
</head>
<body>
<div id="app"></div>

85
package-lock.json

@ -9,7 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@vitejs/plugin-vue": "^1.9.3",
"ant-design-vue": "^2.2.8",
"ant-design-vue": "3.0.0-alpha.9",
"axios": "^0.23.0",
"dayjs": "^1.10.7",
"echarts": "^5.2.2",
@ -3153,32 +3153,45 @@
}
},
"node_modules/ant-design-vue": {
"version": "2.2.8",
"resolved": "https://registry.npmmirror.com/ant-design-vue/download/ant-design-vue-2.2.8.tgz?cache=0&sync_timestamp=1636383524560&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fant-design-vue%2Fdownload%2Fant-design-vue-2.2.8.tgz",
"integrity": "sha1-+ofPaELY7poNivOT/0CZ7MQHLys=",
"version": "3.0.0-alpha.9",
"resolved": "https://registry.npmmirror.com/ant-design-vue/download/ant-design-vue-3.0.0-alpha.9.tgz?cache=0&sync_timestamp=1637420925271&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fant-design-vue%2Fdownload%2Fant-design-vue-3.0.0-alpha.9.tgz",
"integrity": "sha1-So9uZevevE8w3AfMoz9rHuA21CU=",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.0.0",
"@babel/runtime": "^7.10.5",
"@simonwep/pickr": "~1.8.0",
"array-tree-filter": "^2.1.0",
"async-validator": "^3.3.0",
"async-validator": "^4.0.0",
"dayjs": "^1.10.5",
"dom-align": "^1.12.1",
"dom-scroll-into-view": "^2.0.0",
"lodash": "^4.17.21",
"lodash-es": "^4.17.15",
"moment": "^2.27.0",
"omit.js": "^2.0.0",
"resize-observer-polyfill": "^1.5.1",
"scroll-into-view-if-needed": "^2.2.25",
"shallow-equal": "^1.0.0",
"vue-types": "^3.0.0",
"warning": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design-vue"
},
"peerDependencies": {
"@vue/compiler-sfc": ">=3.1.0",
"vue": ">=3.1.0"
}
},
"node_modules/ant-design-vue/node_modules/@ant-design/colors": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/@ant-design/colors/download/@ant-design/colors-6.0.0.tgz",
"integrity": "sha1-m5NmJXz/zEfbQrnQIDu1ksE8Apg=",
"dependencies": {
"@ctrl/tinycolor": "^3.4.0"
}
},
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.nlark.com/anymatch/download/anymatch-3.1.2.tgz",
@ -3281,9 +3294,10 @@
"dev": true
},
"node_modules/async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmmirror.com/async-validator/download/async-validator-3.5.2.tgz?cache=0&sync_timestamp=1634529574100&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fasync-validator%2Fdownload%2Fasync-validator-3.5.2.tgz",
"integrity": "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA="
"version": "4.0.7",
"resolved": "https://registry.npmmirror.com/async-validator/download/async-validator-4.0.7.tgz?cache=0&sync_timestamp=1634529574100&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fasync-validator%2Fdownload%2Fasync-validator-4.0.7.tgz",
"integrity": "sha1-A0oP0hA6ay6/AQ2nUYO+wpkkev4=",
"license": "MIT"
},
"node_modules/at-least-node": {
"version": "1.0.0",
@ -6816,14 +6830,6 @@
"import-meta-resolve": "^1.1.1"
}
},
"node_modules/moment": {
"version": "2.29.1",
"resolved": "https://registry.nlark.com/moment/download/moment-2.29.1.tgz",
"integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M=",
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz",
@ -6964,11 +6970,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/omit.js": {
"version": "2.0.2",
"resolved": "https://registry.nlark.com/omit.js/download/omit.js-2.0.2.tgz",
"integrity": "sha1-3ZuENvq5R6Xz/yFMslOGMeMT7C8="
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.nlark.com/once/download/once-1.4.0.tgz",
@ -11572,26 +11573,36 @@
}
},
"ant-design-vue": {
"version": "2.2.8",
"resolved": "https://registry.npmmirror.com/ant-design-vue/download/ant-design-vue-2.2.8.tgz?cache=0&sync_timestamp=1636383524560&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fant-design-vue%2Fdownload%2Fant-design-vue-2.2.8.tgz",
"integrity": "sha1-+ofPaELY7poNivOT/0CZ7MQHLys=",
"version": "3.0.0-alpha.9",
"resolved": "https://registry.npmmirror.com/ant-design-vue/download/ant-design-vue-3.0.0-alpha.9.tgz?cache=0&sync_timestamp=1637420925271&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fant-design-vue%2Fdownload%2Fant-design-vue-3.0.0-alpha.9.tgz",
"integrity": "sha1-So9uZevevE8w3AfMoz9rHuA21CU=",
"requires": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.0.0",
"@babel/runtime": "^7.10.5",
"@simonwep/pickr": "~1.8.0",
"array-tree-filter": "^2.1.0",
"async-validator": "^3.3.0",
"async-validator": "^4.0.0",
"dayjs": "^1.10.5",
"dom-align": "^1.12.1",
"dom-scroll-into-view": "^2.0.0",
"lodash": "^4.17.21",
"lodash-es": "^4.17.15",
"moment": "^2.27.0",
"omit.js": "^2.0.0",
"resize-observer-polyfill": "^1.5.1",
"scroll-into-view-if-needed": "^2.2.25",
"shallow-equal": "^1.0.0",
"vue-types": "^3.0.0",
"warning": "^4.0.0"
},
"dependencies": {
"@ant-design/colors": {
"version": "6.0.0",
"resolved": "https://registry.npm.taobao.org/@ant-design/colors/download/@ant-design/colors-6.0.0.tgz",
"integrity": "sha1-m5NmJXz/zEfbQrnQIDu1ksE8Apg=",
"requires": {
"@ctrl/tinycolor": "^3.4.0"
}
}
}
},
"anymatch": {
@ -11673,9 +11684,9 @@
"dev": true
},
"async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmmirror.com/async-validator/download/async-validator-3.5.2.tgz?cache=0&sync_timestamp=1634529574100&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fasync-validator%2Fdownload%2Fasync-validator-3.5.2.tgz",
"integrity": "sha1-aOhmqWgk6LJpT/eoMcGiXETV5QA="
"version": "4.0.7",
"resolved": "https://registry.npmmirror.com/async-validator/download/async-validator-4.0.7.tgz?cache=0&sync_timestamp=1634529574100&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fasync-validator%2Fdownload%2Fasync-validator-4.0.7.tgz",
"integrity": "sha1-A0oP0hA6ay6/AQ2nUYO+wpkkev4="
},
"at-least-node": {
"version": "1.0.0",
@ -14408,11 +14419,6 @@
"import-meta-resolve": "^1.1.1"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.nlark.com/moment/download/moment-2.29.1.tgz",
"integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz",
@ -14519,11 +14525,6 @@
"es-abstract": "^1.19.1"
}
},
"omit.js": {
"version": "2.0.2",
"resolved": "https://registry.nlark.com/omit.js/download/omit.js-2.0.2.tgz",
"integrity": "sha1-3ZuENvq5R6Xz/yFMslOGMeMT7C8="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.nlark.com/once/download/once-1.4.0.tgz",

80
src/App.vue

@ -1,18 +1,27 @@
<template>
<a-config-provider :locale="locale">
<a-layout>
<!-- 日历页-->
<a-layout-sider v-show="collapsed" style="background: #fff"><Left /></a-layout-sider>
<div v-if="!token"></div>
<a-config-provider v-else :locale="locale">
<a-layout>
<a-layout-header style="background: #fff"> <TopNavbar /> </a-layout-header>
<a-layout>
<!-- 导航栏-->
<a-layout-header style="background: #fff">
<Navbar />
</a-layout-header>
<!-- 内容区-->
<a-layout-content><router-view></router-view></a-layout-content>
<!-- 脚部-->
<!-- <a-layout-footer>Footer</a-layout-footer>-->
<!-- 日历页-->
<a-layout-sider v-show="collapsed" style="background: #fff"><Left /></a-layout-sider>
<a-layout>
<a-layout-sider class="project-detail"><ProjectDetail /></a-layout-sider>
<a-layout>
<!-- 导航栏-->
<a-layout-header style="background: #fff">
<Navbar />
</a-layout-header>
<!-- 内容区-->
<a-layout-content><router-view></router-view></a-layout-content>
<!-- 脚部-->
<!-- <a-layout-footer>Footer</a-layout-footer>-->
</a-layout>
</a-layout>
</a-layout>
</a-layout>
</a-config-provider>
@ -21,13 +30,36 @@
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
import { useRoute, useRouter } from 'vue-router';
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import Left from 'components/tall/left/Index.vue';
import Navbar from 'components/tall/top/Navbar.vue';
import TopNavbar from 'components/tall/top/TopNavbar.vue';
import ProjectDetail from 'components/tall/center/ProjectDetail.vue';
const locale = zhCN;
const store = useStore();
const collapsed = computed(() => store.state.layout.display.left); //
// queryu token
const route = useRoute();
const router = useRouter();
useRouter()
.isReady()
.then(async () => {
const u = computed(() => route.query.u);
if (!u.value) {
// urlu,
console.log('缺少参数');
router.push({ path: '/user/signIn' });
} else {
// userId token
await store.dispatch('user/getTokenByUserId', u.value);
}
});
const token = computed(() => store.getters['user/token']);
</script>
<style>
@ -37,4 +69,28 @@ body,
#app > section {
height: 100%;
}
.ant-layout-header {
height: 48px;
line-height: 48px;
padding: 0 16px;
border-bottom: 1px solid #cccccc;
}
.ant-layout-sider {
width: 300px !important;
max-width: 300px !important;
min-width: 300px !important;
border-right: 1px solid #cccccc;
flex: 0 0 300px !important;
}
.project-detail {
width: 400px !important;
max-width: 400px !important;
min-width: 400px !important;
border-right: 1px solid #cccccc;
flex: 0 0 400px !important;
background: #fff;
}
</style>

4
src/apis/index.js

@ -4,7 +4,11 @@ import http from 'utils/axios';
const apiUrl = import.meta.env.VITE_API_URL;
const users = `${apiUrl}/gateway/tall3/v3.0/users`;
const tall = `${apiUrl}/gateway/tall3/v3.0`;
// 根据userId 获取token
// eslint-disable-next-line import/prefer-default-export
export const getToken = userId => http.get(`${users}/userId`, { params: { userId } });
// 获取项目列表
export const getProjects = (startTime, endTime) => http.post(`${tall}/project/query`, { startTime, endTime });

191
src/components/tall/center/ProjectDetail.vue

@ -0,0 +1,191 @@
<template>
<div class="navbar flex items-center justify-between">
<div class="project-name">项目名称</div>
<div class="project-action">
<img />
<img @click="toShowMask" />
</div>
</div>
<div class="role-list flex items-center">
<div class="role-box relative">
<div class="role-name">角色名称</div>
<div class="line-box absolute flex justify-center"><div class="line"></div></div>
</div>
</div>
<div class="global">
<div class="global-box">
<div class="global-task">任务1</div>
<div class="global-task">任务1</div>
<div class="global-task">任务1</div>
<div class="global-task">任务1</div>
</div>
</div>
<div class="task-list">
<div class="task-box">
<div class="task-time flex items-center justify-between">
<div class="flex items-center">
<img />
<span>10 09:00</span>
</div>
<div class="task-action"></div>
</div>
<div class="task-info">
<div>
<div class="task-card">
<div class="task-name">任务名</div>
<div class="task-con">
<div>
<a-checkbox @change="onChange"><span class="child-project-name">子课题负责人1 穿戴式运动捕获单元</span></a-checkbox>
</div>
<div>
<a-checkbox @change="onChange"><span class="child-project-name">子课题负责人1 穿戴式运动捕获单元</span></a-checkbox>
</div>
<div>
<a-checkbox @change="onChange"><span class="child-project-name">子课题负责人1 穿戴式运动捕获单元</span></a-checkbox>
</div>
<div>
<a-checkbox @change="onChange"><span class="child-project-name">子课题负责人1 穿戴式运动捕获单元</span></a-checkbox>
</div>
<div>
<a-checkbox @change="onChange"><span class="child-project-name">子课题负责人1 穿戴式运动捕获单元</span></a-checkbox>
</div>
</div>
<div class="open-icon" @click="openCard">
<img />
</div>
</div>
</div>
</div>
</div>
<div class="task-box">
<div class="task-time flex items-center justify-between">
<div class="flex items-center">
<img />
<span>10 09:00</span>
</div>
<div class="task-action"></div>
</div>
<div class="task-info">
<div>
<div class="task-card">
<div class="task-name">任务名</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup></script>
<style scoped>
.navbar {
padding: 0 16px;
height: 44px;
}
.project-name {
font-size: 16px;
font-weight: 600;
color: #333;
}
.role-list {
padding: 0 16px;
height: 36px;
border-bottom: 1px solid #cccccc;
}
.role-box {
height: 36px;
}
.role-name {
font-size: 14px;
line-height: 36px;
font-weight: 600;
color: #1890ff;
}
.role-box .line-box {
width: 100%;
bottom: 0;
}
.line-box .line {
width: 16px;
height: 2px;
background-color: #1890ff;
}
.global {
padding: 16px;
}
.global-box {
border: 1px solid #cccccc;
border-radius: 10px;
padding: 12px 16px;
}
.global-task {
padding: 8px 0;
}
.task-list {
padding: 0 16px;
}
.task-box {
}
.task-time {
height: 32px;
}
.task-time img {
width: 23px;
height: 23px;
margin-right: 16px;
}
.task-time span {
font-size: 14px;
color: #595959;
}
.task-info {
margin: 8px 0;
padding-left: 11px;
}
.task-info > div {
padding-left: 27px;
border-left: 1px solid #d2d2d2;
}
.task-info .task-card {
padding: 16px;
border-radius: 8px;
-moz-box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.12);
-webkit-box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.12);
box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.12);
}
.task-con {
margin-top: 16px;
}
.task-con > div {
height: 30px;
}
.child-project-name {
color: #607d8b;
}
</style>

22
src/components/tall/left/Calendar.vue

@ -1,7 +1,7 @@
<template>
<a-calendar v-model="date" :fullscreen="false" @panelChange="onPanelChange" @select="onSelectDate">
<template #headerRender="{ value: current, onChange }">
<div style="padding: 10px">
<div style="padding: 16px">
<a-row type="flex" justify="space-between">
<a-col>
<a-select
@ -43,11 +43,14 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, defineEmits } from 'vue';
import dayjs from 'dayjs';
const date = ref();
const emit = defineEmits(['changeTime']);
const onPanelChange = (value, mode) => {
console.log(value, mode);
console.log('1111111', value, mode);
};
const getMonths = value => {
@ -73,7 +76,18 @@ const getYears = value => {
};
function onSelectDate(event) {
console.log(event);
const year = event.$y;
const month = event.$M === 12 ? 1 : event.$M + 1;
const day = event.$D;
const startTime = dayjs(`${year}-${month}-${day} ${0}:${0}:${0}`).format('x');
const endTime = dayjs(`${year}-${month}-${day} ${23}:${59}:${59}`).format('x');
const timeObj = {
startTime,
endTime,
};
emit('changeTime', timeObj);
}
</script>

33
src/components/tall/left/Index.vue

@ -1,11 +1,42 @@
<template>
<Calendar />
<Calendar @changeTime="changeTime" />
<Projects />
</template>
<script setup>
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import { getProjects } from 'apis';
import Calendar from './Calendar.vue';
import Projects from './Projects.vue';
const store = useStore();
//
const getProjectsList = async (startTime, endTime) => {
const params = { param: { startTime, endTime } };
try {
const res = await getProjects(params);
if (res.err) {
console.error('err: ', res.err);
} else {
res.data.forEach(item => {
item.show = false;
});
store.commit('projects/setProjects', res.data);
}
} catch (error) {
console.log(error);
}
};
getProjectsList(dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x'));
function changeTime(data) {
getProjectsList(data.startTime, data.endTime);
}
</script>
<script>

142
src/components/tall/left/Projects.vue

@ -1,5 +1,141 @@
<template>项目列表</template>
<template>
<a-divider />
<div class="project-list">项目列表</div>
<div class="list-flex">
<div class="item-box">
<div class="one-level h-70 cursor-pointer flex items-center" @click="toDetail()">
<div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail">
<div class="name-box flex items-center">
<div class="name truncate">项目名称</div>
<div class="precent">50%</div>
</div>
<script setup></script>
<div class="time">11-21 00:00 11-21 23.59</div>
</div>
<style scoped></style>
<div class="right" @click.stop="openMenu">
<img src="" />
<img src="" />
</div>
</div>
<div class="two-box">
<div class="two-flex">
<div class="two-level h-70 cursor-pointer flex items-center" @click="toDetail()">
<div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail">
<div class="name-box flex items-center">
<div class="name truncate">项目名称</div>
<div class="precent">50%</div>
</div>
<div class="time">11-21 00:00 11-21 23.59</div>
</div>
<div class="right" @click.stop="openMenu">
<img src="" />
<img src="" />
</div>
</div>
<div class="three-box">
<div class="three-level h-70 cursor-pointer flex items-center" @click="toDetail()">
<div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail">
<div class="name-box flex items-center">
<div class="name truncate">项目名称</div>
<div class="precent">50%</div>
</div>
<div class="time">11-21 00:00 11-21 23.59</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
// import { useStore } from 'vuex';
// const store = useStore();
function toDetail() {}
</script>
<script>
export default { name: 'Projects' };
</script>
<style scoped>
.ant-divider-horizontal {
height: 16px;
background: #eeeeee;
margin: 0;
}
.project-list {
padding: 16px 0;
}
.h-70 {
height: 70px;
}
.one-level {
padding: 0 16px;
}
.two-level {
padding: 0 16px 0 32px;
}
.three-level {
padding: 0 16px 0 48px;
}
.item-box .icon {
margin-right: 8px;
width: 24px;
height: 24px;
}
.detail {
width: calc(100% - 76px);
}
.name-box {
margin-bottom: 8px;
}
.name {
margin-right: 8px;
font-size: 14px;
line-height: 1;
font-weight: 600;
max-width: calc(100% - 56px);
}
.precent {
width: 48px;
height: 18px;
line-height: 18px;
text-align: center;
border-radius: 18px;
background-color: rgba(24, 144, 255, 0.2);
color: #1890ff;
font-size: 12px;
font-weight: 600;
}
.time {
font-size: 12px;
color: #999999;
}
.right {
width: 14px;
margin-left: 30px;
}
</style>

24
src/components/tall/top/Navbar.vue

@ -1,20 +1,14 @@
<template>
<menu-unfold-outlined v-if="collapsed" @click="toggleCollapse" />
<menu-fold-outlined v-else class="trigger" @click="toggleCollapse" />
<h1>课题数据库</h1>
<h1>课题数据库444444444</h1>
</template>
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
// eslint-disable-next-line import/no-extraneous-dependencies
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
<script setup></script>
const store = useStore();
const collapsed = computed(() => store.state.layout.display.left); //
// toggle left window display
function toggleCollapse() {
store.commit('layout/setDisplay', { prop: 'left', show: !collapsed.value });
<style scoped>
h1 {
font-size: 16px;
font-weight: 600;
color: #666666;
margin: 0;
}
</script>
</style>

33
src/components/tall/top/TopNavbar.vue

@ -0,0 +1,33 @@
<template>
<div class="flex justify-between items-center">
<h1 class="">实验平台</h1>
<div>
<menu-unfold-outlined v-if="collapsed" @click="toggleCollapse" />
<menu-fold-outlined v-else class="trigger" @click="toggleCollapse" />
用户信息
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
// eslint-disable-next-line import/no-extraneous-dependencies
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
const store = useStore();
const collapsed = computed(() => store.state.layout.display.left); //
// toggle left window display
function toggleCollapse() {
store.commit('layout/setDisplay', { prop: 'left', show: !collapsed.value });
}
</script>
<style scoped>
h1 {
font-size: 16px;
font-weight: 600;
margin: 0;
}
</style>

1
src/main.js

@ -4,7 +4,6 @@ import 'virtual:windi.css';
import { createApp } from 'vue';
// eslint-disable-next-line no-unused-vars
import dayjs from 'utils/dayjs';
import App from './App.vue';
import router from './routers/index';
import store from './store/index';

82
src/store/tall/projects/projects.js

@ -0,0 +1,82 @@
export default {
namespaced: true,
state: {
project: { name: '加载中...' }, // 当前项目信息
projects: [], // 项目列表
dotList: [], // 小红点
},
getters: {
/**
* 当前项目的id
* @param {object} project
*/
projectId({ project }) {
return project.id;
},
},
mutations: {
/**
* 设置state projects书籍
* @param {object} state
* @param {array} projects 项目列表
*/
setProjects(state, projects) {
if (!projects || !projects.length) {
state.projects = [];
} else {
state.projects = [...projects];
}
},
/**
* 设置子项目收缩展开
* @param { object } state
* @param { object } options options:{ index,show }
*/
setProjectItemShow(state, options) {
if (options.show) {
for (let i = 0; i < state.projects.length; i++) {
if (i === options.index) {
state.projects[i].show = true;
} else {
state.projects[i].show = false;
}
}
} else {
state.projects[options.index].show = false;
}
},
/**
* 设置当前项目信息
* @param { object } state
* @param { object } data
*/
setProject(state, data) {
state.project = data || { name: '加载中...' };
},
/**
* 设置当前项目名称
* @param { object } state
* @param { string } data
*/
setProjectName(state, data) {
state.project.name = data;
},
/**
* 设置小红点
* @param { object } state
* @param { string } data
*/
setDotList(state, data) {
state.dotList = data;
},
},
actions: {},
};

24
src/views/home/Index.vue

@ -1,12 +1,26 @@
<template>
<div>
<div>左边 时间轴</div>
<div>
<div class="task-detail">
<div class="task-con">任务详情页</div>
<!-- <div>
<router-view></router-view>
</div>
</div> -->
</div>
</template>
<script setup></script>
<style scoped></style>
<style scoped>
.task-detail {
width: 100%;
height: 100%;
padding: 15px 12px;
}
.task-con {
width: 100%;
height: 500px;
background-color: #fff;
border-radius: 10px;
border: 1px solid #cccccc;
}
</style>

4
src/views/user/SignIn.vue

@ -1,3 +1,5 @@
<template>登录</template>
<template>
<div>登录</div>
</template>
<script setup></script>

8552
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save