feat: 内容审核写手端-替换接口,删除无用代码组件逻辑

This commit is contained in:
rd
2025-08-11 18:28:38 +08:00
parent 77cf169607
commit 7a6e696fc3
27 changed files with 151 additions and 675 deletions

View File

@ -9,21 +9,17 @@ const getWriterCode = () => {
return route.params.writerCode as string;
};
// 内容稿件-批量添加(写手)
export const postWorksBatchWriter = (params: any) => {
export const postWorksBatchWriter = (params: {}) => {
return Http.post('/v1/writer/works/batch', params, {
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件-分页(写手)
export const getWorksPageWriter = (params: any) => {
return Http.get(
'/v1/writer/works',
{ params },
{
headers: { 'writer-code': getWriterCode() },
},
);
export const getWorksPageWriter = (params: {}) => {
return Http.get('/v1/writer/works', params, {
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件-详情(写手)
@ -57,17 +53,13 @@ export const getTemplateUrlWriter = () => {
// 内容稿件审核-分页(写手)
export const getWorkAuditsPageWriter = (params: any) => {
return Http.get(
'/v1/writer/work-audits',
{ params },
{
headers: { 'writer-code': getWriterCode() },
},
);
return Http.get('/v1/writer/work-audits', params, {
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件审核-详情(写手)
export const getWorkAuditDetailWriter = (id: string) => {
export const getWorkAuditsDetailWriter = (id: string) => {
return Http.get(`/v1/writer/work-audits/${id}`, {
headers: { 'writer-code': getWriterCode() },
});
@ -75,13 +67,9 @@ export const getWorkAuditDetailWriter = (id: string) => {
// 内容稿件审核-多个详情(写手)
export const getWorkAuditsBatchDetailWriter = (params: any) => {
return Http.get(
'/v1/writer/work-audits/list',
{ params },
{
headers: { 'writer-code': getWriterCode() },
},
);
return Http.get('/v1/writer/work-audits/list', params, {
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件-审核(写手)
@ -128,3 +116,18 @@ export const getWorkAuditsAiReviewResultWriter = (id: string, ticket: string) =>
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件-通过链接获取稿件
export const postWorksByLinkWriter = (params = {}) => {
return Http.post('/v1/writer/works/by-link', params, {
headers: { 'writer-code': getWriterCode() },
});
};
// 内容稿件-通过文档获取稿件
export const postWorksByFileWriter = (params = {}, config = {}) => {
return Http.post('/v1/writer/works/by-file', params, {
...config,
headers: { 'writer-code': getWriterCode() },
});
};

View File

@ -1,5 +1,14 @@
import { postWorkAuditsAiReview, getWorkAuditsAiReviewResult } from '@/api/all/generationWorkshop';
export default function useGetAiReviewResult({ cardInfo, updateAiReview }: { cardInfo: any; updateAiReview: (ai_review: any) => void }) {
export default function useGetAiReviewResult({
cardInfo,
updateAiReview,
startAiReviewFn,
getAiReviewResultFn,
}: {
cardInfo: any;
updateAiReview: (ai_review: any) => void;
startAiReviewFn: (params: { id: string; platform: string; content: string }) => Promise<any>;
getAiReviewResultFn: (id: string, ticket: string) => Promise<any>;
}) {
const statusPollingTimer = ref<number | null>(null);
const ticket = ref('');
const checkLoading = ref(false);
@ -8,7 +17,7 @@ export default function useGetAiReviewResult({ cardInfo, updateAiReview }: { car
const handleStartCheck = async () => {
checkLoading.value = true;
const { id, platform, content } = cardInfo.value;
const { code, data } = await postWorkAuditsAiReview({ id, platform, content });
const { code, data } = await startAiReviewFn({ id, platform, content });
if (code === 200) {
ticket.value = data.ticket;
startStatusPolling();
@ -23,7 +32,7 @@ export default function useGetAiReviewResult({ cardInfo, updateAiReview }: { car
const startStatusPolling = () => {
clearStatusPollingTimer();
statusPollingTimer.value = setInterval(async () => {
const { code, data } = await getWorkAuditsAiReviewResult(cardInfo.value.id, ticket.value);
const { code, data } = await getAiReviewResultFn(cardInfo.value.id, ticket.value);
if (code === 200 && data.status === 1) {
checkResult.value = data.ai_review;
updateAiReview?.(data.ai_review);

View File

@ -27,4 +27,5 @@ export const MENU_GROUP_IDS = {
MANAGEMENT_ID: 3, // 管理中心
PROPERTY_ID: 4, // 资产营销平台
WORK_BENCH_ID: 5, // 工作台
WRITER_CREATIVE_GENERATION_WORKSHOP_ID: 6, // 内容稿件-写手侧
};

View File

@ -14,7 +14,7 @@ const COMPONENTS: AppRouteRecordRaw[] = [
requiresAuth: false,
requireLogin: false,
roles: ['*'],
id: MENU_GROUP_IDS.CREATIVE_GENERATION_WORKSHOP_ID,
id: MENU_GROUP_IDS.WRITER_CREATIVE_GENERATION_WORKSHOP_ID,
},
children: [
{

View File

@ -55,7 +55,15 @@ export const MENU_LIST = [
{
name: '内容稿件',
routeName: 'ManuscriptList',
includeRouteNames: ['ManuscriptList', 'ManuscriptCheck', 'ManuscriptEdit', 'ManuscriptDetail'],
includeRouteNames: [
'ManuscriptList',
'ManuscriptUpload',
'ManuscriptEdit',
'ManuscriptDetail',
'ManuscriptCheckList',
'ManuscriptCheckListDetail',
'ManuscriptCheck',
],
},
],
},

View File

@ -20,7 +20,7 @@
<script setup>
import { ref } from 'vue';
import { deleteWork } from '@/api/all/generationWorkshop';
import { deleteWorkWriter } from '@/api/all/generationWorkshop-writer.ts';
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
const update = inject('update');
@ -46,7 +46,7 @@ const open = (record) => {
};
async function onDelete() {
const { code } = await deleteWork(projectId.value);
const { code } = await deleteWorkWriter(projectId.value);
if (code === 200) {
AMessage.success('删除成功');
update()

View File

@ -54,7 +54,9 @@
<img v-else width="24" height="24" :src="PLATFORMS.find((item) => item.value === record.platform)?.icon" />
</template>
<template v-else-if="column.dataIndex === 'compliance_level'" #cell="{ record }">
<span class="cts num !color-#6D4CFE">{{ record.ai_review?.compliance_level ? `${record.ai_review?.compliance_level}%` : '-' }}</span>
<span class="cts num !color-#6D4CFE">{{
record.ai_review?.compliance_level ? `${record.ai_review?.compliance_level}%` : '-'
}}</span>
</template>
<template v-else-if="column.dataIndex === 'title'" #cell="{ record }">
<TextOverTips :context="record.title" :line="3" class="title" @click="onDetail(record)" />
@ -93,14 +95,11 @@
<template v-else-if="column.dataIndex === 'operation'" #cell="{ record }">
<div class="flex items-center">
<img class="mr-8px cursor-pointer" :src="icon1" width="14" height="14" @click="onDelete(record)" />
<a-button type="outline" size="mini" @click="onShare(record)" v-if="audit_status === AuditStatus.Passed"
>分享</a-button
>
<a-button
type="outline"
size="mini"
@click="onCheck(record)"
v-else-if="audit_status === AuditStatus.Pending"
v-if="audit_status === AuditStatus.Pending"
>审核</a-button
>
<a-button type="outline" size="mini" @click="onScan(record)" v-else>查看</a-button>
@ -113,14 +112,13 @@
</template>
</a-table>
<ShareModal ref="shareModalRef" />
</template>
<script setup>
import { ref } from 'vue';
import { formatTableField, exactFormatTime } from '@/utils/tools';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants';
import { patchWorkAuditsAudit } from '@/api/all/generationWorkshop';
import { patchWorkAuditsAuditWriter } from '@/api/all/generationWorkshop-writer.ts';
import {
AuditStatus,
CUSTOMER_OPINION,
@ -129,7 +127,6 @@ import {
import { slsWithCatch } from '@/utils/stroage.ts';
import TextOverTips from '@/components/text-over-tips';
import ShareModal from '@/views/creative-generation-workshop/manuscript/components/share-manuscript-modal/share-modal.vue';
import icon1 from '@/assets/img/media-account/icon-delete.png';
import icon2 from '@/assets/img/creative-generation-workshop/icon-photo.png';
@ -161,8 +158,8 @@ const props = defineProps({
},
});
const route = useRoute();
const tableRef = ref(null);
const shareModalRef = ref(null);
const handleSorterChange = (column, order) => {
emits('sorterChange', column, order === 'ascend' ? 'asc' : 'desc');
@ -170,20 +167,19 @@ const handleSorterChange = (column, order) => {
const onDelete = (item) => {
emits('delete', item);
};
const onShare = (item) => {
shareModalRef.value?.open([item.id]);
};
const onCheck = (item) => {
patchWorkAuditsAudit(item.id);
slsWithCatch('manuscriptCheckIds', [item.id]);
router.push({ name: 'ManuscriptCheck' });
patchWorkAuditsAuditWriter(item.id);
slsWithCatch('writerManuscriptCheckIds', [item.id]);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
};
const onScan = (item) => {
slsWithCatch('manuscriptCheckIds', [item.id]);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', [item.id]);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
};
const onDetail = (item) => {
router.push(`/manuscript/check-list/detail/${item.id}?source=check&audit_status=${props.audit_status}`);
router.push(
`/writer/manuscript/check-list/detail/${item.id}/${route.params.writerCode}?source=check&audit_status=${props.audit_status}`,
);
};
const getCustomerOpinionInfo = (value) => {
return CUSTOMER_OPINION.find((item) => item.value === value);

View File

@ -68,7 +68,6 @@
</div>
<DeleteManuscriptModal ref="deleteManuscriptModalRef" />
<ShareManuscriptModal ref="shareManuscriptModalRef" />
</div>
</template>
<script lang="jsx" setup>
@ -77,9 +76,8 @@ import { Button, Message as AMessage } from '@arco-design/web-vue';
import FilterBlock from './components/filter-block';
import ManuscriptCheckTable from './components/manuscript-check-table';
import DeleteManuscriptModal from './components/manuscript-check-table/delete-manuscript-modal.vue';
import ShareManuscriptModal from '@/views/creative-generation-workshop/manuscript/components/share-manuscript-modal';
import { getWorkAuditsPage, patchWorkAuditsBatchAudit } from '@/api/all/generationWorkshop.ts';
import { getWorkAuditsPageWriter, patchWorkAuditsBatchAuditWriter } from '@/api/all/generationWorkshop-writer.ts';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { slsWithCatch } from '@/utils/stroage.ts';
// import { getProjects } from '@/api/all/propertyMarketing';
@ -113,6 +111,7 @@ const {
},
});
const router = useRouter();
const route = useRoute();
const tableColumns = ref([]);
const query = ref(cloneDeep(INITIAL_QUERY));
@ -122,7 +121,7 @@ const shareManuscriptModalRef = ref(null);
const getData = async () => {
const { page, page_size } = pageInfo.value;
const { code, data } = await getWorkAuditsPage({
const { code, data } = await getWorkAuditsPageWriter({
...query.value,
page,
page_size,
@ -155,10 +154,10 @@ const handleBatchCheck = () => {
return;
}
patchWorkAuditsBatchAudit({ ids: selectedRowKeys.value });
patchWorkAuditsBatchAuditWriter({ ids: selectedRowKeys.value });
slsWithCatch('manuscriptCheckIds', selectedRowKeys.value);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', selectedRowKeys.value);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
};
const handleBatchView = () => {
if (!selectedRows.value.length) {
@ -166,8 +165,8 @@ const handleBatchView = () => {
return;
}
slsWithCatch('manuscriptCheckIds', selectedRowKeys.value);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', selectedRowKeys.value);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
};
const handleTabClick = (key) => {

View File

@ -29,6 +29,7 @@ import { useRouter } from 'vue-router';
const emit = defineEmits(['selectCard']);
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const action = ref('');
const cardInfo = ref(null);
@ -40,7 +41,7 @@ const onClose = () => {
};
const onConfirm = () => {
if (action.value === 'exit') {
router.push({ name: 'ManuscriptCheckList' });
router.push({ path: `/writer/manuscript/check-list/${route.params.writerCode}` });
} else {
emit('selectCard', cardInfo.value);
}

View File

@ -24,12 +24,13 @@ import { ref } from 'vue';
import icon1 from '@/assets/img/media-account/icon-feedback-success.png';
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const workIds = ref([]);
const onClose = () => {
if (workIds.value.length === 1) {
router.push({ name: 'ManuscriptCheckList' });
router.push({ path: `/writer/manuscript/check-list/${route.params.writerCode}` });
}
workIds.value = [];
visible.value = false;

View File

@ -9,14 +9,13 @@ import CheckListDrawer from './components/check-list-drawer';
import { slsWithCatch, rlsWithCatch, glsWithCatch } from '@/utils/stroage.ts';
import useGetAiReviewResult from '@/hooks/useGetAiReviewResult.ts';
import {
patchWorkAuditsAudit,
patchWorkAuditsBatchAudit,
putWorkAuditsUpdate,
putWorkAuditsAuditPass,
getWorkAuditsDetail,
getWorkAuditsBatchDetail,
postWorkAuditsAiReview,
} from '@/api/all/generationWorkshop.ts';
getWorkAuditsBatchDetailWriter,
putWorkAuditsUpdateWriter,
postWorkAuditsAiReviewWriter,
getWorkAuditsAiReviewResultWriter,
putWorkAuditsAuditPassWriter,
postWorkAuditsAiReviewWriter,
} from '@/api/all/generationWorkshop-writer.ts';
export default {
setup(props, { emit, expose }) {
@ -38,13 +37,15 @@ export default {
const { handleStartCheck, handleAgainCheck, ticket, checkLoading } = useGetAiReviewResult({
cardInfo: selectCardInfo,
startAiReviewFn: postWorkAuditsAiReviewWriter,
getAiReviewResultFn: getWorkAuditsAiReviewResultWriter,
updateAiReview(ai_review) {
selectCardInfo.value.ai_review = ai_review;
},
});
const onBack = () => {
router.push({ name: 'ManuscriptCheckList' });
router.push({ path: `/writer/manuscript/check-list/${route.params.writerCode}` });
};
const onChangeCard = (item) => {
@ -78,7 +79,7 @@ export default {
};
const getWorkAudits = async () => {
const { code, data } = await getWorkAuditsBatchDetail({ ids: workIds.value });
const { code, data } = await getWorkAuditsBatchDetailWriter({ ids: workIds.value });
if (code === 200) {
const _data = (data ?? []).map((item) => ({
...item,
@ -124,7 +125,7 @@ export default {
}
contentCardRef.value?.validate().then(async () => {
const { code, data } = await putWorkAuditsUpdate(selectCardInfo.value);
const { code, data } = await putWorkAuditsUpdateWriter(selectCardInfo.value);
if (code === 200) {
isSaved.value = true;
AMessage.success('当前内容稿件已保存');
@ -139,7 +140,7 @@ export default {
workIds.value = workIds.value.filter((v) => v != _id);
dataSource.value = dataSource.value.filter((v) => v.id != _id);
slsWithCatch('manuscriptCheckIds', workIds.value.join(','));
slsWithCatch('writerManuscriptCheckIds', workIds.value.join(','));
onChangeCard(dataSource.value.length ? dataSource.value[0] : {});
}
};
@ -147,7 +148,7 @@ export default {
contentCardRef.value?.validate().then(async () => {
try {
submitLoading.value = true;
const { code, data } = await putWorkAuditsAuditPass(selectCardInfo.value);
const { code, data } = await putWorkAuditsAuditPassWriter(selectCardInfo.value);
if (code === 200) {
onCheckSuccess();
}
@ -179,11 +180,11 @@ export default {
);
};
onMounted(() => {
workIds.value = glsWithCatch('manuscriptCheckIds')?.split(',') ?? [];
workIds.value = glsWithCatch('writerManuscriptCheckIds')?.split(',') ?? [];
getWorkAudits();
});
onUnmounted(() => {
rlsWithCatch('manuscriptCheckIds');
rlsWithCatch('writerManuscriptCheckIds');
});
return () => (

View File

@ -1,40 +0,0 @@
export const INITIAL_FORM = {
audit_status: '',
sort_column: undefined,
sort_order: undefined,
};
export const TABLE_COLUMNS = [
{
title: '序号',
dataIndex: 'uid',
width: 120,
fixed: 'left',
sortable: {
sortDirections: ['ascend', 'descend'],
},
},
{
title: '内容稿件标题',
dataIndex: 'title',
width: 220,
},
{
title: '审核状态',
dataIndex: 'audit_status',
width: 120,
},
{
title: '稿件类型',
dataIndex: 'type',
width: 120,
},
{
title: '最后修改时间',
dataIndex: 'last_modified_at',
width: 160,
sortable: {
sortDirections: ['ascend', 'descend'],
},
},
];

View File

@ -1,293 +0,0 @@
<script lang="jsx">
import {
Input,
Table,
Modal,
TableColumn,
Checkbox,
Pagination,
Button,
Tooltip,
Notification,
} from '@arco-design/web-vue';
import CommonSelect from '@/components/common-select';
import TextOverTips from '@/components/text-over-tips';
import ShareModal from '@/views/creative-generation-workshop/manuscript/components/share-manuscript-modal/share-modal';
import { INITIAL_FORM, TABLE_COLUMNS } from './constants';
import { formatTableField, exactFormatTime } from '@/utils/tools';
import { CHECK_STATUS, EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { getWorksPage, getWriterLinksGenerate } from '@/api/all/generationWorkshop.ts';
import icon2 from '@/assets/img/creative-generation-workshop/icon-photo.png';
import icon3 from '@/assets/img/creative-generation-workshop/icon-video.png';
export default {
setup(props, { emit, expose }) {
const {
selectedRowKeys,
selectedRows,
dataSource,
pageInfo,
onPageChange,
onPageSizeChange,
rowSelection,
handleSelect,
handleSelectAll,
DEFAULT_PAGE_INFO,
} = useTableSelectionWithPagination({
onPageChange: () => {
getData();
},
onPageSizeChange: () => {
getData();
},
});
const visible = ref(false);
const query = ref(cloneDeep(INITIAL_FORM));
const tableRef = ref(null);
const shareModalRef = ref(null);
const reset = () => {
query.value = cloneDeep(INITIAL_FORM);
pageInfo.value = cloneDeep(DEFAULT_PAGE_INFO);
selectedRowKeys.value = [];
selectedRows.value = [];
dataSource.value = [];
};
const getData = async () => {
const { page, page_size } = pageInfo.value;
const { code, data } = await getWorksPage({
...query.value,
page,
page_size,
});
if (code === 200) {
dataSource.value = data?.data ?? [];
pageInfo.value.total = data.total;
}
};
const handleSearch = (value) => {
query.value.audit_status = value;
reload();
};
const reload = () => {
pageInfo.value.page = 1;
getData();
};
const open = () => {
getData();
visible.value = true;
};
const onClose = () => {
visible.value = false;
reset();
};
const renderColumn = () => {
return TABLE_COLUMNS.map((column) => (
<TableColumn
key={column.dataIndex}
data-index={column.dataIndex}
fixed={column.fixed}
width={column.width}
min-width={column.minWidth}
sortable={column.sortable}
align={column.align}
ellipsis
tooltip
v-slots={{
title: () => (
<div class="flex items-center">
<span class="cts mr-4px">{column.title}</span>
{column.tooltip && (
<Tooltip content={column.tooltip} position="top">
<IconQuestionCircle class="tooltip-icon color-#737478" size={16} />
</Tooltip>
)}
</div>
),
cell: ({ record }) => renderCell(record),
}}
/>
));
};
const onShare = () => {
shareModalRef.value?.open(selectedRowKeys.value);
};
const handleSorterChange = (column, order) => {
query.value.sort_column = column;
query.value.sort_order = order === 'ascend' ? 'asc' : 'desc';
reload();
};
const getStatusInfo = (audit_status) => {
return CHECK_STATUS.find((v) => v.id === audit_status) ?? {};
};
expose({
open,
});
return () => (
<>
<Modal
v-model:visible={visible.value}
title="分享内容稿件"
width="920px"
onClose={onClose}
unmount-on-close
modal-class="share-manuscript-modal"
v-slots={{
footer: () => (
<div class="flex justify-between w-full items-center">
<p class="cts color-#737478">
已选择 <span class="cts color-#211F24 bold">{selectedRows.value.length}</span>
</p>
<div class="flex items-center">
<Button size="medium" onClick={onClose}>
取消
</Button>
<Button
type="primary"
class="ml-16px"
size="medium"
onClick={onShare}
disabled={!selectedRows.value.length}
>
分享
</Button>
</div>
</div>
),
}}
>
<div class="flex flex-col h-100%">
<div class="filter-row-item mb-16px">
<span class="cts text-#211f24 !text-14px mr-12px">审核状态</span>
<CommonSelect
placeholder="全部"
options={CHECK_STATUS}
v-model={query.value.audit_status}
class="!w-200px"
multiple={false}
onChange={handleSearch}
/>
</div>
<Table
ref={tableRef}
data={dataSource.value}
row-key="id"
column-resizable
row-selection={rowSelection.value}
selected-keys={selectedRowKeys.value}
pagination={false}
scroll={{ x: '100%', y: '100%' }}
class="overflow-hidden"
bordered
onSorterChange={handleSorterChange}
onSelect={handleSelect}
onSelectAll={handleSelectAll}
v-slots={{
empty: () => <NoData />,
columns: () => (
<>
{TABLE_COLUMNS.map((column) => (
<TableColumn
key={column.dataIndex}
data-index={column.dataIndex}
fixed={column.fixed}
width={column.width}
min-width={column.minWidth}
sortable={column.sortable}
align={column.align}
ellipsis
tooltip
v-slots={{
title: () => (
<div class="flex items-center">
<span class="cts mr-4px">{column.title}</span>
{column.tooltip && (
<Tooltip content={column.tooltip} position="top">
<IconQuestionCircle class="tooltip-icon color-#737478" size={16} />
</Tooltip>
)}
</div>
),
cell: ({ record }) => {
if (column.dataIndex === 'audit_status') {
return (
<div
class="flex items-center w-fit h-24px px-8px rounded-2px"
style={{ backgroundColor: getStatusInfo(record.audit_status).backgroundColor }}
>
<span class="cts s1" style={{ color: getStatusInfo(record.audit_status).color }}>
{getStatusInfo(record.audit_status).name}
</span>
</div>
);
} else if (column.dataIndex === 'title') {
return <TextOverTips context={record.title} />;
} else if (column.dataIndex === 'type') {
return (
<div class="flex items-center">
<img
src={record.type === EnumManuscriptType.Image ? icon2 : icon3}
width="16"
height="16"
class="mr-4px"
/>
<span
class="cts"
class={
record.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'
}
>
{record.type === EnumManuscriptType.Image ? '图文' : '视频'}
</span>
</div>
);
} else if (column.dataIndex === 'last_modified_at') {
return exactFormatTime(
record.last_modified_at,
'YYYY-MM-DD HH:mm:ss',
'YYYY-MM-DD HH:mm:ss',
);
} else {
return formatTableField(column, record, true);
}
},
}}
/>
))}
</>
),
}}
/>
{pageInfo.value.total > 0 && (
<div class="flex justify-end mt-16px">
<Pagination
total={pageInfo.value.total}
size="mini"
show-total
show-jumper
show-page-size
current={pageInfo.value.page}
page-size={pageInfo.value.page_size}
onChange={onPageChange}
onPageSizeChange={onPageSizeChange}
/>
</div>
)}
</div>
</Modal>
<ShareModal ref={shareModalRef} onClose={onClose} />
</>
);
},
};
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -1,137 +0,0 @@
<script lang="jsx">
import { Modal, Form, FormItem, Input, Button, Message as AMessage } from '@arco-design/web-vue';
import CommonSelect from '@/components/common-select';
import { useClipboard } from '@vueuse/core';
import { postShareLinksGenerate } from '@/api/all/generationWorkshop';
import { generateFullUrl } from '@/utils/tools';
const INITIAL_FORM = {
work_ids: [],
days: 1,
receiver: '',
};
const OPTIONS = [
{
id: 1,
name: '1天',
},
{
id: 2,
name: '3天',
},
{
id: 3,
name: '7天',
},
{
id: 4,
name: '15天',
},
{
id: 5,
name: '30天',
},
{
id: 6,
name: '60天',
},
];
export default {
emits: ['close'],
setup(props, { emit, expose }) {
const visible = ref(false);
const formRef = ref(null);
const formData = ref(cloneDeep(INITIAL_FORM));
const loading = ref(false);
const router = useRouter();
const { copy } = useClipboard({ source: formData.value.link });
const rules = {
receiver: [{ required: true, message: '请输入分享对象' }],
};
const reset = () => {
loading.value = false;
formData.value = cloneDeep(INITIAL_FORM);
formRef.value?.resetFields?.();
formRef.value?.clearValidate?.();
};
const onClose = () => {
visible.value = false;
reset();
};
const onGenerateLink = () => {
formRef.value.validate().then(async (errors) => {
if (!errors) {
try {
loading.value = true;
const { code, data } = await postShareLinksGenerate(formData.value);
if (code === 200) {
onClose();
const url = router.resolve({
path: `/explore/list/${data.code}`,
}).href;
copy(generateFullUrl(url));
AMessage.success('复制成功!');
emit('close');
}
} finally {
loading.value = false;
}
}
});
};
const open = (workIds) => {
formData.value.work_ids = workIds;
visible.value = true;
};
expose({
open,
});
return () => (
<Modal
v-model:visible={visible.value}
title="分享内容稿件"
width="480px"
onClose={onClose}
unmount-on-close
v-slots={{
footer: () => (
<>
<Button size="medium" onClick={onClose}>
取消
</Button>
<Button type="primary" class="ml-16px" size="medium" onClick={onGenerateLink} disabled={loading.value}>
{loading.value ? '生成中...' : '生成链接'}
</Button>
</>
),
}}
>
<Form ref={formRef} rules={rules} model={formData.value} auto-label-width>
<FormItem label="有效期" prop="days">
<CommonSelect
v-model={formData.value.days}
options={OPTIONS}
multiple={false}
placeholder="请选择有效期"
size="large"
class="!w-240px"
allClear={false}
/>
</FormItem>
<FormItem label="分享对象" prop="receiver" required>
<Input v-model={formData.value.receiver} class="!w-240px" size="large" placeholder="请输入分享对象" />
</FormItem>
</Form>
</Modal>
);
},
};
</script>

View File

@ -1,27 +0,0 @@
.share-manuscript-modal {
.cts {
font-family: $font-family-regular;
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 20px;
&.bold {
font-family: $font-family-medium;
}
}
.filter-row-item {
.label {
color: var(--Text-1, #211f24);
font-size: 14px;
}
}
.arco-modal-body {
height: 464px;
display: flex;
flex-direction: column;
overflow: hidden;
.arco-scrollbar-track {
display: none !important;
}
}
}

View File

@ -3,16 +3,16 @@ import { Button, Message as AMessage, Spin } from '@arco-design/web-vue';
import { useRouter, useRoute } from 'vue-router';
import { AuditStatus } from '@/views/creative-generation-workshop/manuscript/check-list/constants';
import { getWorksDetail } from '@/api/all/generationWorkshop';
import { getWorksDetailWriter } from '@/api/all/generationWorkshop-writer.ts';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts';
import { slsWithCatch } from '@/utils/stroage.ts';
const DEFAULT_SOURCE_INFO = {
title: '内容稿件列表',
routeName: 'ManuscriptList',
routePath: '/writer/manuscript/list',
};
const SOURCE_MAP = new Map([['check', { title: '内容稿件审核', routeName: 'ManuscriptCheckList' }]]);
const SOURCE_MAP = new Map([['check', { title: '内容稿件审核', routePath: '/writer/manuscript/check-list' }]]);
export default {
setup(props, { emit, expose }) {
@ -35,7 +35,7 @@ export default {
const sourceInfo = computed(() => SOURCE_MAP.get(source) ?? DEFAULT_SOURCE_INFO);
const onBack = () => {
router.push({ name: sourceInfo.value.routeName });
router.push({ path: `${sourceInfo.value.routePath}/${route.params.writerCode}` });
};
const initData = () => {
@ -52,7 +52,7 @@ export default {
const getData = async () => {
try {
loading.value = true;
const { code, data } = await getWorksDetail(workId.value);
const { code, data } = await getWorksDetailWriter(workId.value);
if (code === 200) {
dataSource.value = data;
initData();
@ -111,8 +111,8 @@ export default {
if (isPassed) {
console.log('审核详情');
} else {
slsWithCatch('manuscriptCheckIds', [workId.value]);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', [workId.value]);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
}
};
@ -125,7 +125,7 @@ export default {
size="medium"
type="outline"
class="mr-12px"
onClick={() => router.push(`/manuscript/edit/${workId.value}`)}
onClick={() => router.push(`/writer/manuscript/edit/${route.params.writerCode}/${workId.value}`)}
>
编辑
</Button>

View File

@ -16,6 +16,7 @@ import { ref } from 'vue';
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const onClose = () => {
@ -23,7 +24,7 @@ const onClose = () => {
};
const onConfirm = () => {
onClose();
router.push({ name: 'ManuscriptList' });
router.push({ path: `/writer/manuscript/list/${route.params.writerCode}` });
};
const open = () => {

View File

@ -2,7 +2,8 @@
import { Button, Message as AMessage } from '@arco-design/web-vue';
import EditForm, { ENUM_UPLOAD_STATUS, INITIAL_VIDEO_INFO } from '../components/edit-form';
import CancelEditModal from './cancel-edit-modal.vue';
import { getWorksDetail, putWorksUpdate } from '@/api/all/generationWorkshop';
import { getWorksDetailWriter, putWorksUpdateWriter } from '@/api/all/generationWorkshop-writer.ts';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools';
import { slsWithCatch } from '@/utils/stroage.ts';
@ -40,14 +41,14 @@ export default {
}
const filteredWorks = omit(dataSource.value, 'videoInfo');
const { code, data } = await putWorksUpdate({ id: workId.value, ...filteredWorks });
const { code, data } = await putWorksUpdateWriter({ id: workId.value, ...filteredWorks });
if (code === 200) {
AMessage.success('保存成功');
isSaved.value = true;
if (check) {
slsWithCatch('manuscriptCheckIds', [workId.value]);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', [workId.value]);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
} else {
onBack();
}
@ -55,7 +56,7 @@ export default {
});
};
const getData = async () => {
const { code, data } = await getWorksDetail(workId.value);
const { code, data } = await getWorksDetailWriter(workId.value);
if (code === 200) {
const { type, files } = data;
const _data = { ...data, videoInfo: cloneDeep(INITIAL_VIDEO_INFO) };
@ -81,7 +82,7 @@ export default {
dataSource.value.videoInfo = { ...dataSource.value.videoInfo, ...newVideoInfo };
};
const onBack = () => {
router.push({ name: 'ManuscriptList' });
router.push({ path: `/writer/manuscript/list/${route.params.writerCode}` });
};
onMounted(() => {
workId && getData();

View File

@ -41,11 +41,11 @@ export const TABLE_COLUMNS = [
sortDirections: ['ascend', 'descend'],
},
},
{
title: '上传人员',
dataIndex: 'uploader',
width: 180,
},
// {
// title: '上传人员',
// dataIndex: 'uploader',
// width: 180,
// },
{
title: '最后修改时间',
dataIndex: 'last_modified_at',
@ -54,11 +54,11 @@ export const TABLE_COLUMNS = [
sortDirections: ['ascend', 'descend'],
},
},
{
title: '最后修改人员',
dataIndex: 'last_modifier',
width: 180,
},
// {
// title: '最后修改人员',
// dataIndex: 'last_modifier',
// width: 180,
// },
{
title: '操作',
dataIndex: 'operation',

View File

@ -20,7 +20,7 @@
<script setup>
import { ref } from 'vue';
import { deleteWork } from '@/api/all/generationWorkshop';
import { deleteWorkWriter } from '@/api/all/generationWorkshop-writer.ts';
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
const update = inject('update');
@ -46,7 +46,7 @@ const open = (record) => {
};
async function onDelete() {
const { code } = await deleteWork(projectId.value);
const { code } = await deleteWorkWriter(projectId.value);
if (code === 200) {
AMessage.success('删除成功');
update()

View File

@ -116,6 +116,7 @@ const props = defineProps({
});
const tableRef = ref(null);
const route = useRoute();
const handleSorterChange = (column, order) => {
emits('sorterChange', column, order === 'ascend' ? 'asc' : 'desc');
@ -124,10 +125,10 @@ const onDelete = (item) => {
emits('delete', item);
};
const onEdit = (item) => {
router.push(`/manuscript/edit/${item.id}`);
router.push(`/writer/manuscript/edit/${route.params.writerCode}/${item.id}`);
};
const onDetail = (item) => {
router.push(`/manuscript/detail/${item.id}`);
router.push(`/writer/manuscript/detail/${route.params.writerCode}/${item.id}`);
};
const getStatusInfo = (audit_status) => {

View File

@ -11,9 +11,7 @@ import {
Message as AMessage,
Textarea,
} from '@arco-design/web-vue';
import { useClipboard } from '@vueuse/core';
import { getWriterLinksGenerate, getTemplateUrl, postWorksByLink, postWorksByFile } from '@/api/all/generationWorkshop';
import { generateFullUrl } from '@/utils/tools';
import { getTemplateUrlWriter, postWorksByLinkWriter, postWorksByFileWriter } from '@/api/all/generationWorkshop-writer.ts';
import TextOverTips from '@/components/text-over-tips';
import icon1 from '@/assets/img/media-account/icon-feedback-fail.png';
@ -29,7 +27,6 @@ const TASK_STATUS = {
const UPLOAD_TYPE = {
LINK: 'link',
LOCAL: 'local',
HANDWRITE: 'handwrite',
};
// 初始表单数据
@ -52,11 +49,9 @@ export default {
const works = ref([]);
// 剪贴板功能
const { copy } = useClipboard({ source: form.value.writerLink });
const isLink = computed(() => uploadType.value === UPLOAD_TYPE.LINK);
const isLocal = computed(() => uploadType.value === UPLOAD_TYPE.LOCAL);
const isHandwrite = computed(() => uploadType.value === UPLOAD_TYPE.HANDWRITE);
const isDefault = computed(() => taskStatus.value === TASK_STATUS.DEFAULT);
// 模态框标题
@ -79,19 +74,7 @@ export default {
works.value = [];
};
const getWriterLink = async () => {
const { code, data } = await getWriterLinksGenerate();
if (code === 200) {
const url = router.resolve({
path: `/writer/manuscript/list/${data.code}`,
}).href;
form.value.writerLink = generateFullUrl(url);
console.log('getWriterLinksGenerate -----writer-code---->', form.value.writerLink);
}
};
const open = () => {
getWriterLink();
visible.value = true;
};
@ -102,15 +85,11 @@ export default {
// 防抖提交
const debouncedSubmit = debounce(async () => {
if (isHandwrite.value) {
handleHandwriteSubmit();
return;
}
formRef.value?.validate(async (errors) => {
if (!errors) {
taskStatus.value = TASK_STATUS.LOADING;
const { link } = form.value;
const { code, data } = await postWorksByLink({ link });
const { code, data } = await postWorksByLinkWriter({ link });
if (code === 200) {
taskStatus.value = TASK_STATUS.SUCCESS;
works.value = data;
@ -124,18 +103,6 @@ export default {
debouncedSubmit();
};
// 手写提交处理
const handleHandwriteSubmit = () => {
if (!form.value.writerLink) {
AMessage.warning('请输入上传链接!');
return;
}
copy(form.value.writerLink);
AMessage.success('复制成功!');
onClose();
};
// 取消上传
const onCancelUpload = () => {
taskStatus.value = TASK_STATUS.DEFAULT;
@ -153,7 +120,7 @@ export default {
const formData = new FormData();
formData.append('file', file);
const { code, data } = await postWorksByFile(formData, {
const { code, data } = await postWorksByFileWriter(formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
@ -169,7 +136,7 @@ export default {
// 跳转编辑
const goUpload = () => {
router.push(`/manuscript/upload/1`);
router.push(`/writer/manuscript/upload/${route.params.writerCode}/1`);
onClose();
};
@ -181,16 +148,13 @@ export default {
// 上传方式切换
const onUploadTypeChange = (val) => {
if (val === UPLOAD_TYPE.HANDWRITE) {
getWriterLink();
}
// uploadType.value = val;
// formRef.value?.clearValidate?.();
uploadType.value = val;
formRef.value?.clearValidate?.();
};
// 下载模板
const handleDownloadTemplate = async () => {
const { code, data } = await getTemplateUrl();
const { code, data } = await getTemplateUrlWriter();
if (code === 200) {
window.open(data.download_url, '_blank');
}
@ -208,13 +172,6 @@ export default {
</FormItem>
);
// 渲染手写上传表单
const renderHandwriteForm = () => (
<FormItem label="上传链接" field="writerLink">
<Input v-model={form.value.writerLink} placeholder="请输入上传链接" disabled size="large" />
</FormItem>
);
// 渲染本地上传表单
const renderLocalForm = () => (
<FormItem label="内容稿件">
@ -290,7 +247,6 @@ export default {
[TASK_STATUS.DEFAULT]: () => {
const formMap = {
[UPLOAD_TYPE.LINK]: renderLinkForm,
[UPLOAD_TYPE.HANDWRITE]: renderHandwriteForm,
[UPLOAD_TYPE.LOCAL]: renderLocalForm,
};
return formMap[uploadType.value]?.();
@ -317,7 +273,7 @@ export default {
取消
</Button>
<Button type="primary" size="medium" onClick={onSubmit}>
{isHandwrite.value ? '复制链接' : '确认'}
确认
</Button>
</>
),
@ -374,9 +330,8 @@ export default {
{isDefault.value && (
<FormItem label="上传方式">
<RadioGroup v-model={uploadType.value} onChange={onUploadTypeChange}>
<Radio value={UPLOAD_TYPE.LINK}>链接上传</Radio>
<Radio value={UPLOAD_TYPE.LINK}>外部链接上传</Radio>
<Radio value={UPLOAD_TYPE.LOCAL}>本地上传</Radio>
<Radio value={UPLOAD_TYPE.HANDWRITE}>写手上传</Radio>
</RadioGroup>
</FormItem>
)}

View File

@ -4,9 +4,6 @@
<div class="top flex h-64px px-24px py-10px justify-between items-center">
<p class="text-18px font-400 lh-26px color-#211F24 title">内容稿件列表</p>
<div class="flex items-center">
<a-button type="outline" size="medium" class="mr-12px" @click="handleShareModal">
分享内容稿件
</a-button>
<a-button type="primary" size="medium" @click="openUploadModal">
<template #icon>
<icon-plus size="16" />
@ -38,7 +35,6 @@
<DeleteManuscriptModal ref="deleteManuscriptModalRef" />
<UploadManuscriptModal ref="uploadManuscriptModalRef" />
<ShareManuscriptModal ref="shareManuscriptModalRef" />
</div>
</template>
<script lang="jsx" setup>
@ -48,10 +44,9 @@ import FilterBlock from './components/filter-block';
import ManuscriptTable from './components/manuscript-table';
import DeleteManuscriptModal from './components/manuscript-table/delete-manuscript-modal.vue';
import UploadManuscriptModal from './components/upload-manuscript-modal';
import ShareManuscriptModal from '@/views/creative-generation-workshop/manuscript/components/share-manuscript-modal';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { getWorksPage } from '@/api/all/generationWorkshop.ts';
import { getWorksPageWriter } from '@/api/all/generationWorkshop-writer.ts';
import { INITIAL_QUERY, EnumCheckStatus } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
const { dataSource, pageInfo, onPageChange, onPageSizeChange, resetPageInfo } = useTableSelectionWithPagination({
@ -66,11 +61,10 @@ const query = ref(cloneDeep(INITIAL_QUERY));
const addManuscriptModalRef = ref(null);
const deleteManuscriptModalRef = ref(null);
const uploadManuscriptModalRef = ref(null);
const shareManuscriptModalRef = ref(null);
const getData = async () => {
const { page, page_size } = pageInfo.value;
const { code, data } = await getWorksPage({
const { code, data } = await getWorksPageWriter({
...query.value,
page,
page_size,
@ -98,9 +92,6 @@ const handleSorterChange = (column, order) => {
reload();
};
const handleShareModal = () => {
shareManuscriptModalRef.value.open()
};
const openUploadModal = () => {
uploadManuscriptModalRef.value?.open();
};

View File

@ -16,6 +16,7 @@ import { ref } from 'vue';
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const num = ref('');
@ -25,7 +26,7 @@ const onClose = () => {
};
const onConfirm = () => {
onClose();
router.push({ name: 'ManuscriptList' });
router.push({ path: `/writer/manuscript/list/${route.params.writerCode}` });
};
const open = (manusNum) => {

View File

@ -6,7 +6,7 @@ import CancelUploadModal from './cancel-upload-modal.vue';
import UploadSuccessModal from './upload-success-modal.vue';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants';
import { postWorksBatch } from '@/api/all/generationWorkshop.ts';
import { postWorksBatchWriter } from '@/api/all/generationWorkshop-writer.ts';
import icon1 from '@/assets/img/creative-generation-workshop/icon-photo.png';
import icon2 from '@/assets/img/creative-generation-workshop/icon-video.png';
@ -75,13 +75,13 @@ export default {
const onSubmit = async (check) => {
uploadLoading.value = true;
const filteredWorks = map(works.value, (work) => omit(work, 'videoInfo'));
const { code, data } = await postWorksBatch({ works: filteredWorks });
const { code, data } = await postWorksBatchWriter({ works: filteredWorks });
if (code === 200) {
uploadLoading.value = false;
if (check) {
uploadSuccessModal.value?.open(workId);
} else {
router.push({ name: 'ManuscriptList' });
router.push({ path: `/writer/manuscript/list/${route.params.writerCode}` });
}
}
};

View File

@ -19,6 +19,7 @@ import { slsWithCatch } from '@/utils/stroage.ts';
import icon1 from '@/assets/img/media-account/icon-feedback-success.png';
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const workId = ref('');
@ -29,16 +30,15 @@ const onClose = () => {
const onBack = () => {
onClose();
router.push({ name: 'ManuscriptList' });
router.push({ path: `/writer/manuscript/list/${route.params.writerCode}` });
};
const onConfirm = () => {
visible.value = false;
slsWithCatch('manuscriptCheckIds', [workId.value]);
router.push({ name: 'ManuscriptCheck' });
slsWithCatch('writerManuscriptCheckIds', [workId.value]);
router.push({ path: `/writer/manuscript/check/${route.params.writerCode}` });
};
const open = (id) => {
console.log({ id });
workId.value = id;
visible.value = true;

View File

@ -16,8 +16,10 @@ import {
getWorkAuditsDetail,
getWorkAuditsBatchDetail,
postWorkAuditsAiReview,
getWorkAuditsAiReviewResult,
} from '@/api/all/generationWorkshop.ts';
export default {
setup(props, { emit, expose }) {
const router = useRouter();
@ -38,6 +40,8 @@ export default {
const { handleStartCheck, handleAgainCheck, ticket, checkLoading } = useGetAiReviewResult({
cardInfo: selectCardInfo,
startAiReviewFn: postWorkAuditsAiReview,
getAiReviewResultFn: getWorkAuditsAiReviewResult,
updateAiReview(ai_review) {
selectCardInfo.value.ai_review = ai_review;
},