This commit is contained in:
2025-03-28 09:37:10 +08:00
parent 505af229fc
commit 168895b5ac
15 changed files with 347 additions and 6 deletions

View File

@@ -57,6 +57,7 @@
"@tailwindcss/vite": "^4.0.15",
"@uni-helper/vite-plugin-uni-tailwind": "^0.15.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"deep-pick-omit": "^1.2.1",
"destr": "^2.0.3",
"pinia": "^2.2.4",

8
pnpm-lock.yaml generated
View File

@@ -65,6 +65,9 @@ importers:
crypto-js:
specifier: ^4.2.0
version: 4.2.0
dayjs:
specifier: ^1.11.13
version: 1.11.13
deep-pick-omit:
specifier: ^1.2.1
version: 1.2.1
@@ -2167,6 +2170,9 @@ packages:
resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==}
engines: {node: '>=10'}
dayjs@1.11.13:
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies:
@@ -6985,6 +6991,8 @@ snapshots:
whatwg-mimetype: 2.3.0
whatwg-url: 8.7.0
dayjs@1.11.13: {}
debug@2.6.9:
dependencies:
ms: 2.0.0

View File

@@ -1,6 +1,7 @@
<script setup>
import dy from "../static/images/抖音.png";
import qrw from "../static/icons/qrw.png";
import XCountdown from "./XCountdown.vue";
</script>
<template>
@@ -9,9 +10,12 @@ import qrw from "../static/icons/qrw.png";
<view style="font-size: 28rpx">
任务编号DF1212
</view>
<view style="font-size: 24rpx">
<view v-if="false" style="font-size: 24rpx">
<Text class="text-[#165DFF]">08-13-09:54</Text>后可开始回填
</view>
<x-countdown v-else>
<view style="font-size: 24rpx;font-weight: 400;" class="text-[rgb(78,89,105)]">审核倒计时:</view>
</x-countdown>
</view>
<view class="!flex gap-[26rpx] !pt-[20rpx]">

25
src/components/XAlert.vue Normal file
View File

@@ -0,0 +1,25 @@
<script setup>
import {ref} from "vue";
const show = ref(false);
</script>
<template>
<view @click="show=true">
<slot></slot>
</view>
<tui-alert
fadeIn
v-bind="$attrs"
@cancel="show=false"
maskClosable
@click="show=false"
:show="show">
<slot name="context"></slot>
</tui-alert>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,50 @@
<script setup>
import {ref} from "vue";
import dayjs from "dayjs";
const {time} = defineProps({
time: {
type: String,
default: '2025-03-28 10:10:00',
}
});
const diff = ref(dayjs(time).diff(dayjs(new Date()), 'second'));
const hours = ref(null);
const minutes = ref(null);
const seconds = ref(null);
const timer = setInterval(() => {
diff.value = dayjs(time).diff(dayjs(new Date()), 'second');
hours.value = Math.floor(diff.value / 3600);
minutes.value = Math.floor((diff.value % 3600) / 60);
seconds.value = diff.value % 60;
}, 1000);
</script>
<template>
<view class="!flex items-center gap-[20rpx]">
<slot></slot>
<view class="!flex gap-[16rpx] items-center">
<view class="time-block" v-if="hours">{{ hours < 10 ? `0${hours}` : hours }}</view>
<view v-if="hours">:</view>
<view class="time-block" v-if="minutes">{{ minutes < 10 ? `0${minutes}` : minutes }}</view>
<view v-if="minutes">:</view>
<view class="time-block" v-if="seconds">{{ seconds < 10 ? `0${seconds}` : seconds }}</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.time-block {
background-color: #E8F3FF;
border-radius: 4rpx;
padding: 4rpx;
color: rgb(22, 93, 255);
font-size: 24rpx;
font-weight: 500;
line-height: 140%;
letter-spacing: 0;
text-align: center;
}
</style>

View File

@@ -0,0 +1,17 @@
<script setup>
import XDateTime from "./XDateTime.vue";
const startTime = defineModel('startTime');
const endTime = defineModel('endTime');
</script>
<template>
<view class="!flex gap-[20rpx] !w-full items-center">
<x-date-time v-model:model-value="startTime"></x-date-time>
<view class="">-</view>
<x-date-time v-model:model-value="endTime"></x-date-time>
</view>
</template>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,36 @@
<script setup>
import timeIcon from "../static/icons/time.png";
const modalValue = defineModel();
const {placeholder} = defineProps({
placeholder: {
type: String,
default: "请选择时间",
}
});
const success = ({detail: {value}}) => {
modalValue.value = value;
}
</script>
<template>
<picker mode="date" class="x-date-input" @change="success">
<view>
<image class="!size-[24rpx] !absolute left-[30rpx] top-1/2 -translate-y-1/2" :src="timeIcon"></image>
<text v-if="!modalValue" class="text-[#666]">{{ placeholder }}</text>
<text v-else>{{modalValue}}</text>
</view>
</picker>
</template>
<style lang="scss" scoped>
.x-date-input {
background-color: #F2F3F5;
padding: 14rpx 0;
flex-grow: 1;
text-align: center;
border-radius: 4rpx;
position: relative;
}
</style>

View File

@@ -0,0 +1,38 @@
<script setup>
const visible = defineModel('visible');
const model = defineModel('model');
const emits = defineEmits(['success']);
const init = () => {
Object.keys(model.value).forEach(key => {
model.value[key] = null;
});
success();
}
const success = () => {
visible.value = false;
emits('success');
}
</script>
<template>
<tui-drawer
mode="top"
maskZIndex="999"
zIndex="999"
@close="visible=false"
:visible="visible">
<view class="!pt-[100rpx] !p-[32rpx]">
<slot></slot>
<view class="!flex gap-[24rpx] !mt-[24rpx]">
<tui-button height="88rpx" plain @click="init">重置</tui-button>
<tui-button height="88rpx" @click="success">确定</tui-button>
</view>
</view>
</tui-drawer>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,29 @@
<script setup>
const {label} = defineProps({
label: {
type: String,
default: "标题",
}
});
</script>
<template>
<view class="x-filter-item">
<view class="label">{{ label }}</view>
<slot></slot>
</view>
</template>
<style lang="scss" scoped>
.x-filter-item {
margin-bottom: 36rpx;
}
.label {
color: rgb(134, 144, 156);
font-size: 24rpx;
font-weight: 500;
letter-spacing: 0;
text-align: left;
margin-bottom: 24rpx;
}
</style>

View File

@@ -14,7 +14,7 @@ const title = ref(document.title);
<template>
<template v-if="!isWXWeb()">
<view class="!flex justify-center items-center w-full h-[100rpx] bg-[#f9f9f9] fixed left-0 top-0 z-[998]">
<view class="!flex justify-center items-center w-full h-[100rpx] bg-[#f9f9f9] fixed left-0 top-0 z-[1000]">
<image
v-if="showBack"
@click="backPage()"

36
src/components/XRadio.vue Normal file
View File

@@ -0,0 +1,36 @@
<script setup>
import {inject} from "vue";
const modelValue = inject('modelValue');
const {value} = defineProps({
value: {
type: [String, Number],
default: 0
}
});
</script>
<template>
<view @click="modelValue=value" :class="['x-radio', modelValue===value ? 'x-radio-cur' : '']">
<slot></slot>
</view>
</template>
<style lang="scss" scoped>
.x-radio {
padding: 12rpx 0;
text-align: center;
background-color: #F7F8FA;
border-radius: 4rpx;
color: rgb(78, 89, 105);
font-size: 24rpx;
font-weight: 500;
line-height: 20px;
letter-spacing: 0;
transition: 500ms;
}
.x-radio-cur {
background-color: #E8F3FF;
color: #165DFF;
}
</style>

View File

@@ -0,0 +1,17 @@
<script setup>
import {provide} from "vue";
const modalValue = defineModel();
provide('modelValue', modalValue);
</script>
<template>
<view>
<slot></slot>
</view>
</template>
<style scoped>
</style>

View File

@@ -5,6 +5,12 @@ import {reactive, ref} from "vue";
import TaskCard from "../../components/TaskCard.vue";
import useTableQuery from "../../hooks/useTableQuery.js";
import Api from "../../api/index.js";
import XFilter from "../../components/XFilter.vue";
import XFilterItem from "../../components/XFilterItem.vue";
import XRadioGroup from "../../components/XRadioGroup.vue";
import XRadio from "../../components/XRadio.vue";
import XDateRange from "../../components/XDateRange.vue";
import XAlert from "../../components/XAlert.vue";
const tabs = [
{
@@ -25,8 +31,14 @@ const tabs = [
},
];
const current = ref(0);
const po = reactive({});
const showFilter = ref(false);
const sumPo = reactive({
type: 0,
startTime: null,
endTime: null,
});
const po = reactive({
});
const vo = reactive({
page: '',
rows: [],
@@ -48,6 +60,49 @@ const {loading, pagination, initFetchData} = useTableQuery({
<!--我的任务-->
<XNav :show-back="false"></XNav>
<x-filter
v-model:model="sumPo"
v-model:visible="showFilter">
<x-filter-item label="任务类型">
<x-radio-group v-model:model-value="sumPo.type">
<view class="!grid grid-cols-4 gap-[24rpx]">
<x-radio :value="0">全部任务</x-radio>
<x-radio :value="1">宣发</x-radio>
<x-radio :value="2">评论</x-radio>
<x-radio :value="3">续期</x-radio>
</view>
</x-radio-group>
</x-filter-item>
<x-filter-item label="发布平台">
<x-radio-group v-model:model-value="sumPo.type">
<view class="!grid grid-cols-4 gap-[24rpx]">
<x-radio :value="0">全部平台</x-radio>
<x-radio :value="1">抖音</x-radio>
<x-radio :value="2">快手</x-radio>
<x-radio :value="3">视频号</x-radio>
<x-radio :value="4">小红书</x-radio>
<x-radio :value="5">今日头条</x-radio>
<x-radio :value="6">咸鱼</x-radio>
</view>
</x-radio-group>
</x-filter-item>
<x-filter-item label="结算状态">
<x-radio-group v-model:model-value="sumPo.type">
<view class="!grid grid-cols-4 gap-[24rpx]">
<x-radio :value="0">全部状态</x-radio>
<x-radio :value="1">未结算</x-radio>
<x-radio :value="2">已结算</x-radio>
</view>
</x-radio-group>
</x-filter-item>
<x-filter-item label="选择时间段">
<x-date-range
v-model:end-time="sumPo.endTime"
v-model:start-time="sumPo.startTime">
</x-date-range>
</x-filter-item>
</x-filter>
<scroll-view
@refresherpulling="initFetchData()"
@scrolltolower="pagination.current++"
@@ -63,6 +118,7 @@ const {loading, pagination, initFetchData} = useTableQuery({
<view class="!w-full text-center !flex justify-center items-center">全部状态</view>
<view class="!w-full text-center !flex justify-center items-center">
<view
@click="showFilter=true"
class="!flex items-center justify-center gap-[10rpx] !py-[10rpx] !px-[30rpx] bg-[#0E42D2] rounded-[8rpx]">
<image class="!w-[22rpx] !h-[22rpx]" :src="filer"></image>
筛选
@@ -95,14 +151,24 @@ const {loading, pagination, initFetchData} = useTableQuery({
</view>
<view
class="!w-full !h-[146rpx] !bg-[#E8FFEA] !py-[24rpx] !px-[32rpx] box-border !flex flex-col justify-between rounded-[12rpx]">
<view class="block-title">到账收益()</view>
<view class="block-title !flex gap-[6rpx] items-center">
到账收益()
<x-alert btnText="知道了" btnColor="#165DFF">
<tui-icon name="explain" :size="16" ></tui-icon>
<template #context>
<view style="font-size: 32rpx;font-weight: 500" class="!mb-[30rpx]">到账收益</view>
<view style="font-size: 28rpx;font-weight: 400" class="text-[rgb(78,89,105)]">根据您的任务完成情况</view>
<view style="font-size: 28rpx;font-weight: 400" class="text-[rgb(78,89,105)] !mt-[10rpx]">实际获得的收益</view>
</template>
</x-alert>
</view>
<view class="block-value">5.60</view>
</view>
</view>
</view>
</view>
<view class="!grid grid-cols-4 gap-[20rpx] !px-[20rpx] sticky top-0 bg-[#F2F3F5] z-10 py-[20rpx]">
<view class="!grid grid-cols-4 gap-[20rpx] !px-[20rpx] bg-[#F2F3F5] py-[20rpx]">
<view
v-for="item in tabs"
@click="current=item.value"

View File

@@ -1,3 +1,5 @@
$primary-color: #2D5CF6;
.test {
border: 1px solid red;
@apply box-border;
@@ -6,3 +8,15 @@
.tui-btn {
border-radius: 12rpx !important;
}
.tui-primary-outline {
background-color: lighten($primary-color, 40%) !important;
}
.tui-alert-box {
border-radius: 16rpx !important;
overflow: hidden;
.tui-alert-content {
padding: 40rpx 32rpx !important;
}
}

BIN
src/static/icons/time.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B