Browse Source

fix: 上下滑动加载定期任务

tall
lucky 4 years ago
parent
commit
4090d892cd
  1. 10
      CHANGELOG.md
  2. 206
      src/components/Roles/Roles.vue
  3. 225
      src/components/Roles/component/RoleList.vue
  4. 33
      src/components/TimeLine/TimeLine.vue
  5. 8
      src/components/TimeLine/component/TimeBox.vue
  6. 29
      src/pages/project/project.vue
  7. 15
      src/store/home/mutations.js
  8. 2
      src/store/home/state.js

10
CHANGELOG.md

@ -19,6 +19,7 @@
- | indexedDB | [687394e](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/687394e)
- | post 封装 | [da52e94](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/da52e94)
- | tall插件封装 | [1bcb920](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/1bcb920)
- | ws storage | [21b3a06](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/21b3a06)
富文本插件 | 富文本插件demo测试 | [ed3d644](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/ed3d644)
pinch | alloy finger实现图片的pinch放大缩小 | [de01343](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/de01343)
@ -42,6 +43,7 @@
### 🐛 Bug 修复
范围|描述|commitId
--|--|--
- | 定期任务接口 | [aa4981c](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/aa4981c)
- | 骨架屏替换 | [e9fdd71](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/e9fdd71)
- | 角色栏修改 | [19228d6](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/19228d6)
- | 上下滚动时间轴 | [d533a01](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/d533a01)
@ -78,13 +80,6 @@
### chore
范围|描述|commitId
--|--|--
- | api 封装 | [8dcb8a2](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/8dcb8a2)
- | env host修改 | [a79a4a5](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/a79a4a5)
- | merge globals | [b0957cc](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/b0957cc)
- | mock | [51c24a5](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/51c24a5)
pwa 小程序 | 移除了pwa,alloyFinger添加平台判断 | [875fab4](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/875fab4)
- | uview-ui | [a9ea34b](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/a9ea34b)
信息配置 | 配置eslint等配置 | [7421443](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/7421443)
- | api 封装 | [8dcb8a2](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/8dcb8a2)
- | env host修改 | [a79a4a5](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/a79a4a5)
- | merge globals | [b0957cc](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/b0957cc)
@ -99,3 +94,4 @@
- | style:index | [978f272](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/978f272)
- | !2 基础模板v1.1.0 | [f5e61dd](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/f5e61dd)
- | init | [c0f1deb](https://dd.tall.wiki/gitea/wally/TALL-MUI-3/commits/c0f1deb)

206
src/components/Roles/Roles.vue

@ -1,25 +1,215 @@
<template>
<view class="wrap bg-white px-2">
<role-list @getTasks="getTasks" />
<view class="home-box u-skeleton">
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x>
<view class="tab-box">
<view :key="index" @click="changeIndex(item.id, index)" class="tab-item" v-for="(item, index) in roles">
<view :class="setColor(item.mine, item.id)" class="tab-children u-skeleton-fillet">{{ item.name }}</view>
</view>
</view>
</scroll-view>
</view>
<u-skeleton :animation="true" :loading="loading" bg-color="#fff"></u-skeleton>
</view>
</template>
<script>
import RoleList from './component/RoleList';
import { mapState, mapMutations, mapActions } from 'vuex';
export default {
name: 'Roles',
components: { RoleList },
data() {
return {};
return {
tabIndex: 0, //访 index 0
tabList: [], //tab dom
scrollLeft: 0, //scrollview
loading: false, //
roles: [
{
id: 1,
name: '项目经理',
mine: 0,
pm: 1,
sequence: 1,
},
{
id: 2,
name: '运维',
mine: 0,
pm: 0,
sequence: 2,
},
],
};
},
computed: { ...mapState('home', ['visibleRoles', 'roleId', 'tasks']) },
watch: {
visibleRoles(val) {
if (val && val.length) {
this.roles = [...this.visibleRoles];
this.loading = false;
}
},
},
mounted() {
if (!this.visibleRoles || !this.visibleRoles.length) {
this.loading = true;
} else {
this.roles = [...this.visibleRoles];
}
},
methods: {
getTasks(query) {
console.log('query: ', query);
this.$emit('getTasks', query);
...mapMutations('home', ['setRoleId', 'setTasks']),
...mapActions('home', ['handleRegularTask']),
//
setCurrentRole(index) {
const data = document.getElementsByClassName('tab-children');
// tabList
data.forEach(item => {
this.tabList.push({
width: item.clientWidth,
left: item.offsetLeft,
});
});
//
let left = 0;
let screenWidth = window.screen.width;
for (let i = 0; i < index; i++) {
left += this.tabList[i].width + this.tabList[i].left * 2;
}
left += this.tabList[index].width;
this.scrollLeft = left - screenWidth / 2;
},
//
async changeIndex(id, index) {
try {
this.setRoleId(id);
//index
this.setCurrentRole(index);
//
this.setTasks([]);
//
await this.$emit('getTasksByRole');
} catch (error) {
console.log('error: ', error);
}
},
//
setColor(mine, id) {
const { roleId } = this;
if (mine === '1' && roleId === id) {
return 'default-tab-choice';
}
if (mine === '1' && roleId !== id) {
return 'default-tab-item';
}
if (mine === '0' && roleId === id) {
return 'tab-choice';
}
},
},
};
</script>
<style scoped lang="scss"></style>
<style lang="scss" scoped>
.home-box {
// sticky
position: sticky;
top: 0;
background: #fff; //
/* #ifdef H5 */
// h5 44px
top: 88rpx;
/* #endif */
.tab-box {
position: relative;
white-space: nowrap;
// height: 84rpx;
.tab-item {
// width: 20%;
// height: 84rpx;
padding: 20rpx 24rpx;
position: relative;
display: inline-block;
text-align: center;
font-size: 30rpx;
transition-property: background-color, width;
}
.default-tab-item {
color: $roleChoiceColor;
}
.default-tab-choice {
//
position: relative;
color: $roleChoiceColor;
font-weight: 600;
}
.default-tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $roleChoiceColor;
}
.tab-choice {
//
position: relative;
color: $uni-color-primary;
font-weight: 600;
}
.tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $uni-color-primary;
}
}
}
// //
/* #ifndef APP-NVUE */
::-webkit-scrollbar,
::-webkit-scrollbar,
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* #endif */
/* #ifdef H5 */
// 穿H5scroll-view
scroll-view ::v-deep ::-webkit-scrollbar {
display: none;
}
/* #endif */
.skeleton {
height: 44rpx;
}
</style>

225
src/components/Roles/component/RoleList.vue

@ -1,225 +0,0 @@
<template>
<view>
<view class="home-box u-skeleton">
<scroll-view :enable-flex="true" :scroll-left="scrollLeft" :throttle="false" scroll-with-animation scroll-x>
<view class="tab-box">
<view :key="index" @click="changeIndex(item.id, index)" class="tab-item" v-for="(item, index) in roles">
<view :class="setColor(item.mine, item.id)" class="tab-children u-skeleton-fillet">{{ item.name }}</view>
</view>
</view>
</scroll-view>
</view>
<u-skeleton :animation="true" :loading="loading" bg-color="#fff"></u-skeleton>
</view>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
export default {
name: 'RoleList',
data() {
return {
tabIndex: 0, //访 index 0
tabList: [], //tab dom
scrollLeft: 0, //scrollview
loading: false, //
roles: [
{
id: 1,
name: '项目经理',
mine: 0,
pm: 1,
sequence: 1,
},
{
id: 2,
name: '运维',
mine: 0,
pm: 0,
sequence: 2,
},
],
};
},
computed: { ...mapState('home', ['visibleRoles', 'roleId', 'tasks']) },
watch: {
visibleRoles(val) {
if (val && val.length) {
this.roles = [...this.visibleRoles];
this.loading = false;
}
},
},
mounted() {
if (!this.visibleRoles || !this.visibleRoles.length) {
this.loading = true;
}
},
methods: {
...mapMutations('home', ['setRoleId']),
...mapActions('home', ['handleRegularTask']),
setCurrentRole(index) {
const data = document.getElementsByClassName('tab-children');
// tabList
data.forEach(item => {
this.tabList.push({
width: item.clientWidth,
left: item.offsetLeft,
});
});
//
let left = 0;
let screenWidth = window.screen.width;
for (let i = 0; i < index; i++) {
left += this.tabList[i].width + this.tabList[i].left * 2;
}
left += this.tabList[index].width;
this.scrollLeft = left - screenWidth / 2;
},
async changeIndex(id, index) {
this.setRoleId(id);
//index
this.setCurrentRole(index);
//
await this.$emit('getTasks', { queryType: 0 });
await this.$emit('getTasks', { queryType: 1 });
console.log('this.tasks && this.tasks.length: ', this.tasks && this.tasks.length);
if (this.tasks && this.tasks.length) {
debugger;
//
const upQuery = {
timeNode: +this.tasks[0].planStart,
queryType: 0,
queryNum: 6,
};
console.log('upQuery: ', upQuery);
await this.$emit('getTasks', upQuery);
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
queryType: 0,
queryNum: 6,
};
console.log('downQuery: ', downQuery);
await this.$emit('getTasks', downQuery);
}
},
//
setColor(mine, id) {
const { roleId } = this;
if (mine === '1' && roleId === id) {
return 'default-tab-choice';
}
if (mine === '1' && roleId !== id) {
return 'default-tab-item';
}
if (mine === '0' && roleId === id) {
return 'tab-choice';
}
},
},
};
</script>
<style lang="scss" scoped>
.home-box {
// sticky
position: sticky;
top: 0;
background: #fff; //
/* #ifdef H5 */
// h5 44px
top: 88rpx;
/* #endif */
.tab-box {
position: relative;
white-space: nowrap;
// height: 84rpx;
.tab-item {
// width: 20%;
// height: 84rpx;
padding: 20rpx 24rpx;
position: relative;
display: inline-block;
text-align: center;
font-size: 30rpx;
transition-property: background-color, width;
}
.default-tab-item {
color: $roleChoiceColor;
}
.default-tab-choice {
//
position: relative;
color: $roleChoiceColor;
font-weight: 600;
}
.default-tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $roleChoiceColor;
}
.tab-choice {
//
position: relative;
color: $uni-color-primary;
font-weight: 600;
}
.tab-choice:before {
content: '';
position: absolute;
left: 0;
bottom: -20rpx;
width: 100%;
height: 6rpx;
border-radius: 2rpx;
background: $uni-color-primary;
}
}
}
// //
/* #ifndef APP-NVUE */
::-webkit-scrollbar,
::-webkit-scrollbar,
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* #endif */
/* #ifdef H5 */
// 穿H5scroll-view
scroll-view ::v-deep ::-webkit-scrollbar {
display: none;
}
/* #endif */
.skeleton {
height: 44rpx;
}
</style>

33
src/components/TimeLine/TimeLine.vue

@ -8,6 +8,7 @@
<template>
<!-- 时间间隔栏 -->
<!-- <Barrier /> -->
<scroll-view
:lower-threshold="300"
:scrollTop="top"
@ -19,7 +20,9 @@
id="scroll"
>
<!-- 时间轴 -->
<u-divider bg-color="#f3f4f6" v-if="topEnd">到顶啦</u-divider>
<TimeBox />
<u-divider bg-color="#f3f4f6" v-if="bottomEnd">到底啦</u-divider>
</scroll-view>
</template>
@ -34,7 +37,11 @@ export default {
return { top: 0 };
},
computed: mapState('home', ['scrollTop', 'showTips', 'visibleRoles', 'tasks']),
computed: mapState('home', ['scrollTop', 'showTips', 'visibleRoles', 'tasks', 'topEnd', 'bottomEnd']),
mounted() {
this.setDatumPoint();
},
methods: {
...mapMutations('home', ['setScrollTop', 'setShrink', 'setRoleId']),
@ -47,15 +54,26 @@ export default {
},
//
handleScrollTop() {
console.log('滚动到顶部');
this.$emit('getTasks', { queryType: 0 });
async handleScrollTop() {
if (this.topEnd) return;
const upQuery = {
timeNode: +this.tasks[0].planStart,
queryType: 0,
queryNum: 6,
};
await this.$emit('getTasks', upQuery);
},
//
handleScrollBottom() {
console.log('滚动到底部');
this.$emit('getTasks', { queryType: 1 });
async handleScrollBottom() {
if (this.bottomEnd) return;
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
queryType: 1,
queryNum: 6,
};
console.log('downQuery: ', downQuery);
await this.$emit('getTasks', downQuery);
},
//
@ -71,6 +89,7 @@ export default {
// }
}
this.top = tasksHeight - scrollHeight / 2;
console.log('this.top: ', this.top);
}
},
},

8
src/components/TimeLine/component/TimeBox.vue

@ -4,8 +4,8 @@
<view class="flex items-center">
<TimeStatus :content="JSON.stringify(item.process)" :status="item.process" />
<view class="flex justify-between flex-1 ml-2">
<view>{{ $u.timeFormat(+item.planStart, 'mm-dd hh:MM') }}</view>
<!-- {{ $u.timeFormat(+item.planDuration, false) }} -->
<view>{{ +item.planStart | date('mm-dd hh:MM') }}</view>
<!-- {{ item.planDuration }} -->
<view>
<view class="flex justify-between" style="min-width: 180rpx">
<u-icon custom-prefix="custom-icon" name="C-bxl-redux" size="34"></u-icon>
@ -21,7 +21,7 @@
<!-- 任务面板插件 -->
<view slot="body">
<view :key="pluginIndex" class="p-0 u-col-between u-skeleton" v-for="(plugin, pluginIndex) in item.plugins">
<view :key="p.pluginId" v-for="p in plugin">
<!-- <view :key="p.pluginId" v-for="p in plugin">
<p-task-title :item="item" v-if="p.pluginId === 1" />
<p-task-description :item="item" v-if="p.pluginId === 2" />
<p-task-duration-delay :item="item" v-if="p.pluginId === 3" />
@ -30,7 +30,7 @@
<p-subtasks :item="item" v-if="p.pluginId === 6" />
<p-subproject :item="item" v-if="p.pluginId === 7" />
<p-task-countdown :item="item" v-if="p.pluginId === 8" />
</view>
</view>-->
</view>
</view>
</u-card>

29
src/pages/project/project.vue

@ -2,7 +2,7 @@
<view :style="{ height: height }" class="flex flex-col overflow-hidden">
<Title />
<view class="container flex flex-col flex-1 overflow-hidden bg-gray-100">
<Roles @getTasks="getTasks" />
<Roles @getTasksByRole="getTasksByRole" />
<Globals :plugins="plugins" />
<TimeLine @getTasks="getTasks" class="flex-1 overflow-hidden" ref="child" />
</view>
@ -44,9 +44,7 @@ export default {
await this.getGlobal();
//
if (this.tasks && this.tasks.length) {
console.log('this.tasks[0].planStart: ', this.tasks[0].planStart);
await this.getTasks({ timeNode: +this.tasks[0].planStart, queryType: 0, queryNum: 6 });
console.log('this.tasks[this.tasks.length - 1].planStart: ', this.tasks[this.tasks.length - 1].planStart);
await this.getTasks({ timeNode: +this.tasks[this.tasks.length - 1].planStart, queryType: 1, queryNum: 6 });
}
},
@ -98,10 +96,8 @@ export default {
params.timeUnit = query.timeUnit || timeUnit;
params.queryNum = query.queryNum || 3;
params.queryType = query.queryType;
console.log('params: ', params);
const res = await this.handleRegularTask(params);
query.queryType === 0 ? this.setUpTasks(res) : this.setDownTasks(res);
this.$refs.child.setDatumPoint();
} catch (error) {
console.log('error: ', error);
}
@ -141,6 +137,29 @@ export default {
console.log('error: ', error);
}
},
//
async getTasksByRole() {
try {
await this.getTasks({ queryType: 0 });
await this.getTasks({ queryType: 1 });
//
const upQuery = {
timeNode: +this.tasks[0].planStart,
queryType: 0,
queryNum: 6,
};
await this.getTasks(upQuery);
const downQuery = {
timeNode: +this.tasks[this.tasks.length - 1].planStart,
queryType: 1,
queryNum: 6,
};
await this.getTasks(downQuery);
} catch (error) {
console.log('error: ', error);
}
},
},
};
</script>

15
src/store/home/mutations.js

@ -122,6 +122,9 @@ const mutations = {
* @param {Array} data 服务端返回的模板数组
*/
setUpTasks(state, data) {
if (!data || !data.length) {
state.topEnd = true;
}
state.tasks = [...data.concat(state.tasks)] || [];
},
@ -131,9 +134,21 @@ const mutations = {
* @param {Array} data 服务端返回的模板数组
*/
setDownTasks(state, data) {
if (!data || !data.length) {
state.bottomEnd = true;
}
state.tasks = [...state.tasks.concat(data)] || [];
},
/**
* 清空定期任务数据
* @param {Object} state
* @param {Array} data 服务端返回的模板数组
*/
setTasks(state, data) {
state.tasks = data || [];
},
/**
* 设置日常任务数据
* @param {Object} state

2
src/store/home/state.js

@ -30,6 +30,8 @@ const state = {
{ id: 11, value: '千年' },
],
tasks: [], // 定期任务
topEnd: false, // 时间轴向上查任务到顶了
bottomEnd: false, // 时间轴向下查任务到底了
dailyTasks: [], // 日常任务
};

Loading…
Cancel
Save