This commit is contained in:
2025-05-09 14:57:18 +08:00
parent 1a7886450d
commit 52a270d27f
15 changed files with 657 additions and 69 deletions

View File

@@ -1,129 +0,0 @@
<script setup>
import {reactive, ref, watch} from 'vue';
import Api from "../../../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const emits = defineEmits(['success']);
const {id} = defineProps({
id: {
type: Number,
default: 0,
}
});
const visible = ref(false);
const detail = reactive({});
const activeKey = ref(1);
watch(
() => visible.value,
(val) => {
if (val) Api.admin.getTaskChildrenInfo(id).then(({data}) => {
Object.assign(detail, data);
console.log('我看看我看看', data);
});
},
{deep: true}
)
const passTaskChildren = async () => {
const {code, msg} = await Api.admin.passTaskChildren(id);
if (code === 1) Message.success(msg);
emits('success');
}
const refuseTaskChildren = async () => {
const {code, msg} = await Api.admin.refuseTaskChildren(id);
if (code === 1) Message.success(msg);
emits('success');
}
</script>
<template>
<a-link :hoverable="false" @click="visible=true">预览</a-link>
<a-modal
title-align="start"
title="预览"
v-model:visible="visible">
<a-tabs v-model:active-key="activeKey" type="rounded" v-if="detail.id !== undefined && detail.id !== null">
<a-tab-pane v-for="(item, index) in detail.content" :title="`素材${index+1}`" :key="index">
<a-form
layout="vertical">
<a-form-item label="标题">
<a-input :model-value="item.title"></a-input>
</a-form-item>
<a-form-item label="正文">
<a-textarea
auto-size
:max-length="1000"
show-word-limit
:model-value="item.content">
</a-textarea>
</a-form-item>
<a-form-item label="话题">
<div id="tag-list" class="w-full bg-[var(--color-neutral-2)] p-[4px]">
<a-tag v-for="v in item.tags_arr">#{{ v }}</a-tag>
</div>
</a-form-item>
<a-form-item label="素材">
<div class="flex flex-wrap gap-[16px]">
<a-image
v-for="v in item.materia_arr"
width="60px"
height="60px"
:src="v">
</a-image>
</div>
</a-form-item>
<a-form-item label="评论区内容">
<div class="flex flex-col gap-[8px] w-full">
<div class="w-full flex gap-[10px] items-center" v-for="v in detail.comment">
{{ v.id }}.
<div class="flex-grow bg-[var(--color-neutral-2)] p-[4px] h-[40px] flex items-center">
<div class="text-[#4E5969] text-[14px] mr-[4px]" v-if="v.pid !== 0">
<icon-redo/>
回复{{ v.pid }}
</div>
<a-image
v-if="v.image"
class="mr-[12px]"
width="30px"
height="30px"
:src="v.image">
</a-image>
第三个很好用大家可以在网上搜同款
</div>
</div>
</div>
</a-form-item>
</a-form>
</a-tab-pane>
</a-tabs>
<template #footer>
<div class="flex items-center gap-[8px]">
<a-checkbox-group>
<template v-for="(item, index) in detail.content" :key="item">
<a-checkbox v-show="activeKey === index" :value="item">选中</a-checkbox>
</template>
</a-checkbox-group>
<a-button @click="passTaskChildren" type="primary" class="ml-auto">通过</a-button>
<a-button @click="refuseTaskChildren">拒绝</a-button>
</div>
</template>
</a-modal>
</template>
<style lang="scss" scoped>
#tag-list {
:deep(.arco-tag) {
color: #000;
background-color: #fff;
border: 1px solid rgb(229, 230, 235);
box-sizing: border-box;
}
}
</style>

View File

@@ -3,7 +3,7 @@ import {reactive} from "vue";
import Filter from "../../../../components/Filter/index.vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import PreviewTaskModal from "./components/PreviewTaskModal.vue";
import PreviewTaskModal from "../../../../components/PreviewTaskModal/PreviewTaskModal.vue";
import openTerminateTask from "../../../../components/TerminateTask/TerminateTask.js";
import {Message} from "@arco-design/web-vue";
import RejectTaskModal from "./components/RejectTaskModal.vue";

View File

@@ -0,0 +1,61 @@
<script setup>
import XSelect from "../../../components/XSelect/index.vue";
import {reactive, ref} from "vue";
import UploadAvatar from "../../../components/upload/UploadAvatar.vue";
import Api from "../../../api/index.js";
const {id} = defineProps({
id: {
type: Number,
default: null,
}
});
const form = reactive({
type: 0,
files: []
});
const visible = ref(false);
const success = async () => {
}
</script>
<template>
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
添加评论
</a-button>
<div @click="visible=true" v-else>
<slot></slot>
</div>
<a-modal
title-align="start"
title="添加评论"
v-model:visible="visible"
@ok="success">
<a-form layout="vertical">
<a-form-item label="是否回复之前评论">
<a-radio-group v-model:model-value="form.type">
<a-radio :value="0"></a-radio>
<a-radio :value="1"></a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="需要回复的评论" v-if="form.type===1">
<x-select api=""></x-select>
</a-form-item>
<a-form-item label="添加图片">
<UploadAvatar
v-model:files="form.files"
:api="Api.system.uploadFile2">
</UploadAvatar>
</a-form-item>
<a-form-item label="添加文字">
<a-textarea placeholder="请输入评论内容"></a-textarea>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,91 @@
<script setup>
import {reactive, ref} from "vue";
import XImage from "../../../components/XImage/Index.vue";
import UploadButton from "../../../components/upload/UploadButton.vue";
import Api from "../../../api/index.js";
import {v4} from "uuid";
import MaterialSource from "./MaterialSource.vue";
const MaterialSourceRef = ref();
const visible = ref(false);
const targetList = reactive([]);
const {id} = defineProps({
id: {
type: Number,
default: null,
}
});
const uploadSuccess = (url) => {
targetList.push({
id: v4(),
image: url,
});
}
const success = async () => {
}
</script>
<template>
<!-- 素材库 -->
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
添加素材
</a-button>
<div @click="visible=true" v-else>
<slot></slot>
</div>
<a-modal
@ok="success"
title-align="start"
:width="820"
v-model:visible="visible"
title="添加素材">
<div class="target">
<div class="text-[#1D2129] text-[14px]">已添加5个素材长摁图片可拖动排序</div>
<div class="grid grid-cols-6 mt-[10px] gap-[16px]">
<x-image
@delete="targetList.splice(index,1)"
v-for="(v, index) in targetList"
:key="v.id"
:src="v.image"
:aspect="true"
width="100%"
height="100%">
</x-image>
</div>
</div>
<div class="mt-[20px]">
<div class="text-[#1D2129] text-[14px] mb-[12px]">从本地添加</div>
<UploadButton :multiple="true" :api="Api.system.uploadFile2" @success="uploadSuccess">
<template #upload-button>
<a-button>
<template #icon>
<icon-upload/>
</template>
本地上传
</a-button>
</template>
</UploadButton>
</div>
<div class="mt-[20px]">
<div class="text-[#1D2129] text-[14px] mb-[12px]">从素材库添加</div>
<MaterialSource
ref="MaterialSourceRef"
v-model:select-list="targetList"
:id="id">
</MaterialSource>
</div>
</a-modal>
</template>
<style scoped lang="scss">
.target {
@apply p-[20px] bg-[#F7F8FA];
border: 1px solid #E5E6EB;
}
</style>

View File

@@ -0,0 +1,92 @@
<script setup>
import XImage from "../../../components/XImage/Index.vue";
import {reactive, ref, watch} from "vue";
import Api from "../../../api/index.js";
import UploadButton from "../../../components/upload/UploadButton.vue";
import {Message} from "@arco-design/web-vue";
const {id} = defineProps({
id: {
type: Number,
default: null,
}
});
const visible = ref(false);
const materialList = reactive([]);
const getMaterialList = async () => {
const {data} = await Api.merchant.getMaterialList(id);
materialList.length = 0;
materialList.push(...data);
}
watch(
() => visible.value,
(val) => {
if (val) getMaterialList();
},
{deep: true}
)
const uploadSuccess = async (url) => {
const {msg} = await Api.merchant.addMaterial({
id: id,
image: url
});
Message.success(msg);
await getMaterialList();
}
const deleteImage = async (id) => {
const {msg} = await Api.merchant.delMaterial(id);
Message.success(msg);
await getMaterialList();
}
</script>
<template>
<!-- 素材库 -->
<a-button v-if="!$slots.default" type="primary" @click="visible=true">
<template #icon>
<icon-apps/>
</template>
素材库
</a-button>
<div @click="visible=true" v-else>
<slot></slot>
</div>
<a-modal
title-align="start"
:width="820"
v-model:visible="visible"
title="素材库">
<UploadButton :multiple="true" :api="Api.system.uploadFile2" @success="uploadSuccess">
<template #upload-button>
<a-button>
<template #icon>
<icon-plus/>
</template>
从本地添加到素材
</a-button>
</template>
</UploadButton>
<div class="box">
<x-image
@delete="deleteImage(v.id)"
height="80px"
width="80px"
v-for="v in materialList"
:key="v.id"
:src="v.image">
</x-image>
</div>
</a-modal>
</template>
<style scoped lang="scss">
.box {
@apply p-[20px] mt-[20px] flex gap-[14px] flex-wrap;
border: 1px solid #E5E6EB;
}
</style>

View File

@@ -0,0 +1,104 @@
<script setup>
import {onMounted, reactive, ref} from "vue";
import Api from "../../../api/index.js";
const selectList = defineModel('select-list');
const type = ref(0);
const list = reactive([]);
const {id} = defineProps({
id: {
type: Number,
default: null,
}
});
onMounted(() => {
Api.merchant.getMaterialList(id).then(({data}) => {
list.length = 0;
list.push(...data);
});
});
const select = (v) => {
const flag = selectList.value.findIndex(k => k.id === v.id);
console.log(flag);
if (flag !== -1) { // 删除
selectList.value.splice(flag, 1);
} else { // 新增
selectList.value.push(v);
}
}
const handle = async () => {
if (type === 0) {
}
}
</script>
<template>
<div class="source">
<div>
<a-radio-group v-model:model-value="type">
<a-radio :value="0">添加并从素材库删除</a-radio>
<a-radio :value="1">添加并在素材库保留</a-radio>
</a-radio-group>
</div>
<div class="mt-[12px] grid grid-cols-8 gap-[14px]">
<div
@click="select(v)"
:class="['checkbox-image', selectList.find(k => k.id===v.id)?'select':'']"
v-for="v in list"
:key="v.id">
<a-image
:preview="false"
fit="contain"
:src="v.image"
width="100%"
height="100%">
</a-image>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.source {
@apply p-[20px] bg-[#F7F8FA];
border: 1px solid #E5E6EB;
}
.checkbox-image {
cursor: pointer;
width: 100%;
aspect-ratio: 1/1;
border: 1px solid #E5E6EB;
overflow: hidden;
transition: 300ms;
position: relative;
&::after {
content: '';
position: absolute;
right: 0;
bottom: 0;
display: block;
width: 14px;
height: 14px;
background-color: rgb(var(--arcoblue-6));
border-top-left-radius: 2px;
background-image: url("../../../assets/images/Combined.png");
background-size: 9px 9px;
background-repeat: no-repeat;
background-position: 3px 3px;
transition: 300ms;
opacity: 0;
}
}
.select {
border: 1px solid rgb(var(--arcoblue-6));
&::after {
opacity: 1;
}
}
</style>

View File

@@ -7,11 +7,13 @@ import RefuseModal from "./components/RefuseModal.vue";
import openTerminateTask from "../../../../components/TerminateTask/TerminateTask.js";
import BlackjackExpertModal from "../../components/BlackjackExpertModal.vue";
import {useRoute} from "vue-router";
import {toPath} from "../../../../utils/index.js";
import PreviewTaskModal from "../../../../components/PreviewTaskModal/PreviewTaskModal.vue";
const route = useRoute();
const columns = [
{
title: '子任务号',
title: '子任务号',
dataIndex: 'uid',
},
{
@@ -58,7 +60,7 @@ const columns = [
dataIndex: 'action2',
slotName: 'action2',
align: 'center',
width: 180,
width: 200,
},
];
const state = reactive({
@@ -95,7 +97,7 @@ const {loading, pagination} = useTableQuery({
<a-card class="flex-grow text-[14px]">
<div class="gap-[20px]">
<a-button type="primary">
<a-button type="primary" @click="toPath('/home/task-center/manage-materials', {id: po.id})">
<template #icon>
<icon-apps/>
</template>
@@ -157,7 +159,9 @@ const {loading, pagination} = useTableQuery({
<template v-slot:action2>
<div class="flex gap-[16px] justify-center items-center">
<a-link :hoverable="false">查看素材</a-link>
<PreviewTaskModal>
<a-link :hoverable="false">查看素材</a-link>
</PreviewTaskModal>
<a-dropdown :hide-on-select="false">
<a-link :hoverable="false">
更多

View File

@@ -0,0 +1,115 @@
<script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import {useRoute} from "vue-router";
import MaterialLibrary from "../../components/MaterialLibrary.vue";
import AddMaterial from "../../components/AddMaterial.vue";
import AddComment from "../../components/AddComment.vue";
const route = useRoute();
const columns = reactive([
{
title: '子任务编号',
dataIndex: 'uid',
},
{
title: '标题',
dataIndex: 'title',
slotName: 'title',
},
{
title: '正文',
dataIndex: 'content',
slotName: 'content',
},
{
title: '话题',
dataIndex: 'tags',
slotName: 'tags',
},
{
title: '素材',
dataIndex: 'material',
slotName: 'material',
},
{
title: '评论',
dataIndex: 'pl',
slotName: 'pl',
},
]);
const po = reactive({
id: route.query.id,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination} = useTableQuery({
parameter: po,
api: Api.merchant.getTaskChildrenList,
callback: (data) => {
Object.assign(vo, data);
console.log(vo);
}
});
</script>
<template>
<!-- 批量管理素材 -->
<a-card class="flex-grow text-[14px]">
<div class="flex justify-between">
<MaterialLibrary :id="po.id"></MaterialLibrary>
<a-button type="primary">确认修改</a-button>
</div>
<a-table
:data="vo.rows"
:loading="loading"
:columns="columns"
class="w-full mt-[20px] flex-grow"
@page-change="(e) => pagination.current = e"
:pagination="pagination">
<template v-slot:title="{record}">
<a-input placeholder="请输入标题" v-model:model-value="record.title"></a-input>
</template>
<template v-slot:content="{record}">
<a-input placeholder="请输入正文" v-model:model-value="record.content"></a-input>
</template>
<template v-slot:tags="{record}">
<a-input placeholder="请输入话题" v-model:model-value="record.tags"></a-input>
</template>
<template v-slot:material="{record}">
<add-material :id="po.id">
<div class="add-materials">
<icon-plus/>
<div>添加</div>
</div>
</add-material>
</template>
<template v-slot:pl="{record}">
<AddComment :id="po.id">
<div class="add-materials">
<icon-plus/>
<div>添加</div>
</div>
</AddComment>
</template>
</a-table>
</a-card>
</template>
<style scoped lang="scss">
.add-materials {
@apply size-[40px] bg-[#F2F3F5] text-[#4E5969] duration-500 flex flex-col justify-center items-center cursor-pointer;
border: 1px dashed rgb(229, 230, 235);
&:hover {
@apply text-[#86909C] bg-[#F2F3F5];
border: 1px dashed rgb(229, 230, 235);
}
}
</style>