feat: 分享内容稿件

This commit is contained in:
rd
2025-08-01 17:25:21 +08:00
parent a9bb9a45c0
commit 0969c806f5
5 changed files with 288 additions and 132 deletions

View File

@ -12,6 +12,7 @@ import {
} from '@arco-design/web-vue';
import CommonSelect from '@/components/common-select';
import TextOverTips from '@/components/text-over-tips';
import ShareModal from './share-modal';
import { INITIAL_FORM, TABLE_COLUMNS } from './constants';
import { formatTableField, exactFormatTime } from '@/utils/tools';
@ -46,6 +47,7 @@ export default {
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);
@ -67,7 +69,8 @@ export default {
pageInfo.value.total = data.total;
}
};
const handleSearch = () => {
const handleSearch = (value) => {
query.value.audit_status = value;
reload();
};
const reload = () => {
@ -113,7 +116,7 @@ export default {
};
const onShare = () => {
console.log('onShare');
shareModalRef.value?.open();
};
const handleSorterChange = (column, order) => {
query.value.sort_column = column;
@ -127,136 +130,159 @@ export default {
open,
});
return () => (
<Modal
v-model:visible={visible.value}
title="分享内容稿件"
width="920px"
onClose={onClose}
modal-class="share-manuscript-modal"
v-slots={{
footer: () => (
<>
<Button size="large" onClick={onClose}>
取消
</Button>
<Button type="primary" class="ml-16px" size="large" onClick={onShare}>
分享
</Button>
</>
),
}}
>
<div class="filter-row-item mb-16px">
<span class="label 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.value}
data={dataSource.value}
row-key="id"
column-resizable
row-selection={rowSelection.value}
selected-keys={selectedRowKeys.value}
pagination={false}
scroll={{ x: '100%' }}
class="flex-1 w-100% overflow-hidden"
bordered
onSorterChange={handleSorterChange}
onSelect={handleSelect}
onSelectAll={handleSelectAll}
<>
<Modal
v-model:visible={visible.value}
title="分享内容稿件"
width="920px"
onClose={onClose}
unmount-on-close
modal-class="share-manuscript-modal"
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-28px 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);
}
},
}}
/>
))}
</>
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="large" onClick={onClose}>
取消
</Button>
<Button
type="primary"
class="ml-16px"
size="large"
onClick={onShare}
disabled={!selectedRows.value.length}
>
分享
</Button>
</div>
</div>
),
}}
/>
{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 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-28px 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>
</Modal>
<ShareModal ref={shareModalRef} onClose={onClose} />
</>
);
},
};

View File

@ -0,0 +1,115 @@
<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';
const INITIAL_FORM = {
link: '',
data: 1,
target: '',
};
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 { copy } = useClipboard({ source: formData.value.link });
const reset = () => {
formData.value = cloneDeep(INITIAL_FORM);
formRef.value?.resetFields?.();
formRef.value?.clearValidate?.();
};
const onClose = () => {
visible.value = false;
reset();
};
const onCopy = () => {
onClose();
copy(formData.value.link);
AMessage.success('复制成功!');
emit('close');
};
const open = () => {
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="large" onClick={onClose}>
取消
</Button>
<Button type="primary" class="ml-16px" size="large" onClick={onCopy}>
复制链接
</Button>
</>
),
}}
>
<Form ref={formRef} model={formData.value} auto-label-width>
<FormItem label="分享地址" prop="link">
<Input v-model={formData.value.link} size="large" placeholder="请输入分享地址" />
</FormItem>
<FormItem label="有效期" prop="data">
<CommonSelect
v-model={formData.value.data}
options={OPTIONS}
multiple={false}
placeholder="请选择有效期"
size="large"
class="!w-240px"
allClear={false}
/>
</FormItem>
<FormItem label="分享对象" prop="target">
<Input v-model={formData.value.target} class="!w-240px" size="large" placeholder="请输入分享对象" />
</FormItem>
</Form>
</Modal>
);
},
};
</script>

View File

@ -1,17 +1,27 @@
.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-family: $font-family-regular;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
}
.arco-modal-body {
height: 464px;
display: flex;
flex-direction: column;
overflow: hidden;
.arco-scrollbar-track {
display: none !important;
}
}
}

View File

@ -11,6 +11,7 @@ import {
Message as AMessage,
Textarea,
} from '@arco-design/web-vue';
import { useClipboard } from '@vueuse/core';
import TextOverTips from '@/components/text-over-tips';
import icon1 from '@/assets/img/media-account/icon-feedback-fail.png';