This commit is contained in:
2025-06-12 20:53:39 +08:00
parent 148e78abf9
commit e10695098c
21 changed files with 467 additions and 51 deletions

View File

@@ -1,3 +1,10 @@
### 2025-06-12
测试文档过到第145条
进度:
测试流程(商家&超管端): 创建任务 -> 任务审核(状态流转) -> 子任务素材上传 -> 子任务审核(状态流转) -> 代付款 -> 支付(充值) -> 开始任务
大人端 领取任务 -> 查看素材
### 2025-06-10 ### 2025-06-10
测试文档过到第96条 测试文档过到第96条

View File

@@ -82,6 +82,13 @@ const admin = {
data: {id}, data: {id},
}); });
}, },
editTask: async (data) => {
return request({
url: '/admin/task/editTask',
method: Method.POST,
data: data,
});
},
getStatusList: async () => { getStatusList: async () => {
return request({ return request({
url: '/admin/taskChildren/getStatusList', url: '/admin/taskChildren/getStatusList',

View File

@@ -498,6 +498,34 @@ const merchant = {
data: data data: data
}); });
}, },
TemplateToTask: async (data) => {
return request({
url: '/index/task/TemplateToTask',
method: Method.POST,
data: data
});
},
delTemplate: async (data) => {
return request({
url: '/index/task/delTemplate',
method: Method.POST,
data: data
});
},
weighTemplate: async (data) => {
return request({
url: '/index/task/weighTemplate',
method: Method.POST,
data: data
});
},
saveNewTask: async (data) => {
return request({
url: '/index/task/saveNewTask',
method: Method.POST,
data: data
});
},
} }
export default merchant; export default merchant;

View File

@@ -1,4 +1,5 @@
<script setup> <script setup>
import {computed} from "vue";
import Api from "../../api/index.js"; import Api from "../../api/index.js";
import {Message} from "@arco-design/web-vue"; import {Message} from "@arco-design/web-vue";
@@ -13,6 +14,7 @@ const {data, hideDelete} = defineProps({
default: false, default: false,
} }
}); });
const list = computed(() => data?.flatMap(v => v.children ? [v, ...v.children] : [v]));
const del = async (id) => { const del = async (id) => {
const {msg} = await Api.merchant.delChildrenComment(id); const {msg} = await Api.merchant.delChildrenComment(id);
Message.success(msg); Message.success(msg);
@@ -21,12 +23,12 @@ const del = async (id) => {
</script> </script>
<template> <template>
<div v-for="(item, index) in data" :key="item.id" class="flex items-center"> <div v-for="(item, index) in list" :key="item.id" class="flex items-center">
<div class="mr-[5px] min-w-[15px]">{{ index + 1 }}.</div> <div class="mr-[5px] min-w-[15px]">{{ index + 1 }}.</div>
<div class="box"> <div class="box">
<div class="flex items-center whitespace-nowrap" v-if="item.pid>0"> <div class="flex items-center whitespace-nowrap" v-if="item.pid>0">
<img class="size-[9px] mr-[5px]" src="../../assets/images/back.png" alt=""/> <img class="size-[9px] mr-[5px]" src="../../assets/images/back.png" alt=""/>
回复{{ data.findIndex(k => k.pid === item.pid) }}: 回复{{ list.findIndex(k => k.pid === item.pid) }}:
</div> </div>
<img class="size-[32px]" v-if="item.image" :src="item.image" alt=""/> <img class="size-[32px]" v-if="item.image" :src="item.image" alt=""/>
<div class="whitespace-nowrap">{{ item.intro }}</div> <div class="whitespace-nowrap">{{ item.intro }}</div>

View File

@@ -30,7 +30,10 @@ const initQR = async () => {
</script> </script>
<template> <template>
<a-button type="primary" @click="open">立即充值</a-button> <a-button v-if="!$slots.default" type="primary" @click="open">立即充值</a-button>
<div @click="open">
<slot></slot>
</div>
<a-modal <a-modal
:footer="false" :footer="false"

View File

@@ -0,0 +1,53 @@
<script setup lang="ts">
import {ref} from "vue";
import Alipay from "./Alipay.vue";
const visible = ref(false);
const money = ref(null);
</script>
<template>
<div @click="visible=true">
<slot></slot>
</div>
<a-modal
title="充值"
:width="600"
title-align="start"
id="GoTask-Modal"
v-model:visible="visible">
<a-alert>平台提示该款项不会直接打给达人只有您对子任务确认结算后才会打款给达人</a-alert>
<div class="p-[24px] h-[370px]">
<a-form layout="vertical">
<a-form-item label="支付方式">
<a-radio :default-checked="true">支付宝</a-radio>
</a-form-item>
<a-form-item label="充值金额">
<a-input-number :min="0" :precision="2" v-model:model-value="money"
placeholder="请输入充值金额"></a-input-number>
</a-form-item>
</a-form>
</div>
<template v-slot:footer>
<div class="flex gap-[24px] justify-end">
<a-button @click="visible=false">取消</a-button>
<Alipay :money="money">
<a-button type="primary" @click="visible=false">下一步</a-button>
</Alipay>
</div>
</template>
</a-modal>
</template>
<style lang="scss">
#GoTask-Modal {
.arco-modal-body {
padding: 0;
}
}
</style>
<style scoped lang="scss">
</style>

View File

@@ -1,5 +1,6 @@
<script setup> <script setup>
import {ref} from "vue"; import {ref} from "vue";
import GoPay from "./GoPay.vue";
const payInfo = ref(null); const payInfo = ref(null);
const visible = ref(false); const visible = ref(false);
@@ -68,10 +69,13 @@ defineExpose({
(可用¥{{ payInfo?.user_money?.toFixed(2) }}) (可用¥{{ payInfo?.user_money?.toFixed(2) }})
</a-radio> </a-radio>
</div> </div>
<div class="text-[12px] text-[#86909C] pl-[20px]"> <div v-if="payInfo.user_money < payInfo?.total_money" class="text-[12px] text-[#86909C] pl-[20px]">
*余额不足本次任务所需,请充值后再进行支付 *余额不足本次任务所需,请充值后再进行支付
</div> </div>
<a-button class="mt-[20px]" type="primary">去充值</a-button> <go-pay>
<a-button class="mt-[20px]" type="primary">去充值
</a-button>
</go-pay>
</div> </div>
</a-modal> </a-modal>
</template> </template>

View File

@@ -3,10 +3,14 @@ import {reactive, ref, watch} from "vue";
import Api from "../../../../../api/index.js"; import Api from "../../../../../api/index.js";
import {Message} from "@arco-design/web-vue"; import {Message} from "@arco-design/web-vue";
const {id} = defineProps({ const {id, disabled} = defineProps({
id: { id: {
type: Number, type: Number,
default: 0 default: 0
},
disabled: {
type: Boolean,
default: 0
} }
}); });
const emits = defineEmits(['success']); const emits = defineEmits(['success']);
@@ -43,7 +47,7 @@ const success = async () => {
</script> </script>
<template> <template>
<a-link :hoverable="false" status="success" @click="visible=true">通过</a-link> <a-link :disabled="disabled" :hoverable="false" status="success" @click="visible=true">通过</a-link>
<a-modal <a-modal
@ok="success" @ok="success"
@@ -52,13 +56,16 @@ const success = async () => {
v-model:visible="visible"> v-model:visible="visible">
<a-form :model="form" layout="vertical"> <a-form :model="form" layout="vertical">
<a-form-item label="该任务对达人端的展示价格为:"> <a-form-item label="该任务对达人端的展示价格为:">
<a-input v-model:model-value="form.real_price" placeholder="请输入价格"></a-input> <a-input-number :min="0" v-model:model-value="form.real_price" placeholder="请输入价格"
:precision="2"></a-input-number>
</a-form-item> </a-form-item>
<a-form-item label="安全评分"> <a-form-item label="安全评分">
<a-input v-model:model-value="form.security_level" placeholder="请输入安全评分满分100"></a-input> <a-input-number :min="0" :max="100" :precision="0" v-model:model-value="form.security_level"
placeholder="请输入安全评分满分100"></a-input-number>
</a-form-item> </a-form-item>
<a-form-item label="耗时评分"> <a-form-item label="耗时评分">
<a-input v-model:model-value="form.time_level" placeholder="请输入耗时评分满分100"></a-input> <a-input-number :min="0" :max="100" :precision="0" v-model:model-value="form.time_level"
placeholder="请输入耗时评分满分100"></a-input-number>
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>

View File

@@ -20,10 +20,12 @@ const columns = [
{ {
title: '子任务状态', title: '子任务状态',
dataIndex: 'status_text', dataIndex: 'status_text',
slotName: 'status_text',
}, },
{ {
title: '平台审核状态', title: '平台审核状态',
dataIndex: 'check_status_text', dataIndex: 'check_status_text',
slotName: 'check_status_text'
}, },
{ {
title: '操作', title: '操作',
@@ -116,16 +118,31 @@ const refuseTaskChildren = async (id) => {
:loading="loading" :loading="loading"
:columns="columns" :columns="columns"
class="flex-grow"> class="flex-grow">
<template v-slot:status_text="{record}">
<a-tag v-if="record.status===0" color="cyan">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===1" color="orangered">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===2" color="red">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===3" color="arcoblue">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===4" color="green">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===5" color="green">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===6">{{ record.status_text }}</a-tag>
</template>
<template v-slot:check_status_text="{record}">
<a-tag v-if="record.check_status===0" color="cyan">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===1" color="green">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===-2">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===-1" color="red">{{ record.check_status_text }}</a-tag>
</template>
<template v-slot:action="{record}"> <template v-slot:action="{record}">
<div class="flex items-center gap-[20px] justify-between"> <div class="flex items-center gap-[20px] justify-between">
<PreviewTaskModal :id="record.id" @success="fetchData"></PreviewTaskModal> <PreviewTaskModal :id="record.id" @success="fetchData"></PreviewTaskModal>
<a-popconfirm content="确定通过?" @ok="passTaskChildren(record.id)"> <a-popconfirm content="确定通过?" @ok="passTaskChildren(record.id)">
<a-link :disabled="record.check_status === 1 || record.check_status === -2" :hoverable="false" <a-link :disabled="record.check_status !== 0 && record.check_status !== -1" :hoverable="false"
status="success">通过 status="success">通过
</a-link> </a-link>
</a-popconfirm> </a-popconfirm>
<RejectTaskModal <RejectTaskModal
:disabled="record.check_status === 1 || record.check_status === -2" :disabled="record.check_status !== 0 && record.check_status !== -1"
:api="Api.admin.refuseTaskChildren" :api="Api.admin.refuseTaskChildren"
:id="record.id" :id="record.id"
@success="fetchData"> @success="fetchData">

View File

@@ -6,6 +6,7 @@ import Api from "../../../../api/index.js";
import TaskPassedReviewModal from "./components/TaskPassedReviewModal.vue"; import TaskPassedReviewModal from "./components/TaskPassedReviewModal.vue";
import RejectTaskModal from "./components/RejectTaskModal.vue"; import RejectTaskModal from "./components/RejectTaskModal.vue";
import TerminateTask from "../../../../components/TerminateTask/TerminateTask.js"; import TerminateTask from "../../../../components/TerminateTask/TerminateTask.js";
import {toPath} from "../../../../utils/index.js";
const columns = [ const columns = [
{ {
@@ -43,15 +44,18 @@ const columns = [
{ {
title: '平台审核状态', title: '平台审核状态',
dataIndex: 'check_status_text', dataIndex: 'check_status_text',
slotName: 'check_status_text',
}, },
{ {
title: '商家任务状态', title: '商家任务状态',
dataIndex: 'status_text', dataIndex: 'status_text',
slotName: 'status_text',
}, },
{ {
title: '操作', title: '操作',
dataIndex: 'action', dataIndex: 'action',
slotName: 'action', slotName: 'action',
fixed: 'right',
width: 250, width: 250,
}, },
]; ];
@@ -144,12 +148,36 @@ const {loading, pagination, initFetchData, fetchData} = useTableQuery({
:loading="loading" :loading="loading"
:columns="columns" :columns="columns"
class="flex-grow"> class="flex-grow">
<template v-slot:check_status_text="{record}">
<a-tag v-if="record.check_status===-2">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===0" color="cyan">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===1" color="green">{{ record.check_status_text }}</a-tag>
<a-tag v-if="record.check_status===-1" color="red">{{ record.check_status_text }}</a-tag>
</template>
<template v-slot:status_text="{record}">
<a-tag v-if="record.status===0 || record.status===2 || record.status===3" color="cyan">
{{ record.status_text }}
</a-tag>
<a-tag v-if="record.status===1 || record.status === -2" color="orangered">{{
record.status_text
}}
</a-tag>
<a-tag v-if="record.status===-1" color="orange">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===4" color="arcoblue">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===-3" color="red">{{ record.status_text }}</a-tag>
<a-tag v-if="record.status===5" color="green">{{ record.status_text }}</a-tag>
</template>
<template v-slot:action="{record}"> <template v-slot:action="{record}">
<div class="flex items-center gap-[20px]"> <div class="flex items-center gap-[20px]">
<a-link :hoverable="false">编辑</a-link> <a-link :hoverable="false" @click="toPath('/home/manage-reward-mission/new-task', {id: record.id})">
<TaskPassedReviewModal :id="record.id" @success="fetchData"></TaskPassedReviewModal> 编辑
<RejectTaskModal :id="record.id" @success="fetchData"></RejectTaskModal> </a-link>
<a-link :hoverable="false" status="danger" class="ml-auto" <TaskPassedReviewModal :disabled="record.check_status===-2 || record.check_status===1"
:id="record.id" @success="fetchData"></TaskPassedReviewModal>
<RejectTaskModal :disabled="record.check_status===-2 || record.check_status===1" :id="record.id"
@success="fetchData"></RejectTaskModal>
<a-link :disabled="record.status_text!==4 && record.status_text!==-2" :hoverable="false"
status="danger" class="ml-auto"
@click="TerminateTask({taskId: record.id})">终止 @click="TerminateTask({taskId: record.id})">终止
</a-link> </a-link>
</div> </div>

View File

@@ -33,6 +33,7 @@ const success = async () => {
is_reply: form.is_reply, is_reply: form.is_reply,
}); });
Message.success(msg); Message.success(msg);
Object.keys(form).forEach(key => form[key] = null);
visible.value = false; visible.value = false;
emits('success'); emits('success');
} }
@@ -58,8 +59,9 @@ const success = async () => {
<a-radio :value="1"></a-radio> <a-radio :value="1"></a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
<a-form-item label="需要回复的评论" v-if="form.is_reply===1"> <a-form-item label="需要回复的评论">
<x-select <x-select
:disabled="form.is_reply===0"
v-model:model-value="form.pid" v-model:model-value="form.pid"
:apiPo="item.id" :apiPo="item.id"
:api="Api.merchant.getChildrenComment"> :api="Api.merchant.getChildrenComment">
@@ -67,6 +69,7 @@ const success = async () => {
</a-form-item> </a-form-item>
<a-form-item label="添加图片"> <a-form-item label="添加图片">
<UploadAvatar <UploadAvatar
:multiple="false"
v-model:files="form.files" v-model:files="form.files"
:api="Api.system.uploadFile2"> :api="Api.system.uploadFile2">
</UploadAvatar> </UploadAvatar>

View File

@@ -22,7 +22,10 @@ const activeKey = ref(0);
const getData = async () => { const getData = async () => {
Api.merchant.getTaskChildrenInfo(task.id).then(({data}) => { Api.merchant.getTaskChildrenInfo(task.id).then(({data}) => {
detail.length = 0; detail.length = 0;
detail.push(...data); detail.push(...data.map(v => ({
...v,
tags: v.tags_arr
})));
console.log('我看看我看看', data); console.log('我看看我看看', data);
}); });
} }
@@ -52,9 +55,10 @@ const refuseTaskChildren = async () => {
const update = async () => { const update = async () => {
const {msg} = await Api.merchant.editChildrenMaterimal({ const {msg} = await Api.merchant.editChildrenMaterimal({
id: task.task_id, id: task.task_id,
data: detail.map(v => ({...v, tags: v.tags_arr.split(",")})), data: detail,
}); });
Message.success(msg); Message.success(msg);
visible.value = false;
emits('success'); emits('success');
} }
</script> </script>

View File

@@ -0,0 +1,159 @@
<script setup>
import {reactive, ref, watch} from "vue";
import Api from "../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
import {findSwappedIds} from "../../../../../utils/index.js";
const visible = ref(false);
const emits = defineEmits(['success']);
const loading = ref(false);
const columns = [
{
title: '模板备注',
key: 'remark',
dataIndex: 'remark',
},
{
title: '任务名称',
key: 'goods_name',
dataIndex: 'goods_name',
},
{
title: '任务渠道',
key: 'platform_name',
dataIndex: 'platform_name',
},
{
title: '包含子任务',
key: 'children_num',
dataIndex: 'children_num',
},
{
title: '子任务单价',
key: 'children_price',
dataIndex: 'children_price',
},
{
title: '发布次数',
key: 'fb_num',
dataIndex: 'fb_num',
},
{
title: '是否评论',
key: 'is_comment',
dataIndex: 'is_comment',
slotName: 'is_comment',
},
{
title: '回填内容',
key: 'content',
dataIndex: 'content',
slotName: 'content',
},
{
title: '保留时间',
key: 'retention_time',
dataIndex: 'retention_time',
slotName: 'retention_time',
},
{
title: '操作',
key: 'action',
dataIndex: 'action',
slotName: 'action',
},
];
const po = reactive({});
const vo = reactive([]);
const gatData = async () => {
loading.value = true;
const {data} = await Api.merchant.getModeList();
vo.length = 0;
vo.push(...data);
loading.value = false;
}
watch(
() => visible.value,
(val) => {
if (val) gatData();
},
{deep: true}
)
const success = async (id) => {
const {msg} = await Api.merchant.TemplateToTask({
id: id
});
Message.success(msg);
emits('success');
visible.value = false;
}
const delTaskTemplate = async (id) => {
const {msg} = await Api.merchant.delTemplate({
id: id
});
Message.success(msg);
await gatData();
}
const handleChange = async (data) => {
const [id, other_id] = findSwappedIds(vo, data);
await Api.merchant.weighTemplate({
id: id,
other_id: other_id
});
await gatData();
}
</script>
<template>
<div @click="visible=true">
<slot></slot>
</div>
<a-modal
:width="1200"
title-align="start"
v-model:visible="visible">
<template v-slot:title>
<div class="flex gap-[20px]">
从模板快速创建
<div class="text-[14px] text-[#4E5969]">模板已创建 {{ vo.length }} / 20</div>
</div>
</template>
<div class="text-[14px] text-[#4E5969] mb-2">选择模板</div>
<a-table
:loading="loading"
@change="handleChange"
:draggable="{type: 'handle',fixed: true}"
class="min-h-[500px]"
:data="vo"
:pagination="false"
:columns="columns">
<template v-slot:is_comment="{record}">
{{ record.is_comment === 1 ? '是' : '否' }}
</template>
<template v-slot:content="{record}">
<div v-for="v in record.content">{{ v }}</div>
</template>
<template v-slot:retention_time="{record}">
{{ record.retention_time }}{{ record.retention_type === 2 ? 'h' : 'm' }}
</template>
<template v-slot:action="{record}">
<div>
<a-link @click="success(record.id)">使用</a-link>
<a-popconfirm @ok="delTaskTemplate(record.id)" content="确定删除吗?">
<a-link status="danger">删除</a-link>
</a-popconfirm>
</div>
</template>
</a-table>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -4,7 +4,9 @@ import Api from "../../../../../api/index.js";
import XSelect from "../../../../../components/XSelect/index.vue"; import XSelect from "../../../../../components/XSelect/index.vue";
import FormTitle from "../../../../../components/FormTitle/index.vue"; import FormTitle from "../../../../../components/FormTitle/index.vue";
import {Message} from "@arco-design/web-vue"; import {Message} from "@arco-design/web-vue";
import {useSystemStore} from "../../../../../pinia/SystemStore/index.js";
const SystemStore = useSystemStore();
const emits = defineEmits(['success']); const emits = defineEmits(['success']);
const form = defineModel('form'); const form = defineModel('form');
const formRef = useTemplateRef('formRef'); const formRef = useTemplateRef('formRef');
@@ -64,7 +66,7 @@ const success = async () => {
:init="true" :init="true"
@change="form.material_id=null" @change="form.material_id=null"
v-model:model-value="form.platform_id" v-model:model-value="form.platform_id"
:api="Api.merchant.getPlatformList"> :api="SystemStore.isRoot ? Api.admin.getPlatform : Api.merchant.getPlatformList">
</XSelect> </XSelect>
</a-form-item> </a-form-item>
<a-form-item label="素材类型" v-if="form.platform_id" field="material_id"> <a-form-item label="素材类型" v-if="form.platform_id" field="material_id">

View File

@@ -5,6 +5,7 @@ import {onMounted, reactive, useTemplateRef} from "vue";
import {v4} from "uuid"; import {v4} from "uuid";
import Api from "../../../../../api/index.js"; import Api from "../../../../../api/index.js";
import {Message} from "@arco-design/web-vue"; import {Message} from "@arco-design/web-vue";
import router from "../../../../../router/index.js";
const settltment_after_list = reactive([]); const settltment_after_list = reactive([]);
const emits = defineEmits(['success', 'prev']); const emits = defineEmits(['success', 'prev']);
@@ -118,7 +119,7 @@ onMounted(() => {
<a-form-item label="结算后" extra="*如有其他要求,可联系管理员添加"> <a-form-item label="结算后" extra="*如有其他要求,可联系管理员添加">
<div class="max-w-[618px]"> <div class="max-w-[618px]">
<a-checkbox-group> <a-checkbox-group v-model:model-value="form.settlement_after">
<a-checkbox v-for="v in settltment_after_list" :value="v.id"> <a-checkbox v-for="v in settltment_after_list" :value="v.id">
{{ v.name }} {{ v.name }}
<a-popover position="rt"> <a-popover position="rt">
@@ -142,7 +143,8 @@ onMounted(() => {
<a-form-item class="mt-[30px]"> <a-form-item class="mt-[30px]">
<a-button class="mr-[24px]" @click="emits('prev')">上一步</a-button> <a-button class="mr-[24px]" @click="emits('prev')">上一步</a-button>
<a-button type="primary" @click="success">下一步</a-button> <a-button v-if="form.status===0 || form.status===-1" type="primary" @click="success">下一步</a-button>
<a-button v-else type="primary" @click="router.back()">返回</a-button>
</a-form-item> </a-form-item>
</a-form> </a-form>
</FormTitle> </FormTitle>

View File

@@ -1,8 +1,10 @@
<script setup> <script setup>
import FormTitle from "../../../../../components/FormTitle/index.vue"; import FormTitle from "../../../../../components/FormTitle/index.vue";
import {toPath} from "../../../../../utils/index.js"; import {toPath} from "../../../../../utils/index.js";
import {useSystemStore} from "../../../../../pinia/SystemStore/index.js";
const emits = defineEmits(['success', 'init']); const emits = defineEmits(['success', 'init']);
const SystemStore = useSystemStore();
const success = () => { const success = () => {
emits('success'); emits('success');
@@ -17,7 +19,7 @@ const success = () => {
<template #extra> <template #extra>
<a-space> <a-space>
<a-button type="secondary" @click="toPath('/home/task-center/reward-mission')">查看任务</a-button> <a-button type="secondary" @click="toPath('/home/task-center/reward-mission')">查看任务</a-button>
<a-button type="primary" @click="emits('init')">再次创建</a-button> <a-button type="primary" @click="emits('init')" v-if="!SystemStore.isRoot">再次创建</a-button>
</a-space> </a-space>
</template> </template>
</a-result> </a-result>

View File

@@ -204,7 +204,7 @@ const passTask = async (id, task_backfill_id) => {
<template v-slot:action2="{record}"> <template v-slot:action2="{record}">
<div class="flex gap-[16px] justify-center items-center"> <div class="flex gap-[16px] justify-center items-center">
<PreviewTaskMaterialModal title="查看素材" :task="record"> <PreviewTaskMaterialModal title="查看素材" :task="record" @success="fetchData">
<a-link :hoverable="false">查看素材</a-link> <a-link :hoverable="false">查看素材</a-link>
</PreviewTaskMaterialModal> </PreviewTaskMaterialModal>
<a-dropdown> <a-dropdown>

View File

@@ -7,12 +7,15 @@ import NewTask4 from "./components/new-task-4.vue";
import NewTask5 from "./components/new-task-5.vue"; import NewTask5 from "./components/new-task-5.vue";
import NewTask6 from "./components/new-task-6.vue"; import NewTask6 from "./components/new-task-6.vue";
import NewTask7 from "./components/new-task-7.vue"; import NewTask7 from "./components/new-task-7.vue";
import {useRoute} from "vue-router"; import {onBeforeRouteLeave, useRoute} from "vue-router";
import Api from "../../../../api/index.js"; import Api from "../../../../api/index.js";
import {deleteObjectFields} from "../../../../utils/index.js"; import {deleteObjectFields} from "../../../../utils/index.js";
import {Message} from "@arco-design/web-vue"; import {Message, Modal} from "@arco-design/web-vue";
import {useSystemStore} from "../../../../pinia/SystemStore/index.js";
import dayjs from "dayjs";
const routes = useRoute(); const routes = useRoute();
const SystemStore = useSystemStore();
const step = ref(1); const step = ref(1);
const form = reactive({ const form = reactive({
id: null, id: null,
@@ -50,6 +53,7 @@ const form = reactive({
back_type: 1, back_type: 1,
settltment_before: [], settltment_before: [],
settlement_after: [],
}); });
const init = () => { const init = () => {
@@ -60,10 +64,12 @@ const init = () => {
const success = async (po) => { const success = async (po) => {
if (step.value === 6) { if (step.value === 6) {
if (form.id) { if (form.id) {
const {msg} = await Api.merchant.editTask(form); const api = SystemStore.isRoot ? Api.admin.editTask : Api.merchant.editTask;
const {msg} = await api(form);
Message.success(msg); Message.success(msg);
} else { } else {
const {data} = await Api.merchant.createTask(form); const {msg} = await Api.merchant.createTask(form);
Message.success(msg);
} }
} }
@@ -74,13 +80,46 @@ const success = async (po) => {
onMounted(() => { onMounted(() => {
const {id} = routes.query; const {id} = routes.query;
if (id) Api.merchant.getTaskInfo(id).then(({data}) => { const api = SystemStore.isRoot ? Api.admin.getTaskDetail : Api.merchant.getTaskInfo
if (id) api(id).then(({data}) => {
Object.assign(form, data); Object.assign(form, data);
form.choose_area = data.choose_area_arr.map(v => Number(v)); form.choose_area = data.choose_area_arr.map(v => Number(v));
form.backfill = data.back; form.backfill = data.back.map(v => ({
...v,
start_time: dayjs(v.start_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
end_time: dayjs(v.end_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
}));
form.settltment_before = data.before.map(v => ({...v, ratio: Number(v.ratio)})); form.settltment_before = data.before.map(v => ({...v, ratio: Number(v.ratio)}));
form.settlement_after = data.settlement_after.map(v => Number(v));
}); });
}) })
onBeforeRouteLeave((to, from, next) => {
if (SystemStore.isRoot) {
next(true);
return;
}
if (step.value === 7) {
next(true);
return;
}
if (form.status === 0) {
Modal.warning({
title: '是否保存当前内容',
hideCancel: false,
onOk: async () => {
const {msg} = await Api.merchant.saveNewTask(form);
Message.success(msg);
next(true);
},
onCancel() {
next(true);
}
});
return;
}
next(true);
})
</script> </script>
<template> <template>

View File

@@ -1,13 +1,14 @@
<script setup> <script setup>
import {computed, reactive} from 'vue'; import {computed, h, reactive} from 'vue';
import Filter from "../../../../components/Filter/index.vue"; import Filter from "../../../../components/Filter/index.vue";
import TooltipTag from "../../../../components/TooltipTag/index.vue"; import TooltipTag from "../../../../components/TooltipTag/index.vue";
import useTableQuery from "../../../../hooks/useTableQuery.js"; import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js"; import Api from "../../../../api/index.js";
import {toPath} from "../../../../utils/index.js"; import {toPath} from "../../../../utils/index.js";
import {Message} from "@arco-design/web-vue"; import {Message, Modal} from "@arco-design/web-vue";
import {usePayTask} from "../../../../hooks/usePayTask.js"; import {usePayTask} from "../../../../hooks/usePayTask.js";
import SaveTemplate from "./components/SaveTemplate.vue"; import SaveTemplate from "./components/SaveTemplate.vue";
import TaskTemplate from "./components/TaskTemplate.vue";
const columns = [ const columns = [
{ {
@@ -115,6 +116,14 @@ const {open: openPayTask} = usePayTask();
const startTask = async (_value, record) => { const startTask = async (_value, record) => {
const {status, id} = record; const {status, id} = record;
if (status === 2) {
Modal.error({
title: '无法查看子任务',
content: '检测到任务尚未审核通过,请等待任务审核通过后,再点击查看子任务',
});
return;
}
const showMessageAndFetch = async (msg) => { const showMessageAndFetch = async (msg) => {
Message.success(msg); Message.success(msg);
await fetchData(); await fetchData();
@@ -136,10 +145,34 @@ const startTask = async (_value, record) => {
}; };
const stopTask = async (id) => { const stopTask = async (id) => {
Modal.error({
width: 460,
title: '确认终止任务',
content: h('div', {}, [
h('div', {}, '终止任务后,后续达人将无法接单,但不影响已经接单的达人'),
h('div', {class: 'text-[#4E5969] text-[14px] mt-[4px]'}, '*请商家及时处理已经被接单的子任务,处理完毕后,剩余任务金额将返款至您钱包')
]),
okText: '确认终止',
okButtonProps: {status: "danger"},
hideCancel: false,
onOk: async () => {
const {msg} = await Api.merchant.stopTask(id); const {msg} = await Api.merchant.stopTask(id);
Message.success(msg); Message.success(msg);
await fetchData(); await fetchData();
} }
})
}
const viewMiniTask = (record) => {
if (record.status === 0 || record.status === 1 || record.status === -1) {
Modal.error({
title: '无法查看子任务',
content: '检测到任务尚未审核通过,请等待任务审核通过后,再点击查看子任务'
});
} else {
toPath('/home/task-center/look-min-task', {id: record.id})
}
}
</script> </script>
<template> <template>
@@ -154,12 +187,14 @@ const stopTask = async (id) => {
</template> </template>
新建任务 新建任务
</a-button> </a-button>
<task-template @success="initFetchData">
<a-button> <a-button>
<template #icon> <template #icon>
<icon-plus/> <icon-plus/>
</template> </template>
从模板快速创建 从模板快速创建
</a-button> </a-button>
</task-template>
</div> </div>
<div class="mt-[20px] flex-grow"> <div class="mt-[20px] flex-grow">
@@ -205,15 +240,14 @@ const stopTask = async (id) => {
编辑 编辑
</a-link> </a-link>
<a-link :hoverable="false" <a-link :hoverable="false"
@click="record.status >= 2 ? toPath('/home/task-center/look-min-task', {id: record.id}) : Message.warning('审核未通过')"> @click="viewMiniTask(record)">
查看子任务 查看子任务
</a-link> </a-link>
<a-popconfirm content="确认终止吗?" @ok="stopTask(record.id)"> <a-link @click="stopTask(record.id)" :disabled="!(record.status === 4 || record.status === -2)"
<a-link :disabled="!(record.status === 4 || record.status === -2)" :hoverable="false" :hoverable="false"
status="danger"> status="danger">
终止 终止
</a-link> </a-link>
</a-popconfirm>
</div> </div>
</template> </template>
<template v-slot:exp="{record}"> <template v-slot:exp="{record}">

View File

@@ -71,6 +71,6 @@ export const useSystemStore = defineStore("SystemStore", () => {
afterHydrate: (val) => { afterHydrate: (val) => {
val.store.installRoute && val.store.installRoute(); val.store.installRoute && val.store.installRoute();
}, },
pick: ['RoutesTemp', 'NOW_ROUTER', 'NOW_ROUTER_QUERY'], pick: ['RoutesTemp', 'NOW_ROUTER', 'NOW_ROUTER_QUERY', 'isRoot'],
} }
}); });

View File

@@ -2,8 +2,7 @@ import router from "../router/index.js";
export const toPath = (path, query = {}) => { export const toPath = (path, query = {}) => {
router.push({ router.push({
path: path, path: path, query: query
query: query
}).then(); }).then();
} }
@@ -40,3 +39,19 @@ export const determineMediaType = (url) => {
return 'Unknown'; return 'Unknown';
} }
} }
export const findSwappedIds = (original, swapped) => {
let id1, id2;
original.forEach((item, index) => {
if (item.id !== swapped[index].id) {
if (!id1) {
id1 = item.id; // 记录第一个不同的 id
} else {
id2 = item.id; // 记录第二个不同的 id
}
}
});
return [id1, id2];
};