update
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
### 2025-06-12
|
||||||
|
|
||||||
|
进度:
|
||||||
|
任务领取 -> 任务回填 -> 任务回填中的所有状态 -> 沟通中的所有状态 -> 平台介入
|
||||||
|
|
||||||
### 2025-06-12
|
### 2025-06-12
|
||||||
|
|
||||||
测试文档过到第145条
|
测试文档过到第145条
|
||||||
|
|||||||
@@ -637,6 +637,20 @@ const admin = {
|
|||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getExchangeLogIntervention: async (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/admin/Intervention/getExchangeLog',
|
||||||
|
method: Method.POST,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addIntervention: async (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/admin/Intervention/addIntervention',
|
||||||
|
method: Method.POST,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default admin;
|
export default admin;
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ import {Message} from "@arco-design/web-vue";
|
|||||||
import useTableQuery from "../../hooks/useTableQuery.js";
|
import useTableQuery from "../../hooks/useTableQuery.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {throttle} from "lodash";
|
import {throttle} from "lodash";
|
||||||
|
import {useSystemStore} from "../../pinia/SystemStore/index.js";
|
||||||
|
import UploadSlot from "../upload/UploadSlot.vue";
|
||||||
|
|
||||||
|
const SystemStore = useSystemStore();
|
||||||
|
const emits = defineEmits(['success']);
|
||||||
const ChatBoxRef = useTemplateRef('ChatBox');
|
const ChatBoxRef = useTemplateRef('ChatBox');
|
||||||
const {task} = defineProps({
|
const {task} = defineProps({
|
||||||
task: {
|
task: {
|
||||||
@@ -19,6 +23,7 @@ const po = reactive({
|
|||||||
id: task.id,
|
id: task.id,
|
||||||
});
|
});
|
||||||
const vo = reactive({
|
const vo = reactive({
|
||||||
|
info: null,
|
||||||
rows: [],
|
rows: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
@@ -29,10 +34,11 @@ const form = reactive({
|
|||||||
|
|
||||||
const {loading, pagination, initFetchData, fetchData} = useTableQuery({
|
const {loading, pagination, initFetchData, fetchData} = useTableQuery({
|
||||||
parameter: po,
|
parameter: po,
|
||||||
api: Api.merchant.getExchangeLog,
|
api: SystemStore.isRoot ? Api.admin.getExchangeLogIntervention : Api.merchant.getExchangeLog,
|
||||||
callback: (data) => {
|
callback: (data) => {
|
||||||
if (data.rows.length === 0) {
|
if (data.rows.length === 0) {
|
||||||
} else {
|
} else {
|
||||||
|
vo.info = data.info;
|
||||||
vo.total = data.total;
|
vo.total = data.total;
|
||||||
vo.rows.push(...data.rows);
|
vo.rows.push(...data.rows);
|
||||||
}
|
}
|
||||||
@@ -58,12 +64,19 @@ const handleScroll = ({target}) => {
|
|||||||
}, 500)();
|
}, 500)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addIntervention = async () => {
|
||||||
|
const {msg} = await Api.admin.addIntervention({...form, id: task.id,});
|
||||||
|
Message.success(msg);
|
||||||
|
await fetchData();
|
||||||
|
emits('success')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
@scroll="handleScroll"
|
@scroll="handleScroll"
|
||||||
class="size-full flex flex-col gap-[30px] max-h-[600px] overflow-auto">
|
:class="['size-full flex flex-col gap-[30px] overflow-auto', !SystemStore.isRoot ? 'max-h-[600px]' : 'max-h-[800px]']">
|
||||||
<div :class="['flex gap-[18px]', v.right === 0 ? 'chat-right' : 'chat-left']" v-for="v in vo.rows">
|
<div :class="['flex gap-[18px]', v.right === 0 ? 'chat-right' : 'chat-left']" v-for="v in vo.rows">
|
||||||
<a-image :src="v.people.avatar" class="rounded-[50%] overflow-hidden" width="64px"
|
<a-image :src="v.people.avatar" class="rounded-[50%] overflow-hidden" width="64px"
|
||||||
height="64px"></a-image>
|
height="64px"></a-image>
|
||||||
@@ -88,9 +101,46 @@ const handleScroll = ({target}) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="SystemStore.isRoot && vo.info?.id" class="flex justify-center">
|
||||||
|
<a-card class="w-[528px]" title="达人发起了平台介入" :header-style="{textAlign: 'center'}">
|
||||||
|
<div class="font-bold text-[#1D2129] mb-[6px]">达人申诉理由:</div>
|
||||||
|
<div class="px-[16px] py-[12px] bg-[#F7F8FA]">
|
||||||
|
<div>
|
||||||
|
{{ vo.info.remark }}
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-5 gap-[12px] mt-[4px]">
|
||||||
|
<x-image hideDelete v-for="v in vo.info.image_arr" :src="v"></x-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-[#1D2129] mt-[20px] mb-[6px]">平台处理结果:</div>
|
||||||
|
<div id="ROOT" class="flex flex-col justify-center items-center">
|
||||||
|
<a-textarea v-model:model-value="form.content" class="w-full h-[140px]"
|
||||||
|
placeholder="输入平台介入结果"></a-textarea>
|
||||||
|
<div class="flex flex-wrap gap-[16px] mt-[10px] mr-auto">
|
||||||
|
<x-image
|
||||||
|
v-for="(v, index) in form.images"
|
||||||
|
@delete="form.images.splice(index,1)"
|
||||||
|
:key="index"
|
||||||
|
width="32px"
|
||||||
|
height="32px"
|
||||||
|
:src="v">
|
||||||
|
</x-image>
|
||||||
|
<upload-slot @success="(e) => form.images.push(e)">
|
||||||
|
<div
|
||||||
|
class="size-[32px] bg-[#F2F3F5] flex justify-center items-center flex-col rounded-[8px] cursor-pointer">
|
||||||
|
<icon-plus/>
|
||||||
|
</div>
|
||||||
|
</upload-slot>
|
||||||
|
</div>
|
||||||
|
<a-button type="primary" class="mt-[10px]" @click="addIntervention">平台介入</a-button>
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
v-if="!SystemStore.isRoot"
|
||||||
class="bg-white rounded-[2px] w-[calc(100%-40px)] h-[144px] absolute left-0 bottom-[20px] mx-[20px] py-[8px]">
|
class="bg-white rounded-[2px] w-[calc(100%-40px)] h-[144px] absolute left-0 bottom-[20px] mx-[20px] py-[8px]">
|
||||||
<a-textarea
|
<a-textarea
|
||||||
v-model:model-value="form.content"
|
v-model:model-value="form.content"
|
||||||
@@ -131,6 +181,14 @@ const handleScroll = ({target}) => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
#ROOT {
|
||||||
|
textarea {
|
||||||
|
background-color: #F7F8FA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.chat-right {
|
.chat-right {
|
||||||
@apply flex-row-reverse;
|
@apply flex-row-reverse;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const {task} = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
const visible = defineModel('visible');
|
const visible = defineModel('visible');
|
||||||
|
const emits = defineEmits(['success']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -25,7 +26,7 @@ const visible = defineModel('visible');
|
|||||||
</a-alert>
|
</a-alert>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="p-[20px] bg-[#F2F3F5] flex-grow min-h-[800px] relative">
|
<div class="p-[20px] bg-[#F2F3F5] flex-grow min-h-[800px] relative">
|
||||||
<Information :task="task" v-if="visible"></Information>
|
<Information :task="task" v-if="visible" @success="emits('success')"></Information>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-[280px] h-auto flex flex-col bg-[#F2F3F5] gap-[20px]" v-if="task">
|
<div class="w-[280px] h-auto flex flex-col bg-[#F2F3F5] gap-[20px]" v-if="task">
|
||||||
<div class="bg-white p-[20px]">
|
<div class="bg-white p-[20px]">
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import Api from "../../api/index.js";
|
import Api from "../../api/index.js";
|
||||||
|
import {useSystemStore} from "../../pinia/SystemStore/index.js";
|
||||||
|
|
||||||
const emits = defineEmits(['success']);
|
const emits = defineEmits(['success']);
|
||||||
|
const SystemStore = useSystemStore();
|
||||||
|
|
||||||
const upload = (e) => {
|
const upload = (e) => {
|
||||||
const file = e.target.files[0];
|
const file = e.target.files[0];
|
||||||
Api.system.uploadFile2(file).then(({data}) => {
|
const api = SystemStore.isRoot ? Api.system.uploadFile : Api.system.uploadFile2;
|
||||||
|
api(file).then(({data}) => {
|
||||||
emits('success', data);
|
emits('success', data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,51 +4,54 @@ import useTableQuery from "../../../../hooks/useTableQuery.js";
|
|||||||
import Api from "../../../../api/index.js";
|
import Api from "../../../../api/index.js";
|
||||||
import Filter from "../../../../components/Filter/index.vue";
|
import Filter from "../../../../components/Filter/index.vue";
|
||||||
import XSelect from "../../../../components/XSelect/index.vue";
|
import XSelect from "../../../../components/XSelect/index.vue";
|
||||||
|
import Chat from "../../../../components/Chat/index.vue";
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '沟通事件ID',
|
title: '沟通事件ID',
|
||||||
dataIndex: 'key',
|
dataIndex: 'code',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '商家ID',
|
title: '商家ID',
|
||||||
dataIndex: 'key',
|
dataIndex: 'b_uid',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '任务编号',
|
title: '任务编号',
|
||||||
dataIndex: 'key',
|
dataIndex: 't_uid',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '子任务编号',
|
title: '子任务编号',
|
||||||
dataIndex: 'key',
|
dataIndex: 'm_code',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '申诉状态',
|
title: '申诉状态',
|
||||||
dataIndex: 'key',
|
dataIndex: 'status',
|
||||||
|
slotName: 'status',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '结算状态',
|
title: '结算状态',
|
||||||
dataIndex: 'key',
|
dataIndex: 'settlement',
|
||||||
|
slotName: 'settlement',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '达人ID',
|
title: '达人ID',
|
||||||
dataIndex: 'key',
|
dataIndex: 'uuid',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '达人账号',
|
title: '达人账号',
|
||||||
dataIndex: 'key',
|
dataIndex: 'account',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '领取时间',
|
title: '领取时间',
|
||||||
dataIndex: 'key',
|
dataIndex: 'receive_time',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '扣除',
|
title: '扣除',
|
||||||
dataIndex: 'key',
|
dataIndex: 'ratio',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '金额',
|
title: '金额',
|
||||||
dataIndex: 'key',
|
dataIndex: 'money',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '原因',
|
title: '原因',
|
||||||
@@ -127,7 +130,10 @@ const FilterConfig = [
|
|||||||
span: 6,
|
span: 6,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const state = reactive({
|
||||||
|
showChat: false,
|
||||||
|
task: null,
|
||||||
|
})
|
||||||
const po = reactive({
|
const po = reactive({
|
||||||
pass: 1,
|
pass: 1,
|
||||||
money_type: null,
|
money_type: null,
|
||||||
@@ -141,7 +147,7 @@ const vo = reactive({
|
|||||||
rows: [],
|
rows: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
});
|
});
|
||||||
const {loading, pagination, initFetchData} = useTableQuery({
|
const {loading, pagination, initFetchData, fetchData} = useTableQuery({
|
||||||
parameter: po,
|
parameter: po,
|
||||||
api: Api.admin.getInterventionList,
|
api: Api.admin.getInterventionList,
|
||||||
callback: (data) => {
|
callback: (data) => {
|
||||||
@@ -183,9 +189,14 @@ const {loading, pagination, initFetchData} = useTableQuery({
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
class="flex-grow">
|
class="flex-grow">
|
||||||
<template v-slot:action>
|
<template v-slot:action="{record}">
|
||||||
<div class="flex gap-[16px]">
|
<div class="flex gap-[16px]">
|
||||||
<a-link :hoverable="false">沟通记录</a-link>
|
<a-link :hoverable="false" @click="async () => {
|
||||||
|
const {data} = await Api.admin.getTaskChildrenInfo(record.tc_id);
|
||||||
|
state.showChat = true;
|
||||||
|
state.task = data;
|
||||||
|
}">沟通记录
|
||||||
|
</a-link>
|
||||||
<a-link :hoverable="false">查看回填</a-link>
|
<a-link :hoverable="false">查看回填</a-link>
|
||||||
<a-link :hoverable="false" status="success">确认结算</a-link>
|
<a-link :hoverable="false" status="success">确认结算</a-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -193,10 +204,56 @@ const {loading, pagination, initFetchData} = useTableQuery({
|
|||||||
<template v-slot:why>
|
<template v-slot:why>
|
||||||
<a-link :hoverable="false">原因</a-link>
|
<a-link :hoverable="false">原因</a-link>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-slot:status="{record}">
|
||||||
|
<a-tag color="green" v-if="record.status===1">已处理</a-tag>
|
||||||
|
<a-tag color="cyan" v-if="record.status===0">未处理</a-tag>
|
||||||
|
</template>
|
||||||
|
<template v-slot:settlement="{record}">
|
||||||
|
<div v-if="record.status===2" class="status success">{{ record.settlement_text }}</div>
|
||||||
|
<div v-if="record.status===1" class="status warning">{{ record.settlement_text }}</div>
|
||||||
|
<div v-if="record.status===-1" class="status danger">{{ record.settlement_text }}</div>
|
||||||
|
<div v-if="record.status===0" class="status primary">{{ record.settlement_text }}</div>
|
||||||
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
|
<Chat
|
||||||
|
:task="state.task"
|
||||||
|
@success="fetchData"
|
||||||
|
v-model:visible="state.showChat">
|
||||||
|
</Chat>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
|
.status {
|
||||||
|
@apply flex whitespace-nowrap items-center gap-[6px];
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
@apply block size-[6px] rounded-[50%];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
&::before {
|
||||||
|
@apply bg-[rgb(var(--green-6))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger {
|
||||||
|
&::before {
|
||||||
|
@apply bg-[rgb(var(--red-6))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
&::before {
|
||||||
|
@apply bg-[rgb(var(--orange-6))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
&::before {
|
||||||
|
@apply bg-[rgb(var(--arcoblue-6))];
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user