| | |
| | | { |
| | | title: '语义词', |
| | | align:"center", |
| | | dataIndex: 'semanticWord.word' |
| | | dataIndex: 'semanticWord.word', |
| | | width: 200, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap; overflow: visible;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | { |
| | | title: '标题', |
| | | align:"center", |
| | | dataIndex: 'title', |
| | | width: 200, |
| | | ellipsis: false |
| | | width: 450, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | // { |
| | | // title: '开始时间', |
| | |
| | | // }, |
| | | { |
| | | title: '见词时间', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.lookTime' |
| | | dataIndex: 'semanticWord.lookTime', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | |
| | | { |
| | | title: '审核状态', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'status_dictText' |
| | | dataIndex: 'status_dictText', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '审核意见', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.remark' |
| | | dataIndex: 'semanticWord.remark', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '预定排名', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.ranking' |
| | | dataIndex: 'semanticWord.ranking', |
| | | width: 80, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '当前排名', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.nowNo' |
| | | dataIndex: 'semanticWord.nowNo', |
| | | width: 80, |
| | | ellipsis: false |
| | | }, |
| | | // { |
| | | // title: '文案编辑', |
| | |
| | | <!--字段回显插槽--> |
| | | <template v-slot:bodyCell="{ column, record }"> |
| | | <template v-if="column.dataIndex === 'semanticWord.word'"> |
| | | {{ record.semanticWord?.word || '--' }} |
| | | <span style="white-space: nowrap;">{{ record.semanticWord?.word || '--' }}</span> |
| | | </template> |
| | | <template v-else-if="column.dataIndex === 'title'"> |
| | | {{ record.title || '--' }} |
| | | <span style="white-space: nowrap;">{{ record.title || '--' }}</span> |
| | | </template> |
| | | <template v-else-if="column.dataIndex === 'semanticWord.lookTime'"> |
| | | {{ record.semanticWord?.lookTime || '--' }} |
| | |
| | | { |
| | | title: '语义词', |
| | | align:"center", |
| | | dataIndex: 'semanticWord.word' |
| | | dataIndex: 'semanticWord.word', |
| | | width: 200, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap; overflow: visible;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | { |
| | | title: '标题', |
| | | align:"center", |
| | | dataIndex: 'title', |
| | | width: 200, |
| | | ellipsis: false |
| | | width: 400, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap; overflow: visible;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | { |
| | | title: '审核状态', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'status_dictText' |
| | | dataIndex: 'status_dictText', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '审核意见', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'remark' |
| | | dataIndex: 'remark', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '预定排名', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.ranking' |
| | | dataIndex: 'semanticWord.ranking', |
| | | width: 80, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '当前排名', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.nowNo' |
| | | dataIndex: 'semanticWord.nowNo', |
| | | width: 80, |
| | | ellipsis: false |
| | | }, |
| | | { |
| | | title: '文案编辑', |
| | | headerAlign:"center", |
| | | align:"center", |
| | | dataIndex: 'semanticWord.changer' |
| | | dataIndex: 'semanticWord.changer', |
| | | width: 100, |
| | | ellipsis: false |
| | | }, |
| | | ]; |
| | | //查询数据 |
| | |
| | | <j-upload-button type="primary" v-auth="'copywriting:copywriting:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls" |
| | | >导入</j-upload-button |
| | | > |
| | | |
| | | |
| | | <a-dropdown v-if="selectedRowKeys.length > 0"> |
| | | <template #overlay> |
| | | <a-menu> |
| | | <a-menu-item key="1" @click="batchHandleDelete"> |
| | | <Icon icon="ant-design:delete-outlined"></Icon> |
| | | 删除 |
| | | </a-menu-item> |
| | | <a-menu-item key="2" @click="batchHandleReview"> |
| | | <Icon icon="ant-design:check-circle-outlined"></Icon> |
| | | 批量审核 |
| | | </a-menu-item> |
| | | </a-menu> |
| | | </template> |
| | |
| | | </BasicTable> |
| | | <!-- 表单区域 --> |
| | | <CopywritingModal @register="registerModal" @success="handleSuccess"></CopywritingModal> |
| | | |
| | | |
| | | <!-- 审核意见弹窗 --> |
| | | <BasicModal @register="registerReviewModal" :footer="null" width="600px"> |
| | | <template #title> |
| | |
| | | </BasicModal> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | <script lang="ts" name="copywriting-copywriting" setup> |
| | | import { reactive, ref } from 'vue'; |
| | | import { BasicTable, TableAction } from '/@/components/Table'; |
| | | import { BasicModal, useModal } from '/@/components/Modal'; |
| | | import { useListPage } from '/@/hooks/system/useListPage'; |
| | | import { useRouter } from 'vue-router'; |
| | | import { defHttp } from '/@/utils/http/axios'; |
| | | import { message } from 'ant-design-vue'; |
| | | import CopywritingModal from './components/CopywritingModal.vue'; |
| | | import { columns, searchFormSchema, superQuerySchema } from './Copywriting.data'; |
| | | import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './Copywriting.api'; |
| | |
| | | schemas: searchFormSchema, |
| | | autoSubmitOnEnter: true, |
| | | showAdvancedButton: true, |
| | | autoAdvancedCol: 4, |
| | | fieldMapToNumber: [], |
| | | fieldMapToTime: [], |
| | | compact: true, |
| | | baseColProps: { |
| | | xs: 24, |
| | | sm: 4, |
| | | md: 4, |
| | | lg: 4, |
| | | xl: 4, |
| | | xxl: 4, |
| | | }, |
| | | rowProps: { |
| | | gutter: 8, |
| | | }, |
| | | actionColOptions: { |
| | | span: 8, |
| | | style: { textAlign: 'left' }, |
| | | }, |
| | | }, |
| | | actionColumn: { |
| | | width: 180, |
| | | width: 120, |
| | | fixed: 'right', |
| | | }, |
| | | beforeFetch: (params) => { |
| | |
| | | success: handleSuccess, |
| | | }, |
| | | }); |
| | | |
| | | |
| | | const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext; |
| | | |
| | | |
| | | // 高级查询配置 |
| | | const superQueryConfig = reactive(superQuerySchema); |
| | | |
| | | |
| | | /** |
| | | * 高级查询事件 |
| | | */ |
| | |
| | | } |
| | | function handleEdit(record: Recordable) { |
| | | try { |
| | | // 直接跳转到生成页面,传递当前页面的参数 |
| | | router.push({ |
| | | path: '/copywriting/generated/index', |
| | | path: '/copywritingReview/review/index', |
| | | query: { |
| | | semanticWord: record.semanticWord?.word || '', |
| | | ranking: record.semanticWord?.ranking || '', |
| | | outWord: record.semanticWord?.outWord || '', |
| | | contractId: record.semanticWord?.contractId || '', |
| | | id: record.id || '', |
| | | title: record.title || '', |
| | | text: record.text || '', |
| | | fromEdit: 'true', // 添加标识,表示来自编辑按钮跳转 |
| | | }, |
| | | }); |
| | | } catch (error) { |
| | | console.error('跳转失败:', error); |
| | | console.error('路由跳转失败:', error); |
| | | // 如果路由跳转失败,尝试使用完整路径 |
| | | window.location.href = '/#/copywriting/generated/index?id=' + (record.id || ''); |
| | | window.location.href = '/#/copywriting/download'; |
| | | } |
| | | } |
| | | /** |
| | |
| | | window.location.href = '/#/copywritingReview/detail/index?id=' + (record.id || ''); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 查看审核意见 |
| | | */ |
| | |
| | | showFooter: false, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 审核事件 |
| | | */ |
| | | function handleReview(record: Recordable) { |
| | | try { |
| | | router.push({ |
| | | path: '/copywriting/generated/index', |
| | | query: { |
| | | semanticWord: record.semanticWord?.word || '', |
| | | ranking: record.semanticWord?.ranking || '', |
| | | outWord: record.semanticWord?.outWord || '', |
| | | contractId: record.semanticWord?.contractId || '', |
| | | id: record.id || '', |
| | | title: record.title || '', |
| | | text: record.text || '', |
| | | fromReview: 'true', // 添加标识,表示来自审核按钮跳转 |
| | | }, |
| | | }); |
| | | } catch (error) { |
| | | console.error('跳转失败:', error); |
| | | window.location.href = '/#/copywriting/generated/index?id=' + (record.id || ''); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 删除事件 |
| | | */ |
| | |
| | | async function batchHandleDelete() { |
| | | await batchDelete({ ids: selectedRowKeys.value }, handleSuccess); |
| | | } |
| | | |
| | | /** |
| | | * 批量审核事件 |
| | | */ |
| | | async function batchHandleReview() { |
| | | if (selectedRowKeys.value.length === 0) { |
| | | return; |
| | | } |
| | | try { |
| | | // 构建请求数据 |
| | | const requestData = { |
| | | ids: selectedRowKeys.value, |
| | | status: 3, // 审核通过状态码 |
| | | remark: '批量审核通过' |
| | | }; |
| | | |
| | | // 调用批量审核接口 |
| | | await defHttp.post({ |
| | | url: '/copywritingReview/copywritingReview/batchReview', |
| | | params: requestData |
| | | }); |
| | | |
| | | // 审核成功后刷新列表 |
| | | handleSuccess(); |
| | | message.success('批量审核成功'); |
| | | } catch (error) { |
| | | console.error('批量审核失败:', error); |
| | | message.error('批量审核失败'); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 成功回调 |
| | | */ |
| | |
| | | // 根据状态值决定按钮显示和点击事件 |
| | | const isReviewStatus = record.status == 3 || record.status == 4; |
| | | const buttonLabel = isReviewStatus ? '查看' : '审核'; |
| | | const onClickHandler = isReviewStatus ? handleReviewDetail : handleReview; |
| | | |
| | | const onClickHandler = isReviewStatus ? handleReviewDetail : handleEdit; |
| | | |
| | | return [ |
| | | { |
| | | label: '编辑', |
| | | onClick: handleEdit.bind(null, record), |
| | | auth: 'copywriting:copywriting:edit', |
| | | }, |
| | | // { |
| | | // label: '编辑', |
| | | // onClick: handleEdit.bind(null, record), |
| | | // auth: 'copywriting:copywriting:edit' |
| | | // }, |
| | | { |
| | | label: buttonLabel, |
| | | onClick: onClickHandler.bind(null, record), |
| | |
| | | ]; |
| | | } |
| | | </script> |
| | | |
| | | |
| | | <style lang="less" scoped> |
| | | :deep(.ant-picker), |
| | | :deep(.ant-input-number) { |
| | | width: 100%; |
| | | } |
| | | |
| | | /* 确保搜索表单完全靠左对齐,消除所有左边空隙 */ |
| | | :deep(.basic-table-search) { |
| | | padding-left: 0 !important; |
| | | margin-left: 0 !important; |
| | | } |
| | | |
| | | /* 消除表单容器的左边空隙 */ |
| | | :deep(.ant-form) { |
| | | margin-left: 0 !important; |
| | | padding-left: 0 !important; |
| | | } |
| | | |
| | | /* 消除行容器的左边空隙 */ |
| | | :deep(.ant-form-item-row) { |
| | | margin-left: 0 !important; |
| | | } |
| | | |
| | | /* 消除表单项的左边空隙 */ |
| | | :deep(.ant-form-item) { |
| | | margin-left: 0 !important; |
| | | } |
| | | </style> |
| | |
| | | <div class="page-header"> |
| | | <h2>文案审核</h2> |
| | | </div> |
| | | |
| | | |
| | | <!-- 文案内容显示区域 --> |
| | | <div class="content-section"> |
| | | <div class="section-title"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <!-- 横线分隔符 --> |
| | | <a-divider /> |
| | | |
| | | |
| | | <!-- 审核表单区域 --> |
| | | <div class="review-form-section"> |
| | | <a-form :model="reviewForm" layout="vertical" @finish="handleSubmit"> |
| | |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | <script lang="ts" name="copywriting-review" setup> |
| | | import { reactive, onMounted, ref } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | import { message, Modal } from 'ant-design-vue'; |
| | | import { reviewCopywriting, queryById } from '../Copywriting.api'; |
| | | import { useUserStore } from '/@/store/modules/user'; |
| | | |
| | | |
| | | // 路由实例 |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | |
| | | |
| | | // 文案ID |
| | | const copywritingId = route.query.id as string; |
| | | |
| | | |
| | | // 文案详情数据 |
| | | const copywritingDetail = ref<any>(null); |
| | | const copywritingContent = ref<string>(''); |
| | | |
| | | |
| | | // 审核表单数据 |
| | | const reviewForm = reactive({ |
| | | recommendedPlatform: '', |
| | | reviewOpinion: '', |
| | | }); |
| | | |
| | | |
| | | // 加载状态 |
| | | const loading = reactive({ |
| | | reject: false, |
| | | approve: false, |
| | | detail: false, |
| | | }); |
| | | |
| | | |
| | | /** |
| | | * 获取文案详情 |
| | | */ |
| | |
| | | message.error('未获取到文案ID,请返回列表页重新选择'); |
| | | return; |
| | | } |
| | | |
| | | |
| | | loading.detail = true; |
| | | try { |
| | | const result = await queryById({ id: copywritingId }); |
| | | copywritingDetail.value = result; |
| | | |
| | | |
| | | // 根据实际返回的数据结构设置文案内容 |
| | | // 这里假设返回的数据中有content字段,如果没有请根据实际字段调整 |
| | | if (result && result.content) { |
| | |
| | | } else { |
| | | // 如果接口没有返回具体内容,使用模拟数据 |
| | | copywritingContent.value = `文案标题:${result.title || '待审核文案'} |
| | | |
| | | |
| | | 语义词:${result.semanticWord?.word || '未指定'} |
| | | 签约排名:${result.semanticWord?.ranking || '未指定'} |
| | | |
| | | |
| | | 文案内容:${result.description || result.remark || '暂无具体文案内容'} |
| | | |
| | | |
| | | 请认真审核以上内容,并在下方填写审核意见。`; |
| | | } |
| | | } catch (error) { |
| | |
| | | message.error('获取文案详情失败,请稍后重试'); |
| | | // 如果接口调用失败,使用模拟数据 |
| | | copywritingContent.value = `文案标题:待审核文案 |
| | | |
| | | |
| | | 语义词:未指定 |
| | | 签约排名:未指定 |
| | | |
| | | |
| | | 这是一段需要审核的文案内容,来自接口数据。文案内容可以包含各种信息,比如产品描述、营销文案、新闻稿等。审核人员需要仔细阅读并给出专业的审核意见。 |
| | | |
| | | |
| | | 文案审核要点: |
| | | 1. 内容是否符合法律法规 |
| | | 2. 语言表达是否准确清晰 |
| | | 3. 是否有敏感词汇 |
| | | 4. 是否符合品牌调性 |
| | | 5. 是否有语法错误或错别字 |
| | | |
| | | |
| | | 请认真审核以上内容,并在下方填写审核意见。`; |
| | | } finally { |
| | | loading.detail = false; |
| | | } |
| | | }; |
| | | |
| | | |
| | | // 生命周期 |
| | | onMounted(() => { |
| | | getCopywritingDetail(); |
| | | }); |
| | | |
| | | |
| | | // 提交处理 |
| | | const handleSubmit = (values: any) => { |
| | | console.log('表单数据:', values); |
| | | }; |
| | | |
| | | |
| | | // 驳回处理 |
| | | const handleReject = () => { |
| | | if (!reviewForm.reviewOpinion.trim()) { |
| | | message.warning('请填写审核意见'); |
| | | return; |
| | | } |
| | | |
| | | |
| | | loading.reject = true; |
| | | |
| | | |
| | | Modal.confirm({ |
| | | title: '确认驳回', |
| | | content: '确定要驳回该文案吗?', |
| | |
| | | remark: reviewForm.reviewOpinion, |
| | | platform: reviewForm.recommendedPlatform, |
| | | }; |
| | | |
| | | |
| | | reviewCopywriting(params) |
| | | .then(() => { |
| | | loading.reject = false; |
| | |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | |
| | | // 通过处理 |
| | | const handleApprove = () => { |
| | | loading.approve = true; |
| | | |
| | | |
| | | Modal.confirm({ |
| | | title: '确认通过', |
| | | content: '确定要通过该文案吗?', |
| | |
| | | remark: reviewForm.reviewOpinion, |
| | | platform: reviewForm.recommendedPlatform, |
| | | }; |
| | | |
| | | |
| | | reviewCopywriting(params) |
| | | .then(() => { |
| | | loading.approve = false; |
| | |
| | | }); |
| | | }; |
| | | </script> |
| | | |
| | | |
| | | <style lang="less" scoped> |
| | | .copywriting-review-page { |
| | | padding: 24px; |
| | | background: #fff; |
| | | min-height: calc(100vh - 48px); |
| | | |
| | | |
| | | .page-header { |
| | | margin-bottom: 24px; |
| | | |
| | | |
| | | h2 { |
| | | margin: 0; |
| | | font-size: 20px; |
| | |
| | | color: #262626; |
| | | } |
| | | } |
| | | |
| | | |
| | | .content-section { |
| | | margin-bottom: 24px; |
| | | |
| | | |
| | | .section-title { |
| | | margin-bottom: 16px; |
| | | |
| | | |
| | | span { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | color: #262626; |
| | | } |
| | | } |
| | | |
| | | |
| | | .content-display { |
| | | border: 1px solid #d9d9d9; |
| | | border-radius: 6px; |
| | | padding: 16px; |
| | | background: #fafafa; |
| | | min-height: 120px; |
| | | |
| | | |
| | | .content-text { |
| | | white-space: pre-wrap; |
| | | line-height: 1.6; |
| | | color: #595959; |
| | | } |
| | | |
| | | |
| | | .empty-content { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | .review-form-section { |
| | | .action-buttons { |
| | | display: flex; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 响应式设计 |
| | | @media (max-width: 768px) { |
| | | .copywriting-review-page { |
| | | padding: 16px; |
| | | |
| | | |
| | | .page-header h2 { |
| | | font-size: 18px; |
| | | } |
| | | |
| | | |
| | | .content-section .content-display { |
| | | padding: 12px; |
| | | } |
| | |
| | | <div class="page-header"> |
| | | <h2>文案审核</h2> |
| | | </div> |
| | | |
| | | |
| | | <!-- 文案内容显示区域 --> |
| | | <div class="content-section"> |
| | | <div class="section-title"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <!-- 横线分隔符 --> |
| | | <a-divider /> |
| | | |
| | | |
| | | <!-- 审核表单区域 --> |
| | | <div class="review-form-section"> |
| | | <a-form :model="reviewForm" layout="vertical" @finish="handleSubmit"> |
| | |
| | | <a-form-item label="推荐平台" name="recommendedPlatform"> |
| | | <a-input v-model:value="reviewForm.recommendedPlatform" placeholder="请输入推荐发布的平台" allow-clear /> |
| | | </a-form-item> |
| | | |
| | | |
| | | <!-- 审核意见文本框 --> |
| | | <a-form-item label="审核意见" name="reviewOpinion"> |
| | | <a-textarea v-model:value="reviewForm.reviewOpinion" placeholder="请输入审核意见" :rows="4" show-count :maxlength="500" /> |
| | | </a-form-item> |
| | | |
| | | |
| | | <!-- 按钮区域 --> |
| | | <a-form-item> |
| | | <div class="action-buttons" style="align-items: center; justify-content: center; "> |
| | |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | <script lang="ts" name="copywriting-review" setup> |
| | | import { reactive, onMounted, ref } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | import { message, Modal } from 'ant-design-vue'; |
| | | import { reviewCopywriting, queryById } from '../Copywriting.api'; |
| | | import { useUserStore } from '/@/store/modules/user'; |
| | | |
| | | |
| | | // 路由实例 |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | |
| | | |
| | | // 文案ID |
| | | const copywritingId = route.query.id as string; |
| | | |
| | | |
| | | // 文案详情数据 |
| | | const copywritingDetail = ref<any>(null); |
| | | const copywritingContent = ref<string>(''); |
| | | |
| | | |
| | | // 审核表单数据 |
| | | const reviewForm = reactive({ |
| | | recommendedPlatform: '', |
| | | reviewOpinion: '', |
| | | }); |
| | | |
| | | |
| | | // 加载状态 |
| | | const loading = reactive({ |
| | | reject: false, |
| | | approve: false, |
| | | detail: false, |
| | | }); |
| | | |
| | | |
| | | /** |
| | | * 获取文案详情 |
| | | */ |
| | |
| | | message.error('未获取到文案ID,请返回列表页重新选择'); |
| | | return; |
| | | } |
| | | |
| | | |
| | | loading.detail = true; |
| | | try { |
| | | const result = await queryById({ id: copywritingId }); |
| | | copywritingDetail.value = result; |
| | | |
| | | |
| | | // 根据实际返回的数据结构设置文案内容 |
| | | // 这里假设返回的数据中有content字段,如果没有请根据实际字段调整 |
| | | if (result && result.content) { |
| | |
| | | } else { |
| | | // 如果接口没有返回具体内容,使用模拟数据 |
| | | copywritingContent.value = `文案标题:${result.title || '待审核文案'} |
| | | |
| | | |
| | | 语义词:${result.semanticWord?.word || '未指定'} |
| | | 签约排名:${result.semanticWord?.ranking || '未指定'} |
| | | |
| | | |
| | | 文案内容:${result.description || result.remark || '暂无具体文案内容'} |
| | | |
| | | |
| | | 请认真审核以上内容,并在下方填写审核意见。`; |
| | | } |
| | | } catch (error) { |
| | |
| | | message.error('获取文案详情失败,请稍后重试'); |
| | | // 如果接口调用失败,使用模拟数据 |
| | | copywritingContent.value = `文案标题:待审核文案 |
| | | |
| | | |
| | | 语义词:未指定 |
| | | 签约排名:未指定 |
| | | |
| | | |
| | | 这是一段需要审核的文案内容,来自接口数据。文案内容可以包含各种信息,比如产品描述、营销文案、新闻稿等。审核人员需要仔细阅读并给出专业的审核意见。 |
| | | |
| | | |
| | | 文案审核要点: |
| | | 1. 内容是否符合法律法规 |
| | | 2. 语言表达是否准确清晰 |
| | | 3. 是否有敏感词汇 |
| | | 4. 是否符合品牌调性 |
| | | 5. 是否有语法错误或错别字 |
| | | |
| | | |
| | | 请认真审核以上内容,并在下方填写审核意见。`; |
| | | } finally { |
| | | loading.detail = false; |
| | | } |
| | | }; |
| | | |
| | | |
| | | // 生命周期 |
| | | onMounted(() => { |
| | | getCopywritingDetail(); |
| | | }); |
| | | |
| | | |
| | | // 提交处理 |
| | | const handleSubmit = (values: any) => { |
| | | console.log('表单数据:', values); |
| | | }; |
| | | |
| | | |
| | | // 驳回处理 |
| | | const handleReject = () => { |
| | | if (!reviewForm.reviewOpinion.trim()) { |
| | | message.warning('请填写审核意见'); |
| | | return; |
| | | } |
| | | |
| | | |
| | | loading.reject = true; |
| | | |
| | | |
| | | Modal.confirm({ |
| | | title: '确认驳回', |
| | | content: '确定要驳回该文案吗?', |
| | |
| | | remark: reviewForm.reviewOpinion, |
| | | platform: reviewForm.recommendedPlatform, |
| | | }; |
| | | |
| | | |
| | | reviewCopywriting(params) |
| | | .then(() => { |
| | | loading.reject = false; |
| | |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | |
| | | // 通过处理 |
| | | const handleApprove = () => { |
| | | loading.approve = true; |
| | | |
| | | |
| | | Modal.confirm({ |
| | | title: '确认通过', |
| | | content: '确定要通过该文案吗?', |
| | |
| | | remark: reviewForm.reviewOpinion, |
| | | platform: reviewForm.recommendedPlatform, |
| | | }; |
| | | |
| | | |
| | | reviewCopywriting(params) |
| | | .then(() => { |
| | | loading.approve = false; |
| | |
| | | }); |
| | | }; |
| | | </script> |
| | | |
| | | |
| | | <style lang="less" scoped> |
| | | .copywriting-review-page { |
| | | padding: 24px; |
| | | background: #fff; |
| | | min-height: calc(100vh - 48px); |
| | | |
| | | |
| | | .page-header { |
| | | margin-bottom: 24px; |
| | | |
| | | |
| | | h2 { |
| | | margin: 0; |
| | | font-size: 20px; |
| | |
| | | color: #262626; |
| | | } |
| | | } |
| | | |
| | | |
| | | .content-section { |
| | | margin-bottom: 24px; |
| | | |
| | | |
| | | .section-title { |
| | | margin-bottom: 16px; |
| | | |
| | | |
| | | span { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | color: #262626; |
| | | } |
| | | } |
| | | |
| | | |
| | | .content-display { |
| | | border: 1px solid #d9d9d9; |
| | | border-radius: 6px; |
| | | padding: 16px; |
| | | background: #fafafa; |
| | | min-height: 120px; |
| | | |
| | | |
| | | .content-text { |
| | | white-space: pre-wrap; |
| | | line-height: 1.6; |
| | | color: #595959; |
| | | } |
| | | |
| | | |
| | | .empty-content { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | .review-form-section { |
| | | .action-buttons { |
| | | display: flex; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // 响应式设计 |
| | | @media (max-width: 768px) { |
| | | .copywriting-review-page { |
| | | padding: 16px; |
| | | |
| | | |
| | | .page-header h2 { |
| | | font-size: 18px; |
| | | } |
| | | |
| | | |
| | | .content-section .content-display { |
| | | padding: 12px; |
| | | } |
| | |
| | | <!-- 媒体组 --> |
| | | <div class="form-item"> |
| | | <span class="required-mark">*</span> |
| | | <span class="form-label">媒体组</span> |
| | | <span class="form-label">媒体渠道</span> |
| | | <a-input |
| | | v-model:value="formState.mediaGroups" |
| | | placeholder="请输入媒体组,以逗号分隔" |
| | |
| | | const loadContractList = async () => { |
| | | try { |
| | | console.log('开始加载合同列表...'); |
| | | // 使用模拟数据,避免调用真实接口产生费用 |
| | | console.log('使用模拟数据加载合同列表'); |
| | | |
| | | // 模拟数据 |
| | | const mockContractList = [ |
| | | { |
| | | label: '模拟合同 - 123456', |
| | | value: '123456' |
| | | } |
| | | ]; |
| | | |
| | | contractList.value = mockContractList; |
| | | console.log('合同列表加载完成,使用模拟数据'); |
| | | |
| | | /* |
| | | // 真实数据获取代码(注释掉,避免产生费用) |
| | | // 真实数据获取代码 |
| | | const response = await defHttp.get({ |
| | | url: '/contract/contract/list', |
| | | params: { |
| | |
| | | |
| | | contractList.value = options; |
| | | console.log('合同列表加载完成'); |
| | | */ |
| | | |
| | | } catch (error) { |
| | | console.error('加载合同列表失败:', error); |
| | | createMessage.error('加载合同列表失败'); |
| | |
| | | { |
| | | title: '语义词', |
| | | align:"center", |
| | | dataIndex: 'semanticWord.word' |
| | | dataIndex: 'semanticWord.word', |
| | | width: 200, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap; overflow: visible;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | { |
| | | title: '标题', |
| | | align:"center", |
| | | dataIndex: 'title' |
| | | dataIndex: 'title', |
| | | width: 400, |
| | | ellipsis: false, |
| | | customRender: ({ text }) => { |
| | | return { |
| | | children: text, |
| | | attrs: { |
| | | style: 'text-align: left; white-space: nowrap; overflow: visible;' |
| | | } |
| | | }; |
| | | } |
| | | }, |
| | | { |
| | | title: '审核状态', |
| | |
| | | <ACard :bordered="false"> |
| | | <div class="card-header" style="display: flex; align-items: center; margin-bottom: 16px;"> |
| | | <h3 style="margin: 0; font-size: 16px; font-weight: 600;">语义词添加</h3> |
| | | <a-button type="primary" style="margin-left: 16px;" @click="switchToBatchImport">批量导入</a-button> |
| | | <!-- <a-button type="primary" style="margin-left: 16px;" @click="switchToBatchImport">批量导入</a-button> --> |
| | | </div> |
| | | <PersonTable ref="tableRef" /> |
| | | </ACard> |
| New file |
| | |
| | | |
| | | SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS |
| | | |
| | | Commands marked with * may be preceded by a number, _N. |
| | | Notes in parentheses indicate the behavior if _N is given. |
| | | A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. |
| | | |
| | | h H Display this help. |
| | | q :q Q :Q ZZ Exit. |
| | | --------------------------------------------------------------------------- |
| | | |
| | | MMOOVVIINNGG |
| | | |
| | | e ^E j ^N CR * Forward one line (or _N lines). |
| | | y ^Y k ^K ^P * Backward one line (or _N lines). |
| | | f ^F ^V SPACE * Forward one window (or _N lines). |
| | | b ^B ESC-v * Backward one window (or _N lines). |
| | | z * Forward one window (and set window to _N). |
| | | w * Backward one window (and set window to _N). |
| | | ESC-SPACE * Forward one window, but don't stop at end-of-file. |
| | | d ^D * Forward one half-window (and set half-window to _N). |
| | | u ^U * Backward one half-window (and set half-window to _N). |
| | | ESC-) RightArrow * Right one half screen width (or _N positions). |
| | | ESC-( LeftArrow * Left one half screen width (or _N positions). |
| | | ESC-} ^RightArrow Right to last column displayed. |
| | | ESC-{ ^LeftArrow Left to first column. |
| | | F Forward forever; like "tail -f". |
| | | ESC-F Like F but stop when search pattern is found. |
| | | r ^R ^L Repaint screen. |
| | | R Repaint screen, discarding buffered input. |
| | | --------------------------------------------------- |
| | | Default "window" is the screen height. |
| | | Default "half-window" is half of the screen height. |
| | | --------------------------------------------------------------------------- |
| | | |
| | | SSEEAARRCCHHIINNGG |
| | | |
| | | /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. |
| | | ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. |
| | | n * Repeat previous search (for _N-th occurrence). |
| | | N * Repeat previous search in reverse direction. |
| | | ESC-n * Repeat previous search, spanning files. |
| | | ESC-N * Repeat previous search, reverse dir. & spanning files. |
| | | ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. |
| | | ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. |
| | | ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. |
| | | ESC-u Undo (toggle) search highlighting. |
| | | ESC-U Clear search highlighting. |
| | | &_p_a_t_t_e_r_n * Display only matching lines. |
| | | --------------------------------------------------- |
| | | A search pattern may begin with one or more of: |
| | | ^N or ! Search for NON-matching lines. |
| | | ^E or * Search multiple files (pass thru END OF FILE). |
| | | ^F or @ Start search at FIRST file (for /) or last file (for ?). |
| | | ^K Highlight matches, but don't move (KEEP position). |
| | | ^R Don't use REGULAR EXPRESSIONS. |
| | | ^S _n Search for match in _n-th parenthesized subpattern. |
| | | ^W WRAP search if no match found. |
| | | ^L Enter next character literally into pattern. |
| | | --------------------------------------------------------------------------- |
| | | |
| | | JJUUMMPPIINNGG |
| | | |
| | | g < ESC-< * Go to first line in file (or line _N). |
| | | G > ESC-> * Go to last line in file (or line _N). |
| | | p % * Go to beginning of file (or _N percent into file). |
| | | t * Go to the (_N-th) next tag. |
| | | T * Go to the (_N-th) previous tag. |
| | | { ( [ * Find close bracket } ) ]. |
| | | } ) ] * Find open bracket { ( [. |
| | | ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. |
| | | ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. |
| | | --------------------------------------------------- |