Browse Source

feat:新增任务列表

dxj
杜贤金 1 year ago
parent
commit
38845f5361
  1. BIN
      src/assets/images/task/dlq.png
  2. BIN
      src/assets/images/task/dot.png
  3. BIN
      src/assets/images/task/history.png
  4. BIN
      src/assets/images/task/money.png
  5. BIN
      src/assets/images/task/qiandao.png
  6. 3
      src/components/AppRoleDefault/index.vue
  7. 8
      src/components/AppTaskMenuList/index.d.ts
  8. 3
      src/components/AppTaskMenuList/index.ts
  9. 99
      src/components/AppTaskMenuList/index.vue
  10. 2
      src/layout/AppMenu/index.vue
  11. 8
      src/router/index.ts
  12. 3
      src/views/task/components/BasicTask/index.ts
  13. 466
      src/views/task/components/BasicTask/index.vue
  14. 3
      src/views/task/components/DailyTask/index.ts
  15. 32
      src/views/task/components/DailyTask/index.vue
  16. 3
      src/views/task/components/NoviceTask/index.ts
  17. 32
      src/views/task/components/NoviceTask/index.vue
  18. 3
      src/views/task/components/OtherTask/index.ts
  19. 32
      src/views/task/components/OtherTask/index.vue
  20. 0
      src/views/task/index.d.ts
  21. 40
      src/views/task/index.vue

BIN
src/assets/images/task/dlq.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
src/assets/images/task/dot.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

BIN
src/assets/images/task/history.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

BIN
src/assets/images/task/money.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

BIN
src/assets/images/task/qiandao.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

3
src/components/AppRoleDefault/index.vue

@ -14,13 +14,14 @@ function getRoleData() {
roleList.value = res
})
}
getRoleData()
//
function getAppData() {
getAppList().then((res) => {
application.value = res
})
}
getRoleData()
getAppData()
//

8
src/components/AppTaskMenuList/index.d.ts vendored

@ -0,0 +1,8 @@
import type { Ref } from 'vue'
export interface Task {
task1: Ref<HTMLElement | null>
task2: Ref<HTMLElement | null>
task3: Ref<HTMLElement | null>
task4: Ref<HTMLElement | null>
}

3
src/components/AppTaskMenuList/index.ts

@ -0,0 +1,3 @@
import AppTaskMenuList from './index.vue'
export { AppTaskMenuList }

99
src/components/AppTaskMenuList/index.vue

@ -0,0 +1,99 @@
<!-- 子菜单列表组件 -->
<script setup lang="ts">
import { inject, ref } from 'vue'
import type { Task } from './index.d'
const sectionRefs = inject<Task>('sectionRefs')
const taskContainer = inject('taskContainer')
const activeIndex = ref(0)
const list = [
{
title: '基础任务',
status: true,
task: 'task1',
},
{
title: '新手任务',
status: false,
task: 'task2',
},
{
title: '每日任务',
status: false,
task: 'task3',
},
{
title: '其他任务',
status: false,
task: 'task4',
},
]
//
function handleClick(index: number, task: string) {
activeIndex.value = index
const target = sectionRefs[task].value.$el.offsetTop - 40
taskContainer.value.scrollTo({
top: target,
behavior: 'smooth',
})
}
</script>
<template>
<div class="app-task-menu-list">
<div
v-for="(item, index) in list"
:key="index"
class="app-task-menu-list-item"
:class="[activeIndex === index && 'app-task-menu-list-item-active']"
@click="handleClick(index, item.task)"
>
<p class="title">
{{ item.title }}
</p>
<div v-show="item.status" class="dot"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
@include app('task-menu-list') {
&-item {
width: 80%;
margin: 5px auto;
padding: 6px;
border-radius: 10px;
transition: all 0.2s;
text-align: center;
cursor: pointer;
color: #888c90;
position: relative;
.title {
font-size: 11px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
line-height: 20px;
margin: 0;
}
.dot {
width: 6px;
height: 6px;
background-color: red;
border-radius: 50%;
position: absolute;
right: 40px;
top: 10px;
}
}
&-item-active {
background: #e1e9f9;
color: #4670e3;
}
&-item:hover {
background: #e1e9f9;
color: #4670e3;
}
}
</style>

2
src/layout/AppMenu/index.vue

@ -29,7 +29,7 @@ const menu = ref<MenuItem[]>([
{
name: '任务',
icon: 'ren_wu',
path: '',
path: '/task',
key: MenuTypeEnum.TASK,
},
])

8
src/router/index.ts

@ -55,6 +55,14 @@ export const constantRoutes: Array<RouteRecordRaw> = [
title: '角色',
},
},
{
name: 'Task',
path: '/Task',
component: () => import('@/views/task/index.vue'),
meta: {
title: '任务',
},
},
],
},

3
src/views/task/components/BasicTask/index.ts

@ -0,0 +1,3 @@
import BasicTask from './index.vue'
export { BasicTask }

466
src/views/task/components/BasicTask/index.vue

@ -0,0 +1,466 @@
<script lang="ts" setup>
import { ref } from 'vue'
import History from '@/assets/images/task/history.png'
import unclaimed from '@/assets/images/task/dlq.png'
import dot from '@/assets/images/task/dot.png'
import money from '@/assets/images/task/money.png'
//
const sign = ref([
{
day: '第1天',
img: unclaimed,
status: 1,
},
{
day: '第2天',
img: unclaimed,
status: 1,
},
{
day: '第3天',
img: unclaimed,
status: 1,
},
{
day: '第4天',
img: unclaimed,
status: 2,
},
{
day: '第5天',
img: unclaimed,
status: 3,
},
{
day: '第6天',
img: unclaimed,
status: 3,
},
{
day: '第7天',
img: unclaimed,
status: 3,
},
])
//
const earn = ref([
{
title: '登录微信小程序',
dot: 1,
status: 1,
},
{
title: '邀请注册',
dot: 200,
status: 0,
},
{
title: '每日登录',
dot: 2,
status: 1,
},
])
</script>
<template>
<div class="basic-task-box">
<div class="title">
基础任务
</div>
<div class="contant flex flex-row">
<div class="left basis-3/5">
<div class="top flex flex-row">
<div class="login-day">
您已连续登录 <span>3</span>
</div>
<div class="historyBox">
<img class="historyImg" :src="History" alt="">
<div class="historyName">
历史
</div>
</div>
</div>
<div class="bottom">
<div class="accumulate">
<div class="three">
累计领取3点数
</div>
<div class="ten">
连续签到7天可得 10 点数
</div>
</div>
<div class="sign-box">
<div v-for="(item, index) in sign" :key="index" class="sign">
<div class="sign-photo" :style="{ backgroundImage: `url(${item.img})`, backgroundSize: '100% 100%', backgroundRepeat: 'no-repeat' }">
<div class="count">
{{ index === 6 ? "10点数" : "1点数" }}
</div>
</div>
<div v-show="item.status !== 2" class="sign-day">
{{ item.day }}
</div>
<div v-show="item.status === 2" class="sign-get">
领取
</div>
</div>
</div>
</div>
</div>
<div class="right basis-2/5">
<div class="earn-points">
<div class="title-box">
<div class="dot">
<img :src="dot" alt="">
</div>
<div class="name">
做任务赚积分
</div>
<div class="dot">
<img :src="dot" alt="">
</div>
</div>
<div class="earn-list-box">
<div v-for="(item, index) in earn" :key="index" class="earn-list">
<div class="earn-list-left">
<div class="name">
{{ item.title }}
</div>
<div v-show="item.status === 1" class="accomplish">
已获得{{ item.dot }}点数
</div>
<div v-show="item.status === 0" class="unfinished">
0/{{ item.dot }}
</div>
</div>
<div class="earn-list-right">
<div class="add-dot-box">
<div class="flex items-center">
<img class="add-dot-photo" :src="money" alt="">
<div class="add-dot-num">
+{{ item.dot }}
</div>
</div>
<div v-show="item.status === 1" class="add-dot-btn accomplish">
已完成
</div>
<div v-if="item.status === 0 && index !== 1" class="add-dot-btn unfinished">
未完成
</div>
<div v-if="item.status === 0 && index === 1" class="add-dot-btn invite">
去邀请
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.basic-task-box {
width: 95%;
.title {
font-size: 13px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
line-height: 22px;
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
column-gap: 10px;
.left {
width: 100%;
background-image: url(@/assets/images/task/qiandao.png);
background-size: 100% 100%;
padding: 20px;
.top {
width: 100%;
justify-content: space-between;
.login-day {
font-size: 19px;
font-family: PingFang-SC, PingFang-SC;
color: #ffffff;
line-height: 33px;
letter-spacing: 2px;
span {
font-size: 27px;
font-weight: bold;
}
}
.historyBox {
display: flex;
cursor: pointer;
align-items: flex-start;
.historyImg {
width: 13px;
height: 13px;
}
.historyName {
padding-left: 5px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
margin-top: -2px;
}
}
}
.bottom {
margin-top: 15px;
.accumulate {
width: 100%;
display: flex;
.three {
width: 30%;
height: 100%;
padding: 3px 0;
text-align: center;
background-color: #ffffff;
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #4670e3;
border-top-left-radius: 6px;
position: relative;
z-index: 2;
&::after {
content: '';
position: absolute;
top: 0;
left: 10px;
width: 96%;
height: 100%;
background-color: inherit;
transform: skewX(35deg); /* 可调整此值以改变倾斜的程度 */
transform-origin: 100% 0;
z-index: -1;
}
}
.ten {
width: 70%;
padding: 3px 0;
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
padding-left: 30px;
}
}
.sign-box {
width: 100%;
height: 100px;
background-color: #ffffff;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
display: flex;
align-items: center;
justify-content: space-around;
.sign {
.sign-photo {
width: 50px;
height: 64px;
position: relative;
.count {
font-size: 10px;
font-family: PingFang-SC, PingFang-SC;
font-weight: 500;
color: #ff9b00;
text-align: center;
font-weight: bold;
padding-top: 5px;
}
}
.sign-day {
text-align: center;
font-size: 10px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #888c90;
padding-top: 5px;
}
.sign-get {
cursor: pointer;
margin-top: 5px;
width: 100%;
height: 15px;
background: linear-gradient(180deg, #ffb33d 0%, #ff9b00 100%);
border-radius: 11px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
line-height: 15px;
text-align: center;
}
}
}
}
}
.right {
width: 100%;
padding: 20px 14px;
background-color: aliceblue;
border-radius: 15px;
.earn-points {
.title-box {
display: flex;
align-items: center;
padding-left: 10px;
.dot {
display: flex;
align-items: center;
}
.name {
padding: 0 7px;
font-size: 13px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 500;
color: #000000;
line-height: 22px;
font-weight: bold;
letter-spacing: 1px;
}
}
.earn-list-box {
margin-top: 15px;
width: 100%;
height: 150px;
background-color: #ffffff;
border-radius: 4px;
padding: 0 10px;
.earn-list {
width: 100%;
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid #ededed;
&:last-child {
border: 0;
}
.earn-list-left {
display: flex;
align-items: center;
width: 60%;
.name {
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 500;
color: #000000;
letter-spacing: 1px;
}
.accomplish {
font-size: 9px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #f7b606;
padding-left: 10px;
}
.unfinished {
font-size: 10px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #888c90;
padding-left: 10px;
}
}
.earn-list-right {
width: 40%;
.add-dot-box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.add-dot-photo {
width: 13px;
height: 13px;
display: flex;
align-items: center;
}
.add-dot-num {
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #f7b500;
padding-left: 3px;
}
.add-dot-btn {
cursor: pointer;
width: 45px;
height: 20px;
border-radius: 16px;
font-size: 10px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
line-height: 20px;
letter-spacing: 1px;
text-align: center;
&.accomplish {
background: linear-gradient(
90deg,
#b5ceff 0%,
#a6baff 100%
);
color: #ffffff;
}
&.unfinished {
background: #ffffff;
border: 1px solid #cdcdcd;
line-height: 18px;
color: #888c90;
}
&.invite {
background: linear-gradient(
90deg,
#6fa3ff 0%,
#486dff 100%
);
color: #ffffff;
}
}
}
}
}
}
}
}
}
}
</style>

3
src/views/task/components/DailyTask/index.ts

@ -0,0 +1,3 @@
import DailyTask from './index.vue'
export { DailyTask }

32
src/views/task/components/DailyTask/index.vue

@ -0,0 +1,32 @@
<script lang="ts" setup>
</script>
<template>
<div class="daily-task-box">
<div class="title">
每日任务
</div>
<div class="contant"></div>
</div>
</template>
<style lang="scss" scoped>
.daily-task-box {
width: 95%;
.title {
font-size: 13px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
line-height: 22px;
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
height: 200px;
background-color: red;
}
}
</style>

3
src/views/task/components/NoviceTask/index.ts

@ -0,0 +1,3 @@
import NoviceTask from './index.vue'
export { NoviceTask }

32
src/views/task/components/NoviceTask/index.vue

@ -0,0 +1,32 @@
<script lang="ts" setup>
</script>
<template>
<div class="nvoice-task-box">
<div class="title">
新手任务
</div>
<div class="contant"></div>
</div>
</template>
<style lang="scss" scoped>
.nvoice-task-box {
width: 95%;
.title {
font-size: 13px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
line-height: 22px;
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
height: 200px;
background-color: red;
}
}
</style>

3
src/views/task/components/OtherTask/index.ts

@ -0,0 +1,3 @@
import OtherTask from './index.vue'
export { OtherTask }

32
src/views/task/components/OtherTask/index.vue

@ -0,0 +1,32 @@
<script lang="ts" setup>
</script>
<template>
<div class="other-task-box">
<div class="title">
其他任务
</div>
<div class="contant"></div>
</div>
</template>
<style lang="scss" scoped>
.other-task-box {
width: 95%;
.title {
font-size: 13px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
line-height: 22px;
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
height: 200px;
background-color: red;
}
}
</style>

0
src/views/task/index.d.ts vendored

40
src/views/task/index.vue

@ -0,0 +1,40 @@
<script setup lang="ts">
import { provide, ref } from 'vue'
import { BasicTask } from './components/BasicTask'
import { NoviceTask } from './components/NoviceTask'
import { DailyTask } from './components/DailyTask'
import { OtherTask } from './components/OtherTask'
import { AppContainerBox } from '@/components/AppContainerBox'
import { AppSubMenuTitle } from '@/components/AppSubMenuTitle'
import { AppTaskMenuList } from '@/components/AppTaskMenuList'
const taskContainer = ref(null)
const task1 = ref(null)
const task2 = ref(null)
const task3 = ref(null)
const task4 = ref(null)
const sectionRefs = { task1, task2, task3, task4 }
provide('sectionRefs', sectionRefs)
provide('taskContainer', taskContainer)
</script>
<template>
<AppContainerBox>
<template #subMenu>
<AppSubMenuTitle title="任务中心"></AppSubMenuTitle>
<AppTaskMenuList></AppTaskMenuList>
</template>
<template #content>
<div ref="taskContainer" class="w-full h-full overflow-auto">
<BasicTask ref="task1" />
<NoviceTask ref="task2" />
<DailyTask ref="task3" />
<OtherTask ref="task4" />
</div>
</template>
</AppContainerBox>
</template>
<style lang="scss" scoped>
</style>
Loading…
Cancel
Save