Browse Source

feat:完成任务页面,新增支付页面

dxj
杜贤金 1 year ago
parent
commit
a4e2db9ba7
  1. BIN
      src/assets/images/money.png
  2. BIN
      src/assets/images/task/invite.png
  3. BIN
      src/assets/images/task/wlq.png
  4. BIN
      src/assets/images/task/ylq.png
  5. 3
      src/components/AppRecharge/index.ts
  6. 141
      src/components/AppRecharge/index.vue
  7. 1
      src/components/AppSubMenuBox/index.vue
  8. 2
      src/components/AppTaskMenuList/index.vue
  9. 3
      src/components/AppUserInfo/index.ts
  10. 129
      src/components/AppUserInfo/index.vue
  11. 37
      src/views/task/components/BasicTask/index.vue
  12. 43
      src/views/task/components/DailyTask/index.vue
  13. 5
      src/views/task/components/InviteForm/index.ts
  14. 141
      src/views/task/components/InviteForm/index.vue
  15. 44
      src/views/task/components/NoviceTask/index.vue
  16. 58
      src/views/task/components/OtherTask/index.vue
  17. 3
      src/views/task/components/TaskList/index.ts
  18. 260
      src/views/task/components/TaskList/index.vue
  19. 3
      src/views/task/index.vue

BIN
src/assets/images/money.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

3
src/components/AppRecharge/index.ts

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

141
src/components/AppRecharge/index.vue

@ -0,0 +1,141 @@
<script lang="ts" setup>
import {
CloseOutlined,
} from '@ant-design/icons-vue'
import { Button, QRCode } from 'ant-design-vue'
import { ref } from 'vue'
defineProps({
show: {
type: Boolean,
default: false,
},
})
const emits = defineEmits(['update:show'])
//
function handleClose() {
emits('update:show', false)
}
//
const qrcodeCanvasRef = ref()
async function dowloadChange() {
const url = await qrcodeCanvasRef.value.toDataURL()
const a = document.createElement('a')
a.download = 'QRCode.png'
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
</script>
<template>
<transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-body">
<div class="closeIcon" @click="handleClose">
<CloseOutlined style="color: #fff;" />
</div>
<div class="close" @click="handleClose">
</div>
<div class="qr">
<QRCode ref="qrcodeCanvasRef" :size="145" value="http://www.antdv.com" />
</div>
<Button type="primary" class="save-qr" @click="dowloadChange">
保存二维码
</Button>
</div>
</div>
</div>
</div>
</transition>
</template>
<style scoped lang="scss">
.modal-mask {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
.modal-wrapper {
background-color: #fff;
}
.modal-body {
width: 530px;
height: 300px;
background-image: url('@/assets/images/task/invite.png');
background-size: 100% 100%;
position: relative;
.closeIcon {
position: absolute;
top: 0;
right: 5px;
z-index: 2;
cursor: pointer;
}
.close {
position: absolute;
cursor: pointer;
top: 0;
right: 0;
width: 35px;
height: 35px;
background-image: linear-gradient(180deg, #5c94f7 0%, #4060e0 100%);
clip-path: polygon(100% 100%, 100% 0, 0 0);
z-index: 1;
}
.qr {
position: absolute;
top: 93px;
left: 50%;
transform: translate(-50%);
}
.save-qr {
cursor: pointer;
width: 130px;
height: 32px;
background: #4670e3;
border-radius: 20px;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
text-align: center;
font-size: 13px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
letter-spacing: 1px;
}
}
}
.modal-enter-active,
.modal-leave-active {
transition: opacity 0.3s;
}
.modal-enter-from,
.modal-leave-to {
opacity: 0;
}
.modal-enter-to,
.modal-leave-from {
opacity: 1;
}
</style>

1
src/components/AppSubMenuBox/index.vue

@ -11,5 +11,6 @@
<style lang="scss" scoped>
@include app('sub-menu-box') {
width: $sub-menu-width;
position: relative;
}
</style>

2
src/components/AppTaskMenuList/index.vue

@ -71,7 +71,7 @@ function handleClick(index: number, task: string) {
color: #888c90;
position: relative;
.title {
font-size: 11px;
font-size: 13px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
line-height: 20px;

3
src/components/AppUserInfo/index.ts

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

129
src/components/AppUserInfo/index.vue

@ -0,0 +1,129 @@
<!-- 子菜单与内容容器布局组件 -->
<script setup lang="ts">
import { Divider } from 'ant-design-vue'
import money from '@/assets/images/money.png'
import { useUserStore } from '@/store/moules/userStore/index'
const userStore = useUserStore()
console.log(userStore.getChatInfo)
</script>
<template>
<div class="app-user-info">
<div class="app-user-info-top">
<div class="dot">
<img :src="money" alt="">
<div class="dot-num">
点数
</div>
</div>
<div class="num">
99
</div>
<div class="pay">
充值
</div>
</div>
<div class="app-user-info-bottom">
<div>
<div class="accumulative">
1321
</div>
<div class="accumulativename">
累计提问
</div>
</div>
<Divider type="vertical" style="height: 30px; background-color: #e1e9f9" />
<div>
<div class="accumulative">
3415
</div>
<div class="accumulativename">
来到同聪
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
@include app('user-info') {
position: absolute;
bottom: 0px;
left: 10px;
right: 10px;
padding: 10px;
width: 90%;
height: 120px;
background: #e1e9f9;
border-radius: 8px;
&-top {
height: 40%;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #dae1ef;
.dot {
display: flex;
align-items: center;
img {
width: 14px;
height: 16px;
}
.dot-num {
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #000000;
padding-left: 4px;
}
}
.num {
font-size: 14px;
font-family: DingTalk, DingTalk;
font-weight: normal;
color: #000000;
line-height: 21px;
}
.pay {
width: 45px;
height: 20px;
background: #4670e3;
border-radius: 13px;
font-size: 12px;
text-align: center;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
line-height: 20px;
}
}
&-bottom {
height: 60%;
width: 100%;
display: flex;
align-items: flex-end;
justify-content: space-around;
.accumulative {
text-align: center;
font-size: 15px;
font-family: DingTalk, DingTalk;
font-weight: normal;
color: #000000;
}
.accumulativename {
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #000000;
}
}
}
</style>

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

@ -1,25 +1,30 @@
<script lang="ts" setup>
import { ref } from 'vue'
import handleAck from 'mqtt/lib/handlers/ack'
import { InviteForm } from '../InviteForm/index'
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'
import receive from '@/assets/images/task/ylq.png'
import lost from '@/assets/images/task/wlq.png'
//
const sign = ref([
{
day: '第1天',
img: unclaimed,
img: receive,
status: 1,
},
{
day: '第2天',
img: unclaimed,
img: receive,
status: 1,
},
{
day: '第3天',
img: unclaimed,
img: lost,
status: 1,
},
{
@ -61,6 +66,11 @@ const earn = ref([
status: 1,
},
])
//
const inviteShow = ref(false)
function handleInvite() {
inviteShow.value = true
}
</script>
<template>
@ -149,7 +159,7 @@ const earn = ref([
<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 v-if="item.status === 0 && index === 1" class="add-dot-btn invite" @click="handleInvite">
去邀请
</div>
</div>
@ -160,13 +170,14 @@ const earn = ref([
</div>
</div>
</div>
<InviteForm v-model:show.sync="inviteShow" />
</template>
<style lang="scss" scoped>
.basic-task-box {
width: 95%;
.title {
font-size: 13px;
font-size: 14px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
@ -334,7 +345,7 @@ const earn = ref([
}
.name {
padding: 0 7px;
font-size: 13px;
font-size: 14px;
font-family:
PingFangSC,
PingFang SC;
@ -367,7 +378,7 @@ const earn = ref([
align-items: center;
width: 60%;
.name {
font-size: 12px;
font-size: 13px;
font-family:
PingFangSC,
PingFang SC;
@ -378,7 +389,7 @@ const earn = ref([
letter-spacing: 1px;
}
.accomplish {
font-size: 9px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
@ -387,7 +398,7 @@ const earn = ref([
padding-left: 10px;
}
.unfinished {
font-size: 10px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
@ -411,7 +422,7 @@ const earn = ref([
align-items: center;
}
.add-dot-num {
font-size: 11px;
font-size: 12px;
font-family:
PingFangSC,
PingFang SC;
@ -421,10 +432,9 @@ const earn = ref([
}
.add-dot-btn {
cursor: pointer;
width: 45px;
height: 20px;
border-radius: 16px;
font-size: 10px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
@ -432,6 +442,7 @@ const earn = ref([
line-height: 20px;
letter-spacing: 1px;
text-align: center;
padding: 2px 5px;
&.accomplish {
background: linear-gradient(
90deg,

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

@ -1,21 +1,45 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
const earn = ref([
{
title: '完成一次同聪3.5对话',
dot: 1,
status: 1,
},
{
title: '完成一次同聪4.0对话',
dot: 1,
status: 0,
},
{
title: '完成一次角色对话',
dot: 1,
status: 1,
},
{
title: '完成一次充值',
dot: 200,
status: 0,
},
{
title: '完成一次xxxxxxxxx',
dot: 2,
status: 1,
},
])
</script>
<template>
<div class="daily-task-box">
<div class="title">
每日任务
</div>
<div class="contant"></div>
</div>
<TaskList title="每日任务" :list="earn" />
</template>
<style lang="scss" scoped>
.daily-task-box {
width: 95%;
.title {
font-size: 13px;
font-size: 14px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
@ -23,10 +47,5 @@
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
height: 200px;
background-color: red;
}
}
</style>

5
src/views/task/components/InviteForm/index.ts

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

141
src/views/task/components/InviteForm/index.vue

@ -0,0 +1,141 @@
<script lang="ts" setup>
import {
CloseOutlined,
} from '@ant-design/icons-vue'
import { Button, QRCode } from 'ant-design-vue'
import { ref } from 'vue'
defineProps({
show: {
type: Boolean,
default: false,
},
})
const emits = defineEmits(['update:show'])
//
function handleClose() {
emits('update:show', false)
}
//
const qrcodeCanvasRef = ref()
async function dowloadChange() {
const url = await qrcodeCanvasRef.value.toDataURL()
const a = document.createElement('a')
a.download = 'QRCode.png'
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
</script>
<template>
<transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-body">
<div class="closeIcon" @click="handleClose">
<CloseOutlined style="color: #fff;" />
</div>
<div class="close" @click="handleClose">
</div>
<div class="qr">
<QRCode ref="qrcodeCanvasRef" :size="145" value="http://www.antdv.com" />
</div>
<Button type="primary" class="save-qr" @click="dowloadChange">
保存二维码
</Button>
</div>
</div>
</div>
</div>
</transition>
</template>
<style scoped lang="scss">
.modal-mask {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
.modal-wrapper {
background-color: #fff;
}
.modal-body {
width: 530px;
height: 300px;
background-image: url('@/assets/images/task/invite.png');
background-size: 100% 100%;
position: relative;
.closeIcon {
position: absolute;
top: 0;
right: 5px;
z-index: 2;
cursor: pointer;
}
.close {
position: absolute;
cursor: pointer;
top: 0;
right: 0;
width: 35px;
height: 35px;
background-image: linear-gradient(180deg, #5c94f7 0%, #4060e0 100%);
clip-path: polygon(100% 100%, 100% 0, 0 0);
z-index: 1;
}
.qr {
position: absolute;
top: 93px;
left: 50%;
transform: translate(-50%);
}
.save-qr {
cursor: pointer;
width: 130px;
height: 32px;
background: #4670e3;
border-radius: 20px;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
text-align: center;
font-size: 13px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #ffffff;
letter-spacing: 1px;
}
}
}
.modal-enter-active,
.modal-leave-active {
transition: opacity 0.3s;
}
.modal-enter-from,
.modal-leave-to {
opacity: 0;
}
.modal-enter-to,
.modal-leave-from {
opacity: 1;
}
</style>

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

@ -1,21 +1,46 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
const earn = ref([
{
title: '完成一次同聪3.5对话',
dot: 1,
status: 1,
},
{
title: '完成一次同聪4.0对话',
dot: 1,
status: 0,
},
{
title: '完成一次角色对话',
dot: 1,
status: 1,
},
{
title: '完成一次充值',
dot: 200,
status: 0,
},
{
title: '完成一次xxxxxxxxx',
dot: 2,
status: 1,
},
])
</script>
<template>
<div class="nvoice-task-box">
<div class="title">
新手任务
</div>
<div class="contant"></div>
</div>
<TaskList title="新手任务" :list="earn" />
</template>
<style lang="scss" scoped>
.nvoice-task-box {
width: 95%;
.title {
font-size: 13px;
font-size: 14px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
@ -23,10 +48,5 @@
letter-spacing: 1px;
margin: 16px 0;
}
.contant {
width: 100%;
height: 200px;
background-color: red;
}
}
</style>

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

@ -1,21 +1,65 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
const earn = ref([
{
title: '完成一次同聪3.5对话',
dot: 1,
status: 1,
},
{
title: '完成一次同聪4.0对话',
dot: 1,
status: 0,
},
{
title: '完成一次角色对话',
dot: 1,
status: 1,
},
{
title: '完成一次充值',
dot: 200,
status: 0,
},
{
title: '完成一次xxxxxxxxx',
dot: 2,
status: 1,
},
{
title: '完成一次充值',
dot: 200,
status: 0,
},
{
title: '完成一次xxxxxxxxx',
dot: 2,
status: 1,
},
{
title: '完成一次充值',
dot: 200,
status: 0,
},
{
title: '完成一次xxxxxxxxx',
dot: 2,
status: 1,
},
])
</script>
<template>
<div class="other-task-box">
<div class="title">
其他任务
</div>
<div class="contant"></div>
</div>
<TaskList title="其他任务" :list="earn" />
</template>
<style lang="scss" scoped>
.other-task-box {
width: 95%;
.title {
font-size: 13px;
font-size: 14px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;

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

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

260
src/views/task/components/TaskList/index.vue

@ -0,0 +1,260 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import {
DownOutlined,
UpOutlined,
} from '@ant-design/icons-vue'
import money from '@/assets/images/task/money.png'
const { title, list } = defineProps({
title: {
type: String,
},
list: {
type: Array,
default: () => [],
},
})
const isExpanded = ref(false)//
const singleItemHeight = 45 //
const dynamicStyle = computed(() => {
let maxHeight
if (isExpanded.value) {
//
maxHeight = singleItemHeight * list.length
}
else {
//
maxHeight = 180
}
return {
'max-height': `${maxHeight}px`,
}
})
</script>
<template>
<div class="nvoice-task-box">
<div class="title">
{{ title }}
</div>
<div class="nvoice-contant">
<div class="top flex justify-between">
<div class="left">
全部完成可获得 72 点数
</div>
<div class="right">
已完成 1/12
</div>
</div>
<div class="content" :style="dynamicStyle">
<div class="earn-list-box">
<div v-for="(item, index) in list" :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 " class="add-dot-btn unfinished">
未完成
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="list.length > 4" class="shrink" @click="isExpanded = !isExpanded">
<DownOutlined v-if="!isExpanded" />
<UpOutlined v-else />
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.nvoice-task-box {
width: 95%;
.title {
font-size: 14px;
font-family: PingFang-SC, PingFang-SC;
font-weight: bold;
color: #000000;
line-height: 22px;
letter-spacing: 1px;
margin: 16px 0;
}
.nvoice-contant {
width: 100%;
position: relative;
background-color: #edf3ff;
border-radius: 15px;
padding-bottom: 15px;
.top {
padding: 12px 40px;
.left {
font-size: 14px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #4670e3;
letter-spacing: 1px;
}
.right {
font-size: 14px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #888c90;
letter-spacing: 1px;
}
}
.content {
width: 95%;
background-color: #fff;
margin: 0 auto;
overflow: hidden;
transition: max-height 0.4s ease-in-out;
padding: 5px 20px;
border-radius: 10px;
position: relative;
.earn-list-box {
width: 100%;
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: 85%;
.name {
font-size: 13px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 500;
color: #000000;
letter-spacing: 1px;
}
.accomplish {
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #f7b606;
padding-left: 10px;
}
.unfinished {
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #888c90;
padding-left: 10px;
}
}
.earn-list-right {
width: 15%;
.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: 12px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
color: #f7b500;
padding-left: 3px;
}
.add-dot-btn {
cursor: pointer;
border-radius: 16px;
font-size: 11px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
line-height: 20px;
letter-spacing: 1px;
text-align: center;
padding: 2px 5px;
&.accomplish {
background: linear-gradient(90deg, #b5ceff 0%, #a6baff 100%);
color: #ffffff;
}
&.unfinished {
background: #ffffff;
border: 1px solid #cdcdcd;
line-height: 18px;
color: #888c90;
}
}
}
}
}
}
}
.shrink {
width: 32px;
height: 32px;
text-align: center;
line-height: 32px;
border-radius: 50%;
background-color: #fff;
text-align: center;
box-shadow: 0px 2px 8px 0px rgba(131, 131, 131, 0.5);
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
}
}
}
</style>

3
src/views/task/index.vue

@ -4,7 +4,7 @@ import { BasicTask } from './components/BasicTask'
import { NoviceTask } from './components/NoviceTask'
import { DailyTask } from './components/DailyTask'
import { OtherTask } from './components/OtherTask'
import { AppUserInfo } from '@/components/AppUserInfo'
import { AppContainerBox } from '@/components/AppContainerBox'
import { AppSubMenuTitle } from '@/components/AppSubMenuTitle'
import { AppTaskMenuList } from '@/components/AppTaskMenuList'
@ -24,6 +24,7 @@ provide('taskContainer', taskContainer)
<template #subMenu>
<AppSubMenuTitle title="任务中心"></AppSubMenuTitle>
<AppTaskMenuList></AppTaskMenuList>
<AppUserInfo />
</template>
<template #content>
<div ref="taskContainer" class="w-full h-full overflow-auto">

Loading…
Cancel
Save