Browse Source

feat: 项目列表, 项目url

develop
wally 4 years ago
parent
commit
32e005bbaf
  1. 3
      CHANGELOG.md
  2. 20
      src/App.vue
  3. 9
      src/apis/plugin.js
  4. 7
      src/apis/project.js
  5. 6
      src/apis/role.js
  6. 3
      src/apis/tall.js
  7. 12
      src/apis/task.js
  8. 7
      src/apis/wbs.js
  9. 203
      src/components/Projects/Projects.vue
  10. 44
      src/components/Upload/Upload.vue
  11. 4
      src/main.js
  12. 68
      src/pages/index/index.vue
  13. 4
      src/pages/project/project.vue
  14. 13
      src/store/project/mutations.js
  15. 1
      src/store/project/state.js
  16. 2
      src/store/user/actions.js
  17. 1
      src/utils/tall.js
  18. 18
      tailwind.config.js

3
CHANGELOG.md

@ -1,4 +1,4 @@
# 0.1.0 (2021-08-05)
# 0.1.0 (2021-08-06)
### 🌟 新功能
范围|描述|commitId
@ -18,6 +18,7 @@
- | 存token | b8a178d
- | 定期任务面板骨架屏添加 | b2698c0
富文本插件 | 富文本插件demo测试 | ed3d644
- | 导入wbs | 1224fcb
- | 引入dayjs | 29b8b93
- | 提交到本地 | 9cbe411
- | 插件参数处理调整 | a3e68d3

20
src/App.vue

@ -1,7 +1,19 @@
<script>
import { mapActions, mapState } from 'vuex';
export default {
onLaunch: function () {
console.log('App Launch');
async onLaunch(options) {
console.log('App Launch', options);
if (!this.token) {
// tokenuserIdtoken
// token userId
if (!options.query || !options.query.u) {
// u (userId)
this.$t.ui.showToast('缺少用户信息参数');
} else {
await this.getToken(options.query.u);
}
}
},
onShow: function () {
console.log('App Show');
@ -9,6 +21,10 @@ export default {
onHide: function () {
console.log('App Hide');
},
computed: mapState('user', ['token']),
methods: { ...mapActions('user', ['getToken']) },
};
</script>

9
src/apis/plugin.js

@ -1,12 +1,7 @@
import domain from '@/config/domains';
const apiUrl = process.env.VUE_APP_API_URL;
const mock = `${apiUrl}${domain}`;
const plugin = `${apiUrl}/pluginshop/plugin`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
vm.$u.api.getPlugin = param => vm.$u.post(`${mock}/plugin`, param);
vm.$u.api.getOtherPlugin = param => vm.$u.post(`${plugin}/query`, param);
vm.$u.api.getPlugin = param => vm.$u.post(`${uni.$t.domain}/plugin`, param);
vm.$u.api.getOtherPlugin = param => vm.$u.post(`${uni.$t.domain}/pluginshop/plugin/query`, param);
};
export default { install };

7
src/apis/project.js

@ -1,12 +1,7 @@
const apiUrl = process.env.VUE_APP_API_URL;
import domainPath from '@/config/domains';
const tall = `${apiUrl}${domainPath}`;
const project = `${tall}/project`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
//根据id获取项目信息
vm.$u.api.findProjectById = param => vm.$u.post(`${project}/findProjectById`, param);
vm.$u.api.findProjectById = param => vm.$u.post(`${uni.$t.domain}/project/findProjectById`, param);
};
export default { install };

6
src/apis/role.js

@ -1,11 +1,7 @@
const apiUrl = process.env.VUE_APP_API_URL;
import domain from '@/config/domains';
const role = `${apiUrl}${domain}/role`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
//根据时间基准点和角色查找定期任务
vm.$u.api.findShowRole = param => vm.$u.post(`${role}/show`, param);
vm.$u.api.findShowRole = param => vm.$u.post(`${uni.$t.domain}/role/show`, param);
};
export default { install };

3
src/apis/user.js → src/apis/tall.js

@ -3,7 +3,10 @@ const tall = `${apiUrl}/tall/v1.0`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
// 根据userId获取token
vm.$u.api.getToken = userId => vm.$u.get(`${tall}/users/userId`, { userId });
// 获取项目列表
vm.$u.api.getProjects = (startTime, endTime) => vm.$u.post(`${tall}/project/query`, { startTime, endTime });
};
export default { install };

12
src/apis/task.js

@ -1,15 +1,11 @@
const apiUrl = process.env.VUE_APP_API_URL;
import domain from '@/config/domains';
const task = `${apiUrl}${domain}/task`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
vm.$u.api.getGlobal = param => vm.$u.post(`${task}/global`, param);
vm.$u.api.getPermanent = param => vm.$u.post(`${task}/permanent`, param);
vm.$u.api.getGlobal = param => vm.$u.post(`${uni.$t.domain}/task/global`, param);
vm.$u.api.getPermanent = param => vm.$u.post(`${uni.$t.domain}/task/permanent`, param);
//根据时间基准点和角色查找定期任务
vm.$u.api.getRegularTask = param => vm.$u.post(`${task}/regular`, param);
vm.$u.api.getRegularTask = param => vm.$u.post(`${uni.$t.domain}/task/regular`, param);
//修改任务状态
vm.$u.api.updateTaskType = param => vm.$u.post(`${task}/type`, param);
vm.$u.api.updateTaskType = param => vm.$u.post(`${uni.$t.domain}/task/type`, param);
};
export default { install };

7
src/apis/wbs.js

@ -1,12 +1,7 @@
const apiUrl = process.env.VUE_APP_API_URL;
import domainPath from '@/config/domains';
const tall = `${apiUrl}${domainPath}`;
const wbs = `${tall}/wbs`;
const install = (Vue, vm) => {
vm.$u.api = { ...vm.$u.api } || {};
// 导入wbs
vm.$u.api.import = formData => vm.$t.chooseAndUpload(wbs, formData);
vm.$u.api.import = formData => vm.$t.chooseAndUpload(`${uni.$t.domain}/wbs`, formData);
};
export default { install };

203
src/components/Projects/Projects.vue

@ -1,182 +1,71 @@
<template>
<view class="bg-white u-p-t-30 u-p-b-30">
<view class="flex items-center">
<view class="flex items-center justify-center rounded-full event-pic">
<image style="width: 25px; height: 25px" src="../../static/local_play1.png"></image>
</view>
<view class="title">我的LWBS</view>
</view>
<view v-for="(task, index) in tasks" :key="index">
<view>
<view class="py-3 mt-4 bg-white">
<view v-for="(project, index) in projects" :key="index">
<!-- 有子项目 -->
<view class="flex items-center justify-between item" v-if="index <= 2">
<view class="flex items-center">
<view class="text-white rounded-full firstTask" v-if="index === 0">
<view class="flex items-center justify-center">{{ index + 1 }}</view>
</view>
<view class="text-white rounded-full sencondTask" v-else-if="index === 1">
<view class="flex items-center justify-center">{{ index + 1 }}</view>
</view>
<view class="text-white rounded-full thirdTask" v-else-if="index === 2">
<view class="flex items-center justify-center">{{ index + 1 }}</view>
</view>
<view>
<view class="flex items-center">
<view class="title">{{ task.taskName }}</view>
<!-- 状态 -->
<view class="text-green-400 bg-green-100 rounded-full u-p-l-10 u-p-r-10 states">{{ task.state }}</view>
<view class="flex items-center justify-between p-3">
<view class="text-blue-400 border border-blue-200 rounded-full order bg-blue-50">
{{ index + 1 }}
</view>
<view class="flex items-center text-gray-400 dates">
<view class="pr-2">{{ task.time }}</view>
<view>时长{{ task.duration }}</view>
<view class="flex-1 px-3">
<view class="flex items-center mb-1">
<view class="mr-2">{{ project.name }}</view>
<!-- 状态 TODO:-->
<view class="px-2 text-xs text-green-400 bg-green-100 rounded-full">进行中</view>
</view>
<view class="flex items-center text-xs text-gray-400">
<view class="pr-2">{{ $moment(+project.startTime).format('MM-DD HH:mm') }}</view>
<view class="pl-2"> {{ $moment(+project.endTime).format('MM-DD HH:mm') }}</view>
</view>
</view>
<!-- 箭头 -->
<u-icon name="arrow-right" color="#A4A6AB" size="14px" @click="openProjectItem(index)"></u-icon>
</view>
<!-- 没有子项目 -->
<view class="item" v-else>
<view class="flex items-center">
<view class="w-8 h-8 bg-white border rounded-full routine">
<view class="flex items-center justify-center">{{ index + 1 }}</view>
</view>
<view>
<view class="flex items-center">
<view class="title">{{ task.taskName }}</view>
<view class="px-2 text-green-400 bg-green-100 rounded-full states">{{ task.state }}</view>
</view>
<view class="flex items-center text-gray-400 dates">
<view class="pr-2">{{ task.time }}</view>
<view>时长{{ task.duration }}</view>
</view>
</view>
</view>
</view>
<view v-if="isrotate === index">
这是子项目
<ProjectItem />
</view>
<u-icon name="arrow-right" class="text-gray-400" size="14px" @click="openProject(project)"></u-icon>
</view>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex';
export default {
data() {
return {
isrotate: -1,
tasks: [
{
taskName: '山西省三大中心建设',
state: '正在进行',
time: '05月31日 00:00',
duration: '365天',
},
{
taskName: '1号康复室',
state: '正在进行',
time: '01月31日 00:00',
duration: '727天',
},
{
taskName: '盐湖医院远程康复',
state: '正在进行',
time: '05月31日 00:00',
duration: '65天',
},
{
taskName: '山西省三大中心建设',
state: '正在进行',
time: '05月31日 00:00',
duration: '365天',
},
{
taskName: '1号康复室',
state: '正在进行',
time: '01月31日 00:00',
duration: '727天',
},
{
taskName: '盐湖医院远程康复',
state: '正在进行',
time: '05月31日 00:00',
duration: '65天',
},
],
};
return {};
},
computed: mapState('project', ['projects']),
methods: {
//
openProjectItem(index) {
if (this.isrotate === -1) {
this.isrotate = index;
} else {
this.isrotate = -1;
}
/**
* 打开项目
* @param {object} project 所点击的项目的信息
*/
openProject(project) {
console.log('project: ', project);
const { name, id, url } = project;
console.log(uni.$t.domain);
url && (uni.$t.domain = url);
console.log('uni.$t.domain: ', uni.$t.domain);
this.$u.route('pages/project/project', {
p: id,
pname: name,
url: encodeURIComponent(url),
});
},
},
};
</script>
<style lang="scss" scoped>
.firstTask {
background: linear-gradient(45deg, #9000ff, #5e00ff);
width: 32px;
height: 32px;
margin-right: 16px;
line-height: 32px;
font-size: 16px;
text-align: center;
border: 1px solid #eee;
}
.sencondTask {
background: linear-gradient(45deg, #0081ff, #1cbbb4);
width: 32px;
height: 32px;
margin-right: 16px;
line-height: 32px;
font-size: 16px;
text-align: center;
border: 1px solid #eee;
}
.thirdTask {
background: linear-gradient(45deg, #39b54a, #8dc63f);
.order {
display: flex;
justify-content: center;
align-items: center;
width: 32px;
height: 32px;
margin-right: 16px;
line-height: 32px;
font-size: 16px;
text-align: center;
border: 1px solid #eee;
}
.routine {
width: 32px;
height: 32px;
margin-right: 16px;
line-height: 32px;
font-size: 16px;
text-align: center;
border: 1px solid #eee;
}
.event-pic {
margin: 0 14px;
width: 36px;
height: 36px;
background: linear-gradient(45deg, #ff9700, #ed1c24);
}
.title {
font-size: 15px;
margin-right: 12px;
}
.dates {
font-size: 12px;
}
.states {
font-size: 10px;
}
.item {
border-bottom: 1px solid #fafafa;
height: 60px;
padding: 10px 16px;
font-size: 13px;
}
</style>

44
src/components/Upload/Upload.vue

@ -1,48 +1,29 @@
<template>
<view class="upload">
<view @tap="handleUpload">
<u-icon name="plus" color="#ffffff" size="24px" class="flex justify-center rounded-full upload-icon"></u-icon>
<u-icon name="plus" color="#ffffff" size="24px" class="flex justify-center w-12 h-12 bg-blue-100 rounded-full shadow-md"></u-icon>
</view>
<!-- <view v-if="!showUploadList">
<view v-for="(item, index) in lists" :key="index">
<image :src="item.url" mode="aspectFill"></image>
</view>
</view>
<u-upload
ref="uUpload"
:show-upload-list="showUploadList"
:custom-btn="true"
:action="action"
:before-upload="beforeUpload"
max-count="6"
>
<view slot="addBtn" class="flex items-center justify-center rounded-full bg-icon" hover-stay-time="150">
<u-icon name="plus" color="#ffffff" size="24px" class="flex justify-center rounded-full upload-icon"></u-icon>
</view>
</u-upload> -->
</view>
</template>
<script>
export default {
data() {
return {};
},
methods: {
// wbs
async handleUpload() {
try {
const data = await this.$u.api.import();
// TODO:
// WBS
//
console.log('data: ', data);
} catch (error) {
this.$t.ui.showToast(error);
this.$emit('show-alert', error);
}
},
},
};
</script>
<style lang="scss" scoped>
.upload {
position: absolute;
@ -51,14 +32,7 @@ export default {
transform: translate3d(0, 50%, 0);
}
.upload-icon {
background: linear-gradient(45deg, #0081ff, #1cbbb4);
height: 50px;
width: 50px;
}
.bg-icon {
background: white;
height: 50px;
width: 50px;
/deep/ .uicon-plus {
color: theme('colors.blue.500') !important;
}
</style>

4
src/main.js

@ -28,7 +28,7 @@ App.mpType = 'app';
const app = new Vue({ ...App, store });
import request from '@/utils/request.js';
import user from '@/apis/user.js';
import tall from '@/apis/tall.js';
import project from '@/apis/project.js';
import task from '@/apis/task.js';
import plugin from '@/apis/plugin.js';
@ -38,7 +38,7 @@ import wbs from '@/apis/wbs.js';
window.vm = app;
Vue.use(request, app);
Vue.use(user, app);
Vue.use(tall, app);
Vue.use(project, app);
Vue.use(task, app);
Vue.use(plugin, app);

68
src/pages/index/index.vue

@ -2,36 +2,90 @@
<view class="bg-gray-50">
<view class="relative">
<!-- 日历 -->
<Calendar @selected-change="dateChange" :show-back="true" :dot-list="dayss" />
<Calendar @selected-change="onDateChange" :show-back="true" :dot-list="days" />
<!-- 上传 导入wbs -->
<Upload />
<Upload @show-alert="onShowAlert" />
</view>
<!-- 项目列表 -->
<Projects class="u-m-t-30" />
<Projects />
<!-- 全局提示框 -->
<u-alert-tips
class="top-0 -inset-x-0"
style="position: fixed !important"
type="error"
:close-able="true"
:title="alert.title"
:show="alert.show"
:description="alert.description"
@close="alert.show = false"
></u-alert-tips>
</view>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
export default {
data() {
return {
dayss: [
days: [
{ date: '2020-08-14' },
{ date: '2020-08-27' },
{ date: '2020-08-09' },
// {date: '2020-08-16'}
],
alert: {
show: false,
title: '',
description: '',
},
};
},
computed: mapState('user', ['token']),
watch: {
token(value) {
if (!value) return;
this.getProjects();
},
},
onShow() {
console.log('index onShow');
if (!this.token) return;
this.getProjects();
},
methods: {
...mapMutations('project', ['setProjects']),
//
async getProjects(start = this.$moment().startOf('day').valueOf(), end = this.$moment().endOf('day').valueOf()) {
try {
const data = await this.$u.api.getProjects(start, end);
this.setProjects(data);
} catch (error) {
console.log('error: ', error);
}
},
changeList() {
this.dayss = [{ date: '2021-08-03' }, { date: '2021-08-04' }, { date: '2021-08-06' }];
this.days = [{ date: '2021-08-03' }, { date: '2021-08-04' }, { date: '2021-08-06' }];
},
dateChange(e) {
console.log(e);
onDateChange(event) {
console.log(event);
},
// alert
onShowAlert(event) {
this.alert.description = event || '发生了点小意外';
this.alert.show = true;
setTimeout(() => (this.alert.show = false), 10000);
},
},
};

4
src/pages/project/project.vue

@ -69,7 +69,7 @@ export default {
},
methods: {
...mapActions('user', ['getUserId']),
...mapActions('user', ['getToken']),
...mapActions('project', ['getProjectById']),
...mapActions('role', ['getRoles']),
...mapActions('task', ['getRegulars', 'getPermanent', 'getGlobal']),
@ -91,7 +91,7 @@ export default {
// u (userId)
this.$t.ui.showToast('缺少用户信息参数');
} else {
await this.getUserId(options.u);
await this.getToken(options.u);
}
}

13
src/store/project/mutations.js

@ -1,4 +1,17 @@
const 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

1
src/store/project/state.js

@ -1,6 +1,7 @@
/* eslint-disable */
const state = {
project: { name: '加载中...' }, // 当前项目信息
projects: [], // 项目列表
};
export default state;

2
src/store/user/actions.js

@ -4,7 +4,7 @@ const actions = {
* @param {any} commit
* @param {string} userId 用户id
*/
async getUserId({ commit }, userId) {
async getToken({ commit }, userId) {
try {
const res = await uni.$u.api.getToken(userId);
commit('setToken', res.token);

1
src/utils/tall.js

@ -16,6 +16,7 @@ const $t = {
timeConfig, // 时间相关配置
ui, // ui界面提示相关
chooseAndUpload: upload.chooseAndUpload, // 选择并上传单个文件相关的封装
domain: 'https://www.tall.wiki/tall/v3.0.0/defaultwbs',
};
uni.$t = $t;

18
tailwind.config.js

@ -1,7 +1,23 @@
const colors = require('tailwindcss/colors');
module.exports = {
// purge: ['./public/index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: { extend: {} },
theme: {
extend: {},
colors: {
blue: colors.lightBlue,
gray: colors.blueGray,
red: colors.red,
orange: colors.orange,
yellow: colors.yellow,
green: colors.green,
pink: colors.rose,
white: colors.white,
black: '#333',
transparent: 'transparent',
},
},
variants: { extend: {} },
plugins: [],
corePlugins: {

Loading…
Cancel
Save