From c80299bdc03c6e5a390303fb50a7c618bba5ef3e Mon Sep 17 00:00:00 2001 From: "1960116313@qq.com" <1960116313@qq.com> Date: Sun, 21 Jan 2024 16:30:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E7=AD=BE=E5=88=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 3 + src/components/AppRecharge/index.vue | 8 +- src/views/task/components/BasicTask/index.vue | 15 +- src/views/task/components/HisTory/index.ts | 5 + src/views/task/components/HisTory/index.vue | 257 ++++++++++++++++++ .../task/components/InviteForm/index.vue | 17 +- 7 files changed, 289 insertions(+), 17 deletions(-) create mode 100644 src/views/task/components/HisTory/index.ts create mode 100644 src/views/task/components/HisTory/index.vue diff --git a/package.json b/package.json index 692cfc6..c16f472 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "axios": "^1.6.5", "clipboard-copy": "^4.0.1", "crypto-js": "^4.2.0", + "dayjs": "^1.11.10", "lodash-es": "^4.17.21", "md-editor-v3": "^4.11.0", "mqtt": "^5.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f86dee7..e524664 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: crypto-js: specifier: ^4.2.0 version: 4.2.0 + dayjs: + specifier: ^1.11.10 + version: 1.11.10 lodash-es: specifier: ^4.17.21 version: 4.17.21 diff --git a/src/components/AppRecharge/index.vue b/src/components/AppRecharge/index.vue index 23e091b..0fc6aa9 100644 --- a/src/components/AppRecharge/index.vue +++ b/src/components/AppRecharge/index.vue @@ -10,6 +10,8 @@ import { useRechargeStore } from '@/store/moules/rechareStore' const rechargeStore = useRechargeStore() const carouselRef = ref() +// 选项卡索引 +const activeTab = ref(0) function getType() { goodsType().then((res) => { console.log(res) @@ -19,6 +21,7 @@ getType() // 关闭充值弹窗 function handleClose() { rechargeStore.rechargeClose() + activeTab.value = 0 } // 选项卡目录 const tabs = ref([ @@ -28,8 +31,7 @@ const tabs = ref([ { title: '年套餐', active: false }, { title: '至尊礼遇卡', active: false }, ]) -// 选项卡索引 -const activeTab = ref(0) + const items = ref(['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8']) // 选中选项卡 @@ -632,7 +634,7 @@ function onNextClick() { border-top-left-radius: 12px; border-top-right-radius: 12px; position: relative; - transition: all 0.3s ease; + transition: all 0.3s ease-out; } .tab:not(:last-child)::after { content: ''; diff --git a/src/views/task/components/BasicTask/index.vue b/src/views/task/components/BasicTask/index.vue index a1efe3f..8a2e1c1 100644 --- a/src/views/task/components/BasicTask/index.vue +++ b/src/views/task/components/BasicTask/index.vue @@ -1,7 +1,8 @@ <script lang="ts" setup> import { ref } from 'vue' -import handleAck from 'mqtt/lib/handlers/ack' +import { Popover } from 'ant-design-vue' import { InviteForm } from '../InviteForm/index' +import { HisTory } from '../HisTory/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' @@ -86,9 +87,15 @@ function handleInvite() { </div> <div class="historyBox"> <img class="historyImg" :src="History" alt=""> - <div class="historyName"> - 历史 - </div> + + <Popover placement="bottomRight" trigger="click"> + <template #content> + <HisTory /> + </template> + <div class="historyName"> + 历史 + </div> + </Popover> </div> </div> <div class="bottom"> diff --git a/src/views/task/components/HisTory/index.ts b/src/views/task/components/HisTory/index.ts new file mode 100644 index 0000000..d2f89ae --- /dev/null +++ b/src/views/task/components/HisTory/index.ts @@ -0,0 +1,5 @@ +import HisTory from './index.vue' + +export { + HisTory, +} diff --git a/src/views/task/components/HisTory/index.vue b/src/views/task/components/HisTory/index.vue new file mode 100644 index 0000000..c9f9f2a --- /dev/null +++ b/src/views/task/components/HisTory/index.vue @@ -0,0 +1,257 @@ +<script lang="ts" setup> +import { onMounted, ref } from 'vue' +import dayjs from 'dayjs' +import { Button, Calendar } from 'ant-design-vue' +import { + LeftOutlined, + RightOutlined, +} from '@ant-design/icons-vue' + +const data = ref(dayjs()) + +const datesData = ref<any>([]) +const month = ref(data.value.month() + 1) + +// 切换月 将来月不能切换 +function changeMonth(type: number) { + if (type > 0) { + const tempDate = dayjs(data.value).add(1, 'month') + if (tempDate.isAfter(dayjs(), 'month')) { + return + } + data.value = tempDate + } + else { + data.value = dayjs(data.value).subtract(1, 'month') + } + month.value = data.value.month() + 1 +} +// 自定义日历头 +function format(val: string | number | dayjs.Dayjs | Date | null | undefined) { + const newVal = dayjs(val).format('YYYY年MM月') + return newVal +} +// 自定义日期样式 1已领取 2 过期 3 未领取 将来的直接 return +const getCellTypeClass = function (value: { $D: string | number }) { + const data = datesData.value[value.$D] + + if (!data) { + return 'future-date' + } + + switch (data.type) { + case 1: + return 'current-date' + case 2: + return 'past-date' + case 3: + return 'future-date' + } +} + +onMounted(async () => { + // 假设fetchDatesData()是从后端获取日期数据的异步函数 + datesData.value = [ + { + num: 10, + type: 1, + }, + { + num: 1, + type: 1, + }, + + { + num: 1, + type: 2, + }, + { + num: 10, + type: 2, + }, + { + num: 1, + type: 1, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 1, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 2, + }, + { + num: 10, + type: 1, + }, + { + num: 1, + type: 1, + }, + { + num: 1, + type: 1, + }, + + { + num: 1, + type: 2, + }, + { + num: 10, + type: 2, + }, + { + num: 1, + type: 1, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 1, + }, + { + num: 1, + type: 2, + }, + { + num: 1, + type: 2, + }, + { + num: 10, + type: 3, + }, + + ] +}) +</script> + +<template> + <div class="haitoryBox"> + <Calendar + v-model:value="data" + :fullscreen="false" + > + <template #headerRender="{ value }"> + <div class="header"> + <Button type="link" style="margin-right: 8px;color: #B3B6BB;" @click="changeMonth(-1)"> + <LeftOutlined /> + </Button> + <span>{{ format(value) }}</span> + <Button type="link" style="margin-left: 8px;color: #B3B6BB;" @click="changeMonth(1)"> + <RightOutlined /> + </Button> + </div> + </template> + <!-- :class="getDateClass(value)" --> + <template #dateFullCellRender="{ current: value }"> + <div v-if="value.month() === data.month() && value.year() === data.year()"> + <div class="cellBox"> + <div class="cellItem" :class="getCellTypeClass(value)"> + <div class="count"> + {{ datesData[value.$D]?.num ? datesData[value.$D]?.num : "1" }}点数 + </div> + </div> + <div v-if="dayjs(value).isSame(dayjs(), 'day') && datesData[value.$D]?.type === 3 " class="getbtn"> + 领取 + </div> + <div v-else class="monthday"> + {{ month }}.{{ value.date() }} + </div> + </div> + </div> + </template> + </Calendar> + </div> +</template> + +<style scoped lang="scss"> +.haitoryBox { + width: 30vw; + .header { + width: 97%; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + } + .cellBox { + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + .getbtn { + width: 35px; + height: 14px; + background: linear-gradient(180deg, #ffb33d 0%, #ff9b00 100%); + border-radius: 11px; + font-size: 10px; + color: white; + margin-top: 1px; + } + .monthday { + width: 35px; + height: 14px; + font-size: 11px; + } + .cellItem { + width: 40px; + height: 50px; + &.future-date { + width: 40px; + height: 50px; + background-image: url(@/assets/images/task/dlq.png); + background-size: 100% 100%; + } + &.past-date { + width: 40px; + height: 50px; + background-image: url(@/assets/images/task/wlq.png); + background-size: 100% 100%; + } + &.current-date { + width: 40px; + height: 50px; + background-image: url(@/assets/images/task/ylq.png); + background-size: 100% 100%; + } + &.current-date2 { + width: 100px; + height: 50px; + background-image: url(@/assets/images/task/ylq.png); + background-size: 100% 100%; + } + .count { + font-size: 9px; + font-family: PingFang-SC, PingFang-SC; + font-weight: 500; + color: #ff9b00; + text-align: center; + font-weight: bold; + padding-top: 3px; + } + } + } +} +</style> diff --git a/src/views/task/components/InviteForm/index.vue b/src/views/task/components/InviteForm/index.vue index 675710b..edd3a4d 100644 --- a/src/views/task/components/InviteForm/index.vue +++ b/src/views/task/components/InviteForm/index.vue @@ -38,13 +38,9 @@ function copyText() { message.success({ content: () => '复制成功', class: 'message-class', + }) - // 复制成功后的操作 }) - // .catch(() => { - // console.log('Failed to copy!') - // // 复制失败后的操作 - // }) } </script> @@ -88,9 +84,13 @@ function copyText() { </template> <style scoped lang="scss"> - .modal-mask { - position: fixed; +.message-class { + position: relative; z-index: 9999; +} +.modal-mask { + position: fixed; + z-index: 10; top: 0; left: 0; width: 100%; @@ -215,7 +215,4 @@ function copyText() { .modal-leave-from { opacity: 1; } -:deep(.message-class) { - z-index: 200; -} </style>