Browse Source

feat:登录页新增邀请码

fix:修改任务角标
dxj
杜贤金 1 year ago
parent
commit
a06d8fdfcd
  1. 3
      src/api/base/login.ts
  2. 18
      src/api/task/index.ts
  3. 30
      src/components/AppRecharge/index.vue
  4. 19
      src/components/AppTaskMenuList/index.d.ts
  5. 17
      src/components/AppTaskMenuList/index.vue
  6. 2
      src/components/AppUserInfo/index.vue
  7. 35
      src/layout/AppMenu/index.vue
  8. 41
      src/store/moules/taskListStore/index.ts
  9. 2
      src/store/moules/userStore/index.ts
  10. 2
      src/views/login/index.d.ts
  11. 17
      src/views/login/index.vue
  12. 10
      src/views/task/components/BasicTask/index.d.ts
  13. 74
      src/views/task/components/BasicTask/index.vue
  14. 7
      src/views/task/components/DailyTask/index.vue
  15. 21
      src/views/task/components/HisTory/index.vue
  16. 3
      src/views/task/components/NoviceTask/index.vue
  17. 7
      src/views/task/components/OtherTask/index.vue
  18. 18
      src/views/task/components/TaskList/index.vue
  19. 5
      src/views/task/index.vue

3
src/api/base/login.ts

@ -7,10 +7,11 @@ export interface TokenParams {
phone: string
phoneCode: string
type: string
inviteCode: string
}
export async function token(params: TokenParams) {
return defHttp.post({
url: `/hulk-auth/oauth/token?grant_type=${params.grant_type}&user_type=${params.user_type}&invite_code=${params.invite_code}&phone=${params.phone}&phoneCode=${params.phoneCode}&type=${params.type}`,
url: `/hulk-auth/oauth/token?grant_type=${params.grant_type}&user_type=${params.user_type}&invite_code=${params.invite_code}&phone=${params.phone}&phoneCode=${params.phoneCode}&type=${params.type}&inviteCode=${params.inviteCode}`,
}, {
isTransformResponse: false,
})

18
src/api/task/index.ts

@ -27,3 +27,21 @@ export async function noviceTask() {
url: `/open-chat/taskCenter/noviceTask/list`,
})
}
// 做任务赚积分
export async function routineTask() {
return defHttp.get({
url: `/open-chat/taskCenter/routineTask/list`,
})
}
// 每日任务列表
export async function dailyTask() {
return defHttp.get({
url: `/open-chat/taskCenter/dailyTask/list`,
})
}
// 领取接口
export async function receiveAward(id: string) {
return defHttp.post({
url: `/open-chat/taskCenter/receiveAward?taskId=${id}`,
})
}

30
src/components/AppRecharge/index.vue

@ -108,24 +108,6 @@ function tabClass(index: number) {
return 'tab'
}
}
//
// const extreme = ref([{
// num: 10000,
// unit: '',
// name: '',
// }, {
// num: '',
// unit: '',
// name: '3.5',
// }, {
// num: 5000,
// unit: '',
// name: '4.0',
// }, {
// num: 10000,
// unit: '',
// name: '',
// }])
//
function onPrevClick() {
@ -135,6 +117,13 @@ function onPrevClick() {
function onNextClick() {
carouselRef.value.next()
}
//
function separator(num: number | string) {
const numParts = num.toString().split('.')
numParts[0] = numParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '’')
return numParts.join('.')
}
</script>
<template>
@ -264,7 +253,7 @@ function onNextClick() {
<div class="extremeequitynum">
<div class="extremeequitynum-box">
<div class="extremeequitynum-box-top">
<span class="num">{{ goodslists[0].giveNum }}</span>
<span class="num">{{ separator(goodslists[0].giveNum) }}</span>
<span class="unit">点数</span>
</div>
<div class="extremeequitynum-box-bottom">
@ -283,7 +272,7 @@ function onNextClick() {
<div class="extremeequitynum-box">
<div class="extremeequitynum-box-top">
<span class="num">{{ goodslists[0].gpt40Num }}</span>
<span class="num">{{ separator(goodslists[0].gpt40Num) }}</span>
<span class="unit"></span>
</div>
<div class="extremeequitynum-box-bottom">
@ -578,6 +567,7 @@ function onNextClick() {
color: #ffe9d5;
.num {
font-size: 25px;
font-family: 'jinbuti';
}
.unit {
font-size: 15px;

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

@ -1,8 +1,17 @@
import type { Ref } from 'vue'
export interface Task {
task1: Ref<HTMLElement | null>
task2: Ref<HTMLElement | null>
task3: Ref<HTMLElement | null>
task4: Ref<HTMLElement | null>
interface Task {
task1: Ref<HTMLElementl>
task2: Ref<HTMLElement>
task3: Ref<HTMLElement>
task4: Ref<HTMLElement>
}
interface ListType {
title: string
status: boolean
task: string
}
export {
Task,
ListType,
}

17
src/components/AppTaskMenuList/index.vue

@ -1,33 +1,36 @@
<!-- 子菜单列表组件 -->
<script setup lang="ts">
import { inject, ref } from 'vue'
import { computed, inject, ref } from 'vue'
import type { Task } from './index.d'
import { useTaskListStore } from '@/store/moules/taskListStore'
const taskListStore = useTaskListStore()
const sectionRefs = inject<Task>('sectionRefs')
const taskContainer = inject('taskContainer')
const activeIndex = ref(0)
const list = [
const list = computed(() => [
{
title: '基础任务',
status: true,
status: taskListStore.basicTask,
task: 'task1',
},
{
title: '新手任务',
status: false,
status: taskListStore.noviceTask,
task: 'task2',
},
{
title: '每日任务',
status: false,
status: taskListStore.dailyTask,
task: 'task3',
},
{
title: '其他任务',
status: false,
status: taskListStore.otherTask,
task: 'task4',
},
]
])
//
function handleClick(index: number, task: string) {
activeIndex.value = index

2
src/components/AppUserInfo/index.vue

@ -16,7 +16,7 @@ function handleRecharge() {
//
function separator(num: number | string) {
const numParts = num.toString().split('.')
numParts[0] = numParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '`')
numParts[0] = numParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '')
return numParts.join('.')
}
</script>

35
src/layout/AppMenu/index.vue

@ -1,12 +1,16 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { createVNode, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { Button, Modal, Popover } from 'ant-design-vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import type { MenuItem } from './index.d'
import { SvgIcon } from '@/components/SvgIcon'
import { MenuTypeEnum } from '@/enums/menuEnum'
import { useUserStore } from '@/store/moules/userStore/index'
const router = useRouter()
const menuActive = ref<MenuTypeEnum>(MenuTypeEnum.TEXT_TO_TEXT)
const userStore = useUserStore()
const menu = ref<MenuItem[]>([
{
name: '会话',
@ -76,6 +80,20 @@ function handleToPath(item: MenuItem) {
menuActive.value = item.key
router.push({ path: item.path })
}
function showConfirm() {
Modal.confirm({
title: '提示',
icon: createVNode(ExclamationCircleOutlined),
content: createVNode('div', { style: 'color:#333;' }, '您确认要退出登录吗?'),
onOk() {
userStore.logout()
},
onCancel() {
console.log('Cancel')
},
class: 'test',
})
}
</script>
<template>
@ -103,10 +121,17 @@ function handleToPath(item: MenuItem) {
:class="[menuActive === item.key ? 'menu-item-active' : '']"
@click="handleToPath(item)"
>
<SvgIcon class="icon" :name="item.icon" />
<p class="text text-center">
{{ item.name }}
</p>
<Popover placement="rightTop" trigger="hover">
<template #content>
<Button type="link" block @click="showConfirm">
退出登录
</Button>
</template>
<SvgIcon class="icon" :name="item.icon" />
<p class="text text-center">
{{ item.name }}
</p>
</Popover>
</div>
</div>
</div>

41
src/store/moules/taskListStore/index.ts

@ -0,0 +1,41 @@
import { defineStore } from 'pinia'
export const useTaskListStore = defineStore('useTaskListStore', {
state: () => {
return {
basicTask: false,
noviceTask: false,
dailyTask: false,
otherTask: false,
}
},
getters: {
getBasicTask(): boolean {
return this.basicTask
},
getNoviceTask(): boolean {
return this.noviceTask
},
getDailyTask(): boolean {
return this.dailyTask
},
getOtherTask(): boolean {
return this.otherTask
},
},
actions: {
changeBasicTask(status: boolean) {
this.basicTask = status
},
changeNoviceTask(status: boolean) {
this.noviceTask = status
},
changeDailyTask(status: boolean) {
this.dailyTask = status
},
changeOtherTask(status: boolean) {
this.otherTask = status
},
},
})

2
src/store/moules/userStore/index.ts

@ -66,7 +66,7 @@ export const useUserStore = defineStore('useUserStore', {
this.$reset()
localStorage.clear()
// 清空数据
goLogin && router.push(PageEnum.BASE_LOGIN)
!goLogin && router.push(PageEnum.BASE_LOGIN)
},
},
persist: [

2
src/views/login/index.d.ts vendored

@ -1,5 +1,5 @@
export interface LoginForm {
phone: string
code: string
inviteCode: string
}

17
src/views/login/index.vue

@ -5,11 +5,12 @@ import { Button, Form, FormItem, Input, message } from 'ant-design-vue'
import { useRouter } from 'vue-router'
import type { Rule } from 'ant-design-vue/es/form'
import { UsergroupAddOutlined } from '@ant-design/icons-vue'
import type { LoginForm } from './index.d'
import { sendCode } from '@/api/base/login'
import { useUserStore } from '@/store/moules/userStore/index'
import { useMessage } from '@/hooks/useMessage'
import { GrantTypeEnum, TypeEnum, UserTypeEnum } from '@/enums/commonEnum'
import Logo from '@/assets/images/login/loginlogo.png'
import Loginleft from '@/assets/images/login/loginleft.png'
import Yh from '@/assets/images/login/yh.png'
@ -17,7 +18,7 @@ import Yzm from '@/assets/images/login/yzm.png'
const router = useRouter()
const userStore = useUserStore()
const { createMessage } = useMessage()
const formRef = ref()
const btnTxt = ref('获取验证码')
const disabled = ref(false)
@ -26,6 +27,7 @@ const time = ref(0)
const ruleForm = reactive<LoginForm>({
phone: '',
code: '',
inviteCode: '',
})
const loading = ref(false)
async function validatePhone(_rule: Rule, value: string) {
@ -40,6 +42,7 @@ const rules: Record<string, Rule[]> = {
{ validator: validatePhone, trigger: 'blur' },
],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
inviteCode: [{ required: false, message: '请输入验证码', trigger: 'blur' }],
}
//
function handleLogin() {
@ -54,6 +57,7 @@ function handleLogin() {
phone: ruleForm.phone,
phoneCode: ruleForm.code,
type: TypeEnum.PHONE,
inviteCode: ruleForm.inviteCode,
}).then(() => {
message.success('登录成功')
loading.value = false
@ -177,6 +181,15 @@ function timer() {
</template>
</Input>
</FormItem>
<FormItem
name="inviteCode"
>
<Input v-model:value="ruleForm.inviteCode" :bordered="false" class="custom-input" placeholder="请输入邀请码">
<template #prefix>
<UsergroupAddOutlined style="color:#787D8E" />
</template>
</Input>
</FormItem>
<FormItem>
<Button
class="login-button"

10
src/views/task/components/BasicTask/index.d.ts vendored

@ -1,6 +1,14 @@
export interface SignType {
interface SignType {
continueDays: number
isSign: number
signDays: number
totalIntegral: number
}
interface TaskType {
name: string
score: number
status: number
id: string
}
export { SignType, TaskType }

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

@ -3,13 +3,18 @@ import { ref } from 'vue'
import { Popover, message } from 'ant-design-vue'
import { InviteForm } from '../InviteForm/index'
import { HisTory } from '../HisTory/index'
import type { SignType } from './index.d'
import { current, logUserSign } from '@/api/task/index'
import type { SignType, TaskType } from './index.d'
import { current, logUserSign, receiveAward, routineTask } from '@/api/task/index'
import { useTaskListStore } from '@/store/moules/taskListStore'
import History from '@/assets/images/task/history.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 unclaimed from '@/assets/images/task/dlq.png'
import { useUserStore } from '@/store/moules/userStore/index'
const userStore = useUserStore()
const taskListStore = useTaskListStore()
//
const visible = ref<boolean>(false)
@ -37,27 +42,30 @@ function handleSign(type: string) {
}
getCurrent()
message.success('签到成功!')
userStore.getChatInfoFun()
})
}
//
const earn = ref([
{
title: '登录微信小程序',
dot: 1,
status: 1,
},
{
title: '邀请注册',
dot: 200,
status: 0,
},
{
title: '每日登录',
dot: 2,
status: 1,
},
])
//
const earn = ref<TaskType[]>([])
function getRoutineTask() {
routineTask().then((res) => {
earn.value = res.taskCenterList
taskListStore.changeBasicTask(res.existFinishedTask)
})
}
getRoutineTask()
//
function handleGetDot(id: string) {
receiveAward(id).then(() => {
message.success('领取成功')
getRoutineTask()
userStore.getChatInfoFun()
})
}
//
const inviteShow = ref(false)
function handleInvite() {
@ -143,13 +151,13 @@ function handleInvite() {
<div v-for="(item, index) in earn" :key="index" class="earn-list">
<div class="earn-list-left">
<div class="name">
{{ item.title }}
{{ item.name }}
</div>
<div v-show="item.status === 1" class="accomplish">
已获得{{ item.dot }}点数
<div v-show="item.status === 2" class="accomplish">
已获得{{ item.score }}点数
</div>
<div v-show="item.status === 0" class="unfinished">
0/{{ item.dot }}
<div v-show="item.status !== 2" class="unfinished">
0/{{ item.score }}
</div>
</div>
<div class="earn-list-right">
@ -157,19 +165,23 @@ function handleInvite() {
<div class="flex items-center">
<img class="add-dot-photo" :src="money" alt="">
<div class="add-dot-num">
+{{ item.dot }}
+{{ item.score }}
</div>
</div>
<div v-show="item.status === 1" class="add-dot-btn accomplish">
<div v-show="item.status === 2" class="add-dot-btn accomplish">
已完成
</div>
<div v-if="item.status === 0 && index !== 1" class="add-dot-btn unfinished">
未完成
<div v-if="item.status === 1 " class="add-dot-btn invite" @click="handleGetDot(item.id)">
领取
</div>
<div v-if="item.status === 0 && index === 1" class="add-dot-btn invite" @click="handleInvite">
去邀请
<div v-if="item.status === 0">
<div v-if="item.name === '邀请注册'" class="add-dot-btn invite" @click="handleInvite">
去邀请
</div>
<div v-else class="add-dot-btn unfinished">
未完成
</div>
</div>
</div>
</div>

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

@ -2,17 +2,20 @@
import { onMounted, ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
import type { TaskType } from './index.d'
import { noviceTask } from '@/api/task/index'
import { dailyTask } from '@/api/task/index'
import { useTaskListStore } from '@/store/moules/taskListStore'
const taskListStore = useTaskListStore()
const totalScore = ref(0)
const list = ref<TaskType[]>([])
const finishedTaskCount = ref(0)
function getTaskList() {
noviceTask().then((res) => {
dailyTask().then((res) => {
list.value = res.taskCenterList
totalScore.value = res.totalScore
finishedTaskCount.value = res.finishedTaskCount
taskListStore.changeDailyTask(res.existFinishedTask)
})
}
onMounted(() => {

21
src/views/task/components/HisTory/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref, watch, watchEffect } from 'vue'
import { ref, watchEffect } from 'vue'
import dayjs from 'dayjs'
import { Button, Calendar } from 'ant-design-vue'
import {
@ -17,11 +17,12 @@ const props = defineProps({
})
const emit = defineEmits(['handleHsigns'])
const data = ref(dayjs())
const yam = ref(dayjs(data.value).format('YYYY-MM'))
const datesData = ref<HistoryType[]>([])
const month = ref(data.value.month() + 1)
const yam = ref(dayjs(data.value).format('YYYY-MM')) // yyyy-MM
const datesData = ref<HistoryType[]>([]) //
const month = ref(data.value.month() + 1) //
const formerly = ref(false)
const targetIndex = ref(-1) // 10
//
function changeMonth(type: number) {
if (type > 0) {
@ -51,6 +52,11 @@ function format(val: string | number | dayjs.Dayjs | Date | null | undefined) {
//
function getHistory(time: string) {
history({ yearAndMonth: time }).then((res) => {
for (let i = 0; i < res.length; i++) {
if (res[i].signType === 0) {
targetIndex.value = i + 7
}
}
datesData.value = res
})
}
@ -109,8 +115,11 @@ const getCellTypeClass = function (value: { $D: number }) {
<div v-if="value.month() === data.month() && value.year() === data.year()">
<div class="cellBox">
<div class="cellItem" :class="datesData.length > 0 ? getCellTypeClass(value) : ''">
<div class="count">
{{ datesData[value.$D - 1]?.awardIntegral ? datesData[value.$D - 1]?.awardIntegral : "1" }}点数
<div v-if="value.$D - 1 !== targetIndex" class="count">
{{ datesData[value.$D - 1] ? datesData[value.$D - 1]?.awardIntegral : '1' }}点数
</div>
<div v-else class="count">
10点数
</div>
</div>
<div v-if="dayjs(value).isSame(dayjs(), 'day') && datesData[value.$D - 1]?.signType === 0 " class="getbtn" @click="handleGet">

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

@ -3,7 +3,9 @@ import { onMounted, ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
import type { TaskType } from './index.d'
import { noviceTask } from '@/api/task/index'
import { useTaskListStore } from '@/store/moules/taskListStore'
const taskListStore = useTaskListStore()
const totalScore = ref(0)
const list = ref<TaskType[]>([])
const finishedTaskCount = ref(0)
@ -12,6 +14,7 @@ function getTaskList() {
list.value = res.taskCenterList
totalScore.value = res.totalScore
finishedTaskCount.value = res.finishedTaskCount
taskListStore.changeNoviceTask(res.existFinishedTask)
})
}
onMounted(() => {

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

@ -2,17 +2,20 @@
import { onMounted, ref } from 'vue'
import { TaskList } from '../TaskList/index.ts'
import type { TaskType } from './index.d'
import { noviceTask } from '@/api/task/index'
import { routineTask } from '@/api/task/index'
import { useTaskListStore } from '@/store/moules/taskListStore'
const taskListStore = useTaskListStore()
const totalScore = ref(0)
const list = ref<TaskType[]>([])
const finishedTaskCount = ref(0)
function getTaskList() {
noviceTask().then((res) => {
routineTask().then((res) => {
list.value = res.taskCenterList
totalScore.value = res.totalScore
finishedTaskCount.value = res.finishedTaskCount
taskListStore.changeOtherTask(res.existFinishedTask)
})
}
onMounted(() => {

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

@ -7,6 +7,8 @@ import {
import { message } from 'ant-design-vue'
import type { TaskType } from './index.d'
import money from '@/assets/images/task/money.png'
import { receiveAward } from '@/api/task/index'
import { useUserStore } from '@/store/moules/userStore/index'
const { title, list, totalScore } = defineProps({
title: {
@ -25,10 +27,14 @@ const { title, list, totalScore } = defineProps({
},
})
const emit = defineEmits(['updateList'])
const userStore = useUserStore()
//
function hanndleGetDot(id) {
message.success('领取成功')
emit('updateList')
function handleGetDot(id: string) {
receiveAward(id).then(() => {
message.success('领取成功')
userStore.getChatInfoFun()
emit('updateList')
})
}
const isExpanded = ref(false)//
const singleItemHeight = 45 //
@ -71,10 +77,10 @@ const dynamicStyle = computed(() => {
<div class="name">
{{ item.name }}
</div>
<div v-show="item.status === 1" class="accomplish">
<div v-show="item.status === 2" class="accomplish">
已获得{{ item.score }}点数
</div>
<div v-show="item.status === 0" class="unfinished">
<div v-show="item.status !== 2" class="unfinished">
0/{{ item.score }}
</div>
</div>
@ -91,7 +97,7 @@ const dynamicStyle = computed(() => {
已完成
</div>
<div v-show="item.status === 1" class="add-dot-btn finished" @click="hanndleGetDot(item.id)">
<div v-show="item.status === 1" class="add-dot-btn finished" @click="handleGetDot(item.id)">
领取
</div>

5
src/views/task/index.vue

@ -3,7 +3,8 @@ 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 { OtherTask } from './components/OtherTask'
import { AppUserInfo } from '@/components/AppUserInfo'
import { AppContainerBox } from '@/components/AppContainerBox'
import { AppSubMenuTitle } from '@/components/AppSubMenuTitle'
@ -31,7 +32,7 @@ provide('taskContainer', taskContainer)
<BasicTask ref="task1" />
<NoviceTask ref="task2" />
<DailyTask ref="task3" />
<OtherTask ref="task4" />
<!-- <OtherTask ref="task4" /> -->
</div>
</template>
</AppContainerBox>

Loading…
Cancel
Save