This commit is contained in:
2025-05-26 19:46:42 +08:00
parent b62c715dfd
commit c302c8ae50
12 changed files with 537 additions and 53 deletions

View File

@@ -1,26 +1,28 @@
<script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import {reactive, ref} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const columns = [
{
title: '编号',
dataIndex: 'key',
dataIndex: 'code',
},
{
title: '任务编号',
dataIndex: 'key',
dataIndex: 'm_code',
},
{
title: '子任务编号',
dataIndex: 'key',
dataIndex: 'uid',
},
{
title: '文字',
dataIndex: 'key',
dataIndex: 'content',
slotName: 'content',
},
{
title: '图片',
@@ -29,19 +31,19 @@ const columns = [
},
{
title: '来源',
dataIndex: 'key',
dataIndex: 'type_text',
},
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'type_uid',
},
{
title: '类型',
dataIndex: 'key',
dataIndex: 'pattern_text',
},
{
title: '时间',
dataIndex: 'key',
dataIndex: 'createtime',
},
{
title: '操作',
@@ -87,12 +89,14 @@ const FilterConfig = [
}
];
const selectedKeys = ref([]);
const rowSelection = reactive({
type: 'checkbox',
showCheckedAll: true,
onlyCurrent: false,
});
const po = reactive({
pass: 0,
rangeTime: null,
});
const vo = reactive({
@@ -101,14 +105,38 @@ const vo = reactive({
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
const {loading, pagination, initFetchData, fetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
api: Api.admin.getExchangeLog,
callback: (data) => {
Object.assign(vo, data);
console.log(vo);
}
});
const passExchange = async (id) => {
const {msg} = await Api.admin.passExchange([id]);
Message.success(msg);
await fetchData();
}
const refuseExchange = async (id) => {
const {msg} = await Api.admin.refuseExchange([id]);
Message.success(msg);
await fetchData();
}
const passExchangeAll = async () => {
const {msg} = await Api.admin.passExchange(selectedKeys.value);
Message.success(msg);
await fetchData();
}
const refuseExchangeAll = async () => {
const {msg} = await Api.admin.refuseExchange(selectedKeys.value);
Message.success(msg);
await fetchData();
}
</script>
<template>
@@ -119,7 +147,13 @@ const {loading, pagination, initFetchData} = useTableQuery({
:config="FilterConfig">
</Filter>
<div class="flex gap-[20px] mb-[20px]">
<a-button type="primary" @click="passExchangeAll">批量通过</a-button>
<a-button type="primary" @click="refuseExchangeAll">批量拒绝</a-button>
</div>
<a-table
v-model:selectedKeys="selectedKeys"
:row-selection="rowSelection"
:data="vo.rows"
@page-change="(e) => pagination.current = e"
@@ -127,18 +161,25 @@ const {loading, pagination, initFetchData} = useTableQuery({
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:image>
<a-image
width="40px"
height="40px"
src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp">
</a-image>
<template v-slot:content="{record}">
<view v-html="record.content"></view>
</template>
<template v-slot:action>
<template v-slot:image="{record}">
<div class="flex gap-[12px]">
<a-image
v-for="v in images_arr"
width="40px"
height="40px"
:src="v">
</a-image>
</div>
</template>
<template v-slot:action="{record}">
<div class="flex items-center gap-[20px]">
<a-link :hoverable="false" status="success">通过</a-link>
<a-link :hoverable="false" status="danger">拒绝</a-link>
<a-link @click="passExchange(record.id)" :hoverable="false" status="success">通过</a-link>
<a-link @click="refuseExchange(record.id)" :hoverable="false" status="danger">拒绝</a-link>
</div>
</template>
</a-table>

View File

@@ -1,26 +1,28 @@
<script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import {reactive, ref} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const columns = [
{
title: '编号',
dataIndex: 'key',
dataIndex: 'code',
},
{
title: '任务编号',
dataIndex: 'key',
dataIndex: 'm_code',
},
{
title: '子任务编号',
dataIndex: 'key',
dataIndex: 'uid',
},
{
title: '文字',
dataIndex: 'key',
dataIndex: 'content',
slotName: 'content',
},
{
title: '图片',
@@ -29,19 +31,19 @@ const columns = [
},
{
title: '来源',
dataIndex: 'key',
dataIndex: 'type_text',
},
{
title: 'ID',
dataIndex: 'key',
dataIndex: 'type_uid',
},
{
title: '类型',
dataIndex: 'key',
dataIndex: 'pattern_text',
},
{
title: '时间',
dataIndex: 'key',
dataIndex: 'createtime',
},
{
title: '操作',
@@ -110,13 +112,14 @@ const FilterConfig = [
}
];
const selectedKeys = ref([]);
const rowSelection = reactive({
type: 'checkbox',
showCheckedAll: true,
onlyCurrent: false,
});
const po = reactive({
pass: 0
pass: 1,
});
const vo = reactive({
page: '',
@@ -124,13 +127,37 @@ const vo = reactive({
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
const {loading, pagination, initFetchData, fetchData} = useTableQuery({
parameter: po,
api: Api.admin.getExchangeLog,
callback: (data) => {
Object.assign(vo, data);
}
});
const passExchange = async (id) => {
const {msg} = await Api.admin.passExchange([id]);
Message.success(msg);
await fetchData();
}
const refuseExchange = async (id) => {
const {msg} = await Api.admin.refuseExchange([id]);
Message.success(msg);
await fetchData();
}
const passExchangeAll = async () => {
const {msg} = await Api.admin.passExchange(selectedKeys.value);
Message.success(msg);
await fetchData();
}
const refuseExchangeAll = async () => {
const {msg} = await Api.admin.refuseExchange(selectedKeys.value);
Message.success(msg);
await fetchData();
}
</script>
<template>
@@ -142,7 +169,13 @@ const {loading, pagination, initFetchData} = useTableQuery({
:config="FilterConfig">
</Filter>
<div class="flex gap-[20px] mb-[20px]">
<a-button type="primary" @click="passExchangeAll">批量通过</a-button>
<a-button type="primary" @click="refuseExchangeAll">批量拒绝</a-button>
</div>
<a-table
v-model:selectedKeys="selectedKeys"
:row-selection="rowSelection"
:data="vo.rows"
@page-change="(e) => pagination.current = e"
@@ -150,18 +183,25 @@ const {loading, pagination, initFetchData} = useTableQuery({
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:image>
<a-image
width="40px"
height="40px"
src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp">
</a-image>
<template v-slot:content="{record}">
<view v-html="record.content"></view>
</template>
<template v-slot:action>
<template v-slot:image="{record}">
<div class="flex gap-[12px]">
<a-image
v-for="v in images_arr"
width="40px"
height="40px"
:src="v">
</a-image>
</div>
</template>
<template v-slot:action="{record}">
<div class="flex items-center gap-[20px]">
<a-link :hoverable="false" status="success">通过</a-link>
<a-link :hoverable="false" status="danger">拒绝</a-link>
<a-link @click="passExchange(record.id)" :hoverable="false" status="success">通过</a-link>
<a-link @click="refuseExchange(record.id)" :hoverable="false" status="danger">拒绝</a-link>
</div>
</template>
</a-table>

View File

@@ -0,0 +1,141 @@
<script setup>
import {reactive, ref, watch} from "vue";
import Api from "../../../../../api";
import XImage from "../../../../../components/XImage/Index.vue";
import UploadButton from "../../../../../components/upload/UploadButton.vue";
const {task} = defineProps({
task: {
type: Object,
default: {},
}
});
const visible = ref(false);
const TaskSettltment = reactive([]);
const columns = [
{
title: '提前约定事项',
dataIndex: 'intro'
},
{
title: '扣除比例',
dataIndex: 'ratio'
},
{
title: '扣除金额(元)',
dataIndex: 'discount',
slotName: 'discount'
},
{
title: '截图说明',
dataIndex: 'images',
slotName: 'images',
width: 250,
},
];
const rowSelection = reactive({
type: 'checkbox',
showCheckedAll: true,
onlyCurrent: false,
});
const selectedKeys = ref([]);
watch(
() => visible.value,
(val) => {
if (val) Api.merchant.getTaskSettltment({id: task.task_id}).then(({data}) => {
TaskSettltment.length = 0;
TaskSettltment.push(...data.map((v, index) => ({
...v,
key: index,
images: [],
})));
});
}
)
const confirmTask = () => {
Api.merchant.confirmTask({
id: task.id,
content: TaskSettltment.filter((v, index) => selectedKeys.value.includes(index)).map(v => ({
id: v.id,
images: v.images,
})),
});
}
</script>
<template>
<a-link @click="visible = true" :hoverable="false" status="success">
确认结算
</a-link>
<a-modal
width="800px"
title-align="start"
@ok="confirmTask"
v-model:visible="visible">
<template v-slot:title>
<div>确认结算</div>
<div class="text-[14px] text-[#4E5969] ml-[8px]">提示若有扣款请提供对应截图方便达人理解</div>
</template>
<a-table
:data="TaskSettltment"
:columns="columns"
:pagination="false"
:row-selection="rowSelection"
v-model:selectedKeys="selectedKeys">
<template v-slot:discount="{record}">
{{ record.discount.toFixed(2) }}
</template>
<template v-slot:images="{record}">
<div class="flex gap-[16px]">
<x-image
v-for="(v, index) in record.images"
class="flex-shrink-0"
:key="index"
width="40px"
height="40px"
:src="v">
</x-image>
<upload-button :api="Api.system.uploadFile2" @success="e => record.images.push(e)">
<template v-slot:upload-button>
<div
class="size-[40px] bg-[#F2F3F5] flex justify-center items-center flex-col rounded-[8px] cursor-pointer">
<icon-plus/>
<div>添加</div>
</div>
</template>
</upload-button>
</div>
</template>
</a-table>
<div class="mt-[22px] flex">
该子任务需结算
<div class="text-[#165DFF] text-[16px]">¥{{
task.coin / 100
-
TaskSettltment.filter((v, index) => selectedKeys.includes(index)).reduce((accumulator, item) => {
return accumulator + item.discount;
}, 0)
}}
</div>
<div class="text-[14px] text-[#4E5969]" v-if="selectedKeys.length > 0">
{{ task.coin / 100 }}
<span v-for="v in selectedKeys">- {{ TaskSettltment[v].discount }}</span>
= {{
task.coin / 100
-
TaskSettltment.filter((v, index) => selectedKeys.includes(index)).reduce((accumulator, item) => {
return accumulator + item.discount;
}, 0)
}}
</div>
</div>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -11,6 +11,8 @@ import {openUrl, toPath} from "../../../../utils/index.js";
import PreviewTaskMaterialModal from "./components/PreviewTaskMaterialModal.vue";
import {Message} from "@arco-design/web-vue";
import EffectManagementModal from "./components/effectManagementModal.vue";
import Settlement from "./components/Settlement.vue";
import Chat from "../../../../components/Chat/index.vue";
const route = useRoute();
const taskId = ref(null);
@@ -43,7 +45,7 @@ const columns = [
},
{
title: '领取时间',
dataIndex: 'key',
dataIndex: 'accept_time',
},
{
title: '达人反馈',
@@ -69,7 +71,9 @@ const columns = [
];
const state = reactive({
openBlackjackExpertModal: false,
openEffectManagementModal: false
openEffectManagementModal: false,
showChat: false,
task: null,
})
const vo = reactive({
@@ -99,10 +103,6 @@ const passTask = async (id, task_backfill_id) => {
Message.success(msg);
await fetchData();
}
const confirmTask = async () => {
}
</script>
<template>
@@ -189,16 +189,17 @@ const confirmTask = async () => {
</div>
</template>
<template v-slot:callback>
<a-link :hoverable="false">
<template v-slot:callback="{record}">
<a-link :hoverable="false" @click="() => {
state.showChat = true;
state.task = record
}">
沟通记录
</a-link>
</template>
<template v-slot:payStatus>
<a-link :hoverable="false" status="success" @click="confirmTask">
确认结算
</a-link>
<template v-slot:payStatus="{record}">
<settlement :task="record"></settlement>
</template>
<template v-slot:action2="{record}">
@@ -247,6 +248,11 @@ const confirmTask = async () => {
v-model:visible="state.openEffectManagementModal"
@success="fetchData">
</effect-management-modal>
<Chat
:task="state.task"
v-model:visible="state.showChat">
</Chat>
</template>
<style scoped>