feat: 组件库替换
This commit is contained in:
@ -3,13 +3,13 @@
|
|||||||
* @Date: 2025-08-11 22:15:35
|
* @Date: 2025-08-11 22:15:35
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-popover
|
<Popover
|
||||||
:trigger="'hover'"
|
trigger="hover"
|
||||||
class="hover-big-image-preview-popover"
|
:placement="props.position"
|
||||||
:position="props.position"
|
:mouseEnterDelay="props.enterDelay / 1000"
|
||||||
:mouse-enter-delay="props.enterDelay"
|
:mouseLeaveDelay="props.leaveDelay / 1000"
|
||||||
:mouse-leave-delay="props.leaveDelay"
|
:open="props.src ? undefined : false"
|
||||||
:disabled="!props.src"
|
overlayClassName="hover-big-image-preview-popover"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="preview-container">
|
<div class="preview-container">
|
||||||
@ -18,17 +18,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
</a-popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { Popover } from 'ant-design-vue';
|
||||||
// import { computed, onMounted, ref, watch } from 'vue';
|
// import { computed, onMounted, ref, watch } from 'vue';
|
||||||
// import type { ImageOrientation } from '@/utils/tools';
|
// import type { ImageOrientation } from '@/utils/tools';
|
||||||
// import { getImageOrientationByUrl } from '@/utils/tools';
|
// import { getImageOrientationByUrl } from '@/utils/tools';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
src: string;
|
src: string;
|
||||||
position?: 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb';
|
position?: 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight' | 'left' | 'leftTop' | 'leftBottom' | 'right' | 'rightTop' | 'rightBottom';
|
||||||
enterDelay?: number;
|
enterDelay?: number;
|
||||||
leaveDelay?: number;
|
leaveDelay?: number;
|
||||||
}
|
}
|
||||||
@ -67,7 +68,11 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.hover-big-image-preview-popover {
|
.hover-big-image-preview-popover {
|
||||||
.arco-popover-popup-content {
|
.ant-popover-content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-popover-inner {
|
||||||
padding: 16px !important;
|
padding: 16px !important;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-upload
|
<Upload
|
||||||
:custom-request="customRequest"
|
:customRequest="customRequest"
|
||||||
action="/"
|
action="/"
|
||||||
:limit="limit"
|
:maxCount="limit"
|
||||||
:fileList="fileList"
|
:fileList="fileList"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
@success="handleSuccess"
|
|
||||||
@error="handleError"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Upload, message } from 'ant-design-vue';
|
||||||
import { fetchImageUploadFile, fetchUploadFile } from '@/api/all';
|
import { fetchImageUploadFile, fetchUploadFile } from '@/api/all';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
@ -70,8 +68,10 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let previousFileListLength = 0;
|
let previousFileListLength = 0;
|
||||||
//删除图片
|
const onChange = (info) => {
|
||||||
const onChange = (fileList) => {
|
const { fileList } = info;
|
||||||
|
|
||||||
|
// 如果删除了文件
|
||||||
if (fileList.length < previousFileListLength) {
|
if (fileList.length < previousFileListLength) {
|
||||||
if (props.limit === 1) {
|
if (props.limit === 1) {
|
||||||
if (fileList.length === 0) {
|
if (fileList.length === 0) {
|
||||||
@ -87,27 +87,34 @@ const onChange = (fileList) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理上传成功的文件
|
||||||
|
if (info.file.status === 'done' && info.file.response) {
|
||||||
|
handleSuccess(info.file);
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
handleError(info.file.error);
|
||||||
|
}
|
||||||
|
|
||||||
previousFileListLength = fileList.length;
|
previousFileListLength = fileList.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
const beforeUpload = (file, files) => {
|
const beforeUpload = (file, files) => {
|
||||||
if (props.limit > 0 && files.length >= props.limit) {
|
if (props.limit > 0 && files.length >= props.limit) {
|
||||||
Message.warning(`最多只能上传 ${props.limit} 张图片`);
|
message.warning(`最多只能上传 ${props.limit} 张图片`);
|
||||||
return false; // 阻止上传
|
return false; // 阻止上传
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleError = (error) => {
|
const handleError = (error) => {
|
||||||
Message.error('上传失败');
|
message.error('上传失败');
|
||||||
console.error(error);
|
console.error(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
const customRequest = async (option) => {
|
const customRequest = async (option) => {
|
||||||
const { onProgress, onError, onSuccess, fileItem, name } = option;
|
const { onProgress, onError, onSuccess, file, name } = option;
|
||||||
try {
|
try {
|
||||||
// 1. 获取预签名上传URL
|
// 1. 获取预签名上传URL
|
||||||
const response = await fetchUploadFile({ suffix: getFileExtension(fileItem.file.name) });
|
const response = await fetchUploadFile({ suffix: getFileExtension(file.name) });
|
||||||
const preSignedUrl = response?.data?.upload_url;
|
const preSignedUrl = response?.data?.upload_url;
|
||||||
|
|
||||||
if (!preSignedUrl) {
|
if (!preSignedUrl) {
|
||||||
@ -115,9 +122,9 @@ const customRequest = async (option) => {
|
|||||||
}
|
}
|
||||||
console.log('preSignedUrl', preSignedUrl);
|
console.log('preSignedUrl', preSignedUrl);
|
||||||
// 2. 使用预签名URL上传文件
|
// 2. 使用预签名URL上传文件
|
||||||
const blob = new Blob([fileItem.file], { type: fileItem.file.type });
|
const blob = new Blob([file], { type: file.type });
|
||||||
await axios.put(preSignedUrl, blob, {
|
await axios.put(preSignedUrl, blob, {
|
||||||
headers: { 'Content-Type': fileItem.file.type },
|
headers: { 'Content-Type': file.type },
|
||||||
});
|
});
|
||||||
|
|
||||||
onSuccess(JSON.stringify(response));
|
onSuccess(JSON.stringify(response));
|
||||||
|
|||||||
@ -1,20 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-upload
|
<Upload
|
||||||
:custom-request="customRequest"
|
:customRequest="customRequest"
|
||||||
list-type="picture-card"
|
listType="picture-card"
|
||||||
action="/"
|
action="/"
|
||||||
:limit="limit"
|
:maxCount="limit"
|
||||||
:fileList="fileList"
|
:fileList="fileList"
|
||||||
image-preview
|
:showUploadList="{ showPreviewIcon: true, showRemoveIcon: true }"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
@success="handleSuccess"
|
@preview="handlePreview"
|
||||||
@error="handleError"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Upload, message } from 'ant-design-vue';
|
||||||
import { fetchImageUploadFile } from '@/api/all';
|
import { fetchImageUploadFile } from '@/api/all';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
@ -72,8 +71,14 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let previousFileListLength = 0;
|
let previousFileListLength = 0;
|
||||||
//删除图片
|
const handlePreview = (file) => {
|
||||||
const onChange = (fileList) => {
|
console.log('Preview file:', file);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (info) => {
|
||||||
|
const { fileList } = info;
|
||||||
|
|
||||||
|
// 如果删除了文件
|
||||||
if (fileList.length < previousFileListLength) {
|
if (fileList.length < previousFileListLength) {
|
||||||
if (props.limit === 1) {
|
if (props.limit === 1) {
|
||||||
if (fileList.length === 0) {
|
if (fileList.length === 0) {
|
||||||
@ -89,19 +94,26 @@ const onChange = (fileList) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理上传成功的文件
|
||||||
|
if (info.file.status === 'done' && info.file.response) {
|
||||||
|
handleSuccess(info.file);
|
||||||
|
} else if (info.file.status === 'error') {
|
||||||
|
handleError(info.file.error);
|
||||||
|
}
|
||||||
|
|
||||||
previousFileListLength = fileList.length;
|
previousFileListLength = fileList.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
const beforeUpload = (file, files) => {
|
const beforeUpload = (file, files) => {
|
||||||
if (props.limit > 0 && files.length >= props.limit) {
|
if (props.limit > 0 && files.length >= props.limit) {
|
||||||
Message.warning(`最多只能上传 ${props.limit} 张图片`);
|
message.warning(`最多只能上传 ${props.limit} 张图片`);
|
||||||
return false; // 阻止上传
|
return false; // 阻止上传
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleError = (error) => {
|
const handleError = (error) => {
|
||||||
Message.error('上传失败');
|
message.error('上传失败');
|
||||||
console.error(error);
|
console.error(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button, Result } from 'ant-design-vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -10,7 +10,7 @@ const back = () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<a-result class="result" status="404" subtitle="页面跑路了" />
|
<Result class="result" status="404" sub-title="页面跑路了" />
|
||||||
<div class="operation-row flex justify-center">
|
<div class="operation-row flex justify-center">
|
||||||
<Button key="back" type="primary" @click="back">返回</Button>
|
<Button key="back" type="primary" @click="back">返回</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -22,8 +22,10 @@ const back = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -95px;
|
transform: translate(-50%, -50%);
|
||||||
margin-top: -121px;
|
padding: 32px 32px 24px;
|
||||||
text-align: center;
|
// margin-left: -95px;
|
||||||
|
// margin-top: -121px;
|
||||||
|
// text-align: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -8,42 +8,42 @@
|
|||||||
width: 560px;
|
width: 560px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 0 2px 0 16px;
|
padding: 0 2px 0 16px;
|
||||||
border-radius: 50px;
|
border-radius: 50px !important;
|
||||||
background: rgba(255, 255, 255, 0.6);
|
background-color: rgba(255, 255, 255, 0.6) !important;
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
border-color: #fff;
|
border-color: #fff !important;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
&.ant-input-affix-wrapper-focused {
|
&.ant-input-affix-wrapper-focused {
|
||||||
border-color: #6d4cfe;
|
border-color: #6d4cfe !important;
|
||||||
caret-color: #6d4cfe;
|
caret-color: #6d4cfe !important;
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #6d4cfe;
|
border-color: #6d4cfe !important;
|
||||||
}
|
}
|
||||||
.ant-input-suffix {
|
.ant-input-suffix {
|
||||||
margin-inline-start: 0;
|
margin-inline-start: 0 !important;
|
||||||
}
|
}
|
||||||
.ant-input {
|
.ant-input {
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
background-color: transparent;
|
background-color: transparent !important;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
font-family: $font-family-regular;
|
font-family: $font-family-regular;
|
||||||
color: #211f24;
|
color: #211f24;
|
||||||
font-size: 12px;
|
font-size: 12px !important;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: #939499;
|
color: #939499 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
&::after {
|
&::after {
|
||||||
border-width: 1px;
|
border-width: 1px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,13 +10,11 @@
|
|||||||
<div class="agent-entry mx-16px" :class="isAgentRoute ? 'agent' : ''" @click="handleAgentClick"></div>
|
<div class="agent-entry mx-16px" :class="isAgentRoute ? 'agent' : ''" @click="handleAgentClick"></div>
|
||||||
|
|
||||||
<!-- 头像设置 -->
|
<!-- 头像设置 -->
|
||||||
<a-dropdown trigger="click" class="layout-avatar-dropdown">
|
<Dropdown trigger="click" overlayClassName="layout-avatar-dropdown">
|
||||||
<a-avatar class="cursor-pointer" :size="32">
|
<img alt="avatar" src="@/assets/avatar.svg" class="cursor-pointer w-32px h-32px rounded-50%" />
|
||||||
<img alt="avatar" src="@/assets/avatar.svg" />
|
<template #overlay>
|
||||||
</a-avatar>
|
<Menu>
|
||||||
<template #content>
|
<MenuItem>
|
||||||
<div>
|
|
||||||
<a-doption>
|
|
||||||
<div class="h-full flex justify-between items-center w-100%" @click="setServerMenu">
|
<div class="h-full flex justify-between items-center w-100%" @click="setServerMenu">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="icon1" class="w-16px h-16px mr-8px" />
|
<img :src="icon1" class="w-16px h-16px mr-8px" />
|
||||||
@ -24,19 +22,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<icon-right size="12" />
|
<icon-right size="12" />
|
||||||
</div>
|
</div>
|
||||||
</a-doption>
|
</MenuItem>
|
||||||
<a-dsubmenu value="option-1" position="lt" trigger="hover" class="enterprises-dsubmenu">
|
<MenuItem>
|
||||||
<a-doption class="enterprises-doption">
|
<SubMenu value="option-1" position="lt" trigger="hover" popupClassName="enterprises-dsubmenu">
|
||||||
<div class="flex justify-between w-100% h-full items-center">
|
<template #title>
|
||||||
<div class="flex items-center">
|
<div class="flex justify-between w-100% h-full items-center">
|
||||||
<img :src="icon3" class="w-16px h-16px mr-8px" />
|
<div class="flex items-center">
|
||||||
<span>切换企业账号</span>
|
<img :src="icon3" class="w-16px h-16px mr-8px" />
|
||||||
|
<span>切换企业账号</span>
|
||||||
|
</div>
|
||||||
|
<icon-right size="12" />
|
||||||
</div>
|
</div>
|
||||||
<icon-right size="12" />
|
</template>
|
||||||
</div>
|
<MenuItem
|
||||||
</a-doption>
|
|
||||||
<template #content>
|
|
||||||
<a-doption
|
|
||||||
v-for="(item, index) in enterprises"
|
v-for="(item, index) in enterprises"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="rounded-8px hover:bg-#F2F3F5"
|
class="rounded-8px hover:bg-#F2F3F5"
|
||||||
@ -49,10 +47,10 @@
|
|||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<icon-check v-if="enterpriseInfo?.id === item.id" size="16" />
|
<icon-check v-if="enterpriseInfo?.id === item.id" size="16" />
|
||||||
</div>
|
</div>
|
||||||
</a-doption>
|
</MenuItem>
|
||||||
</template>
|
</SubMenu>
|
||||||
</a-dsubmenu>
|
</MenuItem>
|
||||||
<a-doption>
|
<MenuItem>
|
||||||
<div class="flex justify-between w-100% h-full items-center" @click="clickExit">
|
<div class="flex justify-between w-100% h-full items-center" @click="clickExit">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img :src="icon2" class="w-16px h-16px mr-8px" />
|
<img :src="icon2" class="w-16px h-16px mr-8px" />
|
||||||
@ -60,10 +58,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<icon-right size="12" />
|
<icon-right size="12" />
|
||||||
</div>
|
</div>
|
||||||
</a-doption>
|
</MenuItem>
|
||||||
</div>
|
</Menu>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</Dropdown>
|
||||||
|
|
||||||
<ExitAccountModal ref="exitAccountModalRef" />
|
<ExitAccountModal ref="exitAccountModalRef" />
|
||||||
<DownloadCenterModal ref="downloadCenterModalRef" />
|
<DownloadCenterModal ref="downloadCenterModalRef" />
|
||||||
@ -71,6 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { Dropdown, Menu, MenuItem, SubMenu } from 'ant-design-vue';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
import { useSidebarStore } from '@/stores/modules/side-bar';
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
||||||
@ -137,35 +136,51 @@ const handleAgentClick = () => {
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.layout-avatar-dropdown,
|
.layout-avatar-dropdown,
|
||||||
.enterprises-dsubmenu {
|
.enterprises-dsubmenu {
|
||||||
.arco-dropdown {
|
.ant-dropdown-menu {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid var(--BG-300, #e6e6e8);
|
border: 1px solid var(--BG-300, #e6e6e8);
|
||||||
background: var(--BG-white, #fff);
|
background: var(--BG-white, #fff);
|
||||||
padding: 12px 0px;
|
padding: 12px 0px;
|
||||||
.arco-dropdown-option {
|
.ant-dropdown-menu-item {
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
&-content {
|
|
||||||
|
.ant-dropdown-menu-title-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px 24px;
|
padding: 10px 24px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.menu-item-text {
|
.ant-dropdown-menu-submenu {
|
||||||
color: var(--Text-2, #3c4043);
|
width: 100%;
|
||||||
font-family: $font-family-regular;
|
.ant-dropdown-menu-submenu-title {
|
||||||
font-size: 16px;
|
padding: 0;
|
||||||
font-style: normal;
|
&:hover {
|
||||||
font-weight: 400;
|
background: none;
|
||||||
line-height: 22px;
|
}
|
||||||
|
.ant-dropdown-menu-title-content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-dropdown-menu-submenu-arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.arco-dropdown-option-content {
|
.menu-item-text {
|
||||||
|
color: var(--Text-2, #3c4043);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.ant-dropdown-menu-title-content {
|
||||||
border-radius: 8px !important;
|
border-radius: 8px !important;
|
||||||
}
|
}
|
||||||
&:not(.arco-dropdown-option-disabled):hover {
|
&:not(.ant-dropdown-menu-item):hover {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
.arco-dropdown-option-content {
|
.ant-dropdown-menu-title-content {
|
||||||
background: var(--BG-200, #f2f3f5);
|
background: var(--BG-200, #f2f3f5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,29 +190,29 @@ const handleAgentClick = () => {
|
|||||||
.layout-avatar-dropdown,
|
.layout-avatar-dropdown,
|
||||||
.enterprises-dsubmenu {
|
.enterprises-dsubmenu {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
.arco-dropdown {
|
.ant-dropdown-menu {
|
||||||
padding: 12px 4px;
|
padding: 12px 4px;
|
||||||
.arco-dropdown-option {
|
.ant-dropdown-menu-item {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
&-content {
|
.ant-dropdown-menu-title-content {
|
||||||
padding: 0 12px !important;
|
padding: 0 12px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.arco-dropdown-option-suffix {
|
.ant-dropdown-option-suffix {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.enterprises-doption {
|
// .enterprises-doption {
|
||||||
.arco-dropdown-option-content {
|
// .ant-dropdown-menu-title-content {
|
||||||
padding: 0 !important;
|
// padding: 0 !important;
|
||||||
border-radius: 8px;
|
// border-radius: 8px;
|
||||||
}
|
// }
|
||||||
&:not(.arco-dropdown-option-disabled):hover {
|
// &:not(.ant-dropdown-option-disabled):hover {
|
||||||
background-color: transparent;
|
// background-color: transparent;
|
||||||
.arco-dropdown-option-content {
|
// .ant-dropdown-menu-title-content {
|
||||||
background: var(--BG-200, #f2f3f5);
|
// background: var(--BG-200, #f2f3f5);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
10
src/styles/components/ant-switch.scss
Normal file
10
src/styles/components/ant-switch.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.ant-switch {
|
||||||
|
&.ant-switch-checked {
|
||||||
|
background: $color-primary;
|
||||||
|
&:not(ant-switch-disabled) {
|
||||||
|
&:hover {
|
||||||
|
background: $color-primary !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,3 +24,4 @@
|
|||||||
@import './ant-tabs.scss';
|
@import './ant-tabs.scss';
|
||||||
@import "./ant-notification.scss";
|
@import "./ant-notification.scss";
|
||||||
@import "./ant-tag.scss";
|
@import "./ant-tag.scss";
|
||||||
|
@import "./ant-switch.scss";
|
||||||
@ -14,8 +14,8 @@
|
|||||||
</Input>
|
</Input>
|
||||||
<div v-for="(item, index) in list" :key="index">
|
<div v-for="(item, index) in list" :key="index">
|
||||||
<p class="span-title w-fit mb-16px">{{ item.name }}</p>
|
<p class="span-title w-fit mb-16px">{{ item.name }}</p>
|
||||||
<a-row class="grid-demo" :gutter="[20, 16]" v-if="item.agent_products.length > 0">
|
<Row class="grid-demo" :gutter="[20, 16]" v-if="item.agent_products.length > 0">
|
||||||
<a-col :xs="24" :sm="12" :md="8" :lg="5" :xl="6" :xxl="4" v-for="(product, k) in item.agent_products" :key="k">
|
<Col :xs="24" :sm="12" :md="8" :lg="5" :xl="6" :xxl="4" v-for="(product, k) in item.agent_products" :key="k">
|
||||||
<div class="card-container cursor-pointer !h-252px" @click="goDetail(product?.type, product?.id)">
|
<div class="card-container cursor-pointer !h-252px" @click="goDetail(product?.type, product?.id)">
|
||||||
<div class="card-image h-120px w-100% bg-cover bg-center mb-8px" v-image-main-color="product.image_url">
|
<div class="card-image h-120px w-100% bg-cover bg-center mb-8px" v-image-main-color="product.image_url">
|
||||||
<img class="object-contain h-full w-100%" :src="product?.image_url" />
|
<img class="object-contain h-full w-100%" :src="product?.image_url" />
|
||||||
@ -56,8 +56,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
|
|
||||||
<NoData v-else />
|
<NoData v-else />
|
||||||
</div>
|
</div>
|
||||||
@ -65,7 +65,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Input } from 'ant-design-vue';
|
import { Input, Row, Col } from 'ant-design-vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { getAgentList } from '@/api/all/agent';
|
import { getAgentList } from '@/api/all/agent';
|
||||||
import { formatNumberShow } from '@/utils/tools';
|
import { formatNumberShow } from '@/utils/tools';
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<a-form :model="formData" ref="formRef" layout="vertical">
|
<Form :model="formData" ref="formRef" layout="vertical">
|
||||||
<a-form-item
|
<FormItem
|
||||||
v-for="(field, index) in formFields"
|
v-for="(field, index) in formFields"
|
||||||
:key="index"
|
:key="index"
|
||||||
:label="field.props.label"
|
:label="field.props.label"
|
||||||
:field="field.props.name"
|
:name="field.props.name"
|
||||||
:rules="field.props.rules"
|
:rules="field.props.rules"
|
||||||
:tooltip="field.props.tip"
|
:tooltip="field.props.tip"
|
||||||
>
|
>
|
||||||
@ -21,9 +21,6 @@
|
|||||||
v-model:value="formData[field.props.name]"
|
v-model:value="formData[field.props.name]"
|
||||||
:placeholder="field?.props?.placeholder"
|
:placeholder="field?.props?.placeholder"
|
||||||
/>
|
/>
|
||||||
<!-- <a-color-picker v-if="field.type === 'color_picker'"
|
|
||||||
style="width: 500px; height: 200px"
|
|
||||||
v-model="formData[field.props.name]" /> -->
|
|
||||||
<ImageUpload
|
<ImageUpload
|
||||||
v-if="field.type == 'upload_image'"
|
v-if="field.type == 'upload_image'"
|
||||||
v-model="formData[field.props.name]"
|
v-model="formData[field.props.name]"
|
||||||
@ -43,8 +40,8 @@
|
|||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</Option>
|
</Option>
|
||||||
</Select>
|
</Select>
|
||||||
</a-form-item>
|
</FormItem>
|
||||||
</a-form>
|
</Form>
|
||||||
<Button class="submit-btn" type="primary" :disabled="loading" @click="handleSubmit">提交执行</Button>
|
<Button class="submit-btn" type="primary" :disabled="loading" @click="handleSubmit">提交执行</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -52,9 +49,10 @@
|
|||||||
import { defineProps, defineEmits } from 'vue';
|
import { defineProps, defineEmits } from 'vue';
|
||||||
import ImageUpload from '@/components/upload/ImageUpload.vue';
|
import ImageUpload from '@/components/upload/ImageUpload.vue';
|
||||||
import FileUpload from '@/components/upload/FileUpload.vue';
|
import FileUpload from '@/components/upload/FileUpload.vue';
|
||||||
import { Button, Input, Select } from 'ant-design-vue';
|
import { Button, Input, Select, Row, Col, Form } from 'ant-design-vue';
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
const { Item: FormItem } = Form;
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formFields: {
|
formFields: {
|
||||||
|
|||||||
@ -42,15 +42,14 @@
|
|||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="trigger-container">
|
<div class="trigger-container">
|
||||||
<a-trigger
|
<Dropdown
|
||||||
mouse-leave-delay="200"
|
:mouseLeaveDelay="200"
|
||||||
position="top"
|
placement="top"
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
:auto-fit-position="false"
|
:overlayStyle="{ width: 'auto' }"
|
||||||
:unmount-on-close="true"
|
|
||||||
>
|
>
|
||||||
<SvgIcon size="12" name="svg-more" class="icon-more" />
|
<SvgIcon size="12" name="svg-more" class="icon-more" />
|
||||||
<template #content>
|
<template #overlay>
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="history-item-dropdown">
|
<div class="history-item-dropdown">
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
@ -61,18 +60,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
<SvgIcon size="12" name="svg-delete" class="icon color-#6D4CFE" />
|
<SvgIcon size="12" name="svg-delete" class="icon color-#6D4CFE" />
|
||||||
<a-popconfirm
|
<Popconfirm
|
||||||
content="你确认删除该历史对话吗"
|
content="你确认删除该历史对话吗"
|
||||||
@ok="deleteHistory(item.id, index)"
|
@confirm="deleteHistory(item.id, index)"
|
||||||
type="error"
|
ok-text="确定"
|
||||||
|
cancel-text="取消"
|
||||||
>
|
>
|
||||||
<div class="text delete">删除</div>
|
<div class="text delete">删除</div>
|
||||||
</a-popconfirm>
|
</Popconfirm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-trigger>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -95,7 +95,7 @@
|
|||||||
<DynamicForm :formFields="formFields.form" :formData="formData" :loading="loading" @submit="handleSubmit" />
|
<DynamicForm :formFields="formFields.form" :formData="formData" :loading="loading" @submit="handleSubmit" />
|
||||||
</div>
|
</div>
|
||||||
<div class="res h-full">
|
<div class="res h-full">
|
||||||
<a-spin v-if="loading" class="spin-center" tip="生成中。。。" />
|
<Spin v-if="loading" class="spin-center" tip="生成中。。。" />
|
||||||
<div
|
<div
|
||||||
class="markdown-container"
|
class="markdown-container"
|
||||||
v-if="workFlowRes.output != '' && loading === false"
|
v-if="workFlowRes.output != '' && loading === false"
|
||||||
@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive } from 'vue';
|
import { ref, reactive } from 'vue';
|
||||||
import { Modal, Tooltip, message } from 'ant-design-vue';
|
import { Modal, Tooltip, message, Popconfirm, Spin, Dropdown } from 'ant-design-vue';
|
||||||
import DynamicForm from './components/DynamicForm.vue';
|
import DynamicForm from './components/DynamicForm.vue';
|
||||||
import {
|
import {
|
||||||
executeWorkFlow,
|
executeWorkFlow,
|
||||||
|
|||||||
@ -134,9 +134,9 @@
|
|||||||
<p class="!mr-16px w-48px cts relative top-2px">原始来源</p>
|
<p class="!mr-16px w-48px cts relative top-2px">原始来源</p>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div v-for="item in topicInfo.industry_topic_sources" :key="item" class="mb-18px flex items-center">
|
<div v-for="item in topicInfo.industry_topic_sources" :key="item" class="mb-18px flex items-center">
|
||||||
<a-link style="background-color: initial" :href="item.link" target="_blank" class="!text-12px">{{
|
<Link :href="item.link" target="_blank" class="!text-12px">{{
|
||||||
item.title
|
item.title
|
||||||
}}</a-link>
|
}}</Link>
|
||||||
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -153,7 +153,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import topHeader from './topHeader.vue';
|
import topHeader from './topHeader.vue';
|
||||||
import { Modal, Button, Tooltip, Space, Table, Tag } from 'ant-design-vue';
|
import { Modal, Button, Tooltip, Space, Table, Tag, Typography } from 'ant-design-vue';
|
||||||
|
const { Link } = Typography;
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { fetchIndustriesTree, fetchIndustryTopics, fetchIndustryTopicDetail } from '@/api/all/index';
|
import { fetchIndustriesTree, fetchIndustryTopics, fetchIndustryTopicDetail } from '@/api/all/index';
|
||||||
import star1 from '@/assets/img/hottranslation/star-fill1.png';
|
import star1 from '@/assets/img/hottranslation/star-fill1.png';
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.slotName === 'volumeRate'" #customRender="{ record }">
|
<template v-else-if="column.slotName === 'volumeRate'" #customRender="{ record }">
|
||||||
<a-statistic :value="record.volume_rate * 100" />%
|
<Statistic :value="record.volume_rate * 100" />%
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.titleSlotName === 'hotTitle'" #title>
|
<template v-else-if="column.titleSlotName === 'hotTitle'" #title>
|
||||||
<Space>
|
<Space>
|
||||||
@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import topHeader from './topHeader.vue';
|
import topHeader from './topHeader.vue';
|
||||||
import { Tooltip, Space, Table } from 'ant-design-vue';
|
import { Tooltip, Space, Table, Statistic } from 'ant-design-vue';
|
||||||
import { fetchFocusBrandsList, fetchEventDynamicsList } from '@/api/all/index';
|
import { fetchFocusBrandsList, fetchEventDynamicsList } from '@/api/all/index';
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import star1 from '@/assets/img/hottranslation/star-fill1.png';
|
import star1 from '@/assets/img/hottranslation/star-fill1.png';
|
||||||
|
|||||||
@ -250,9 +250,9 @@
|
|||||||
<p class="!mr-16px w-83px cts relative top-2px">原始来源</p>
|
<p class="!mr-16px w-83px cts relative top-2px">原始来源</p>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div v-for="item in topicInfo.industry_new_keyword_sources" :key="item" class="mb-18px flex items-center">
|
<div v-for="item in topicInfo.industry_new_keyword_sources" :key="item" class="mb-18px flex items-center">
|
||||||
<a-link style="background-color: initial" :href="item.link" target="_blank" class="!text-12px">{{
|
<Link :href="item.link" target="_blank" class="!text-12px">{{
|
||||||
item.title
|
item.title
|
||||||
}}</a-link>
|
}}</Link>
|
||||||
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -269,7 +269,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import topHeader from './topHeader.vue';
|
import topHeader from './topHeader.vue';
|
||||||
import { Checkbox, Modal, Button, Tooltip, Space, Table, Tag } from 'ant-design-vue';
|
import { Modal, Button, Tooltip, Space, Table, Tag, Typography } from 'ant-design-vue';
|
||||||
|
const { Link } = Typography;
|
||||||
import {
|
import {
|
||||||
fetchKeywordTrendsList,
|
fetchKeywordTrendsList,
|
||||||
fetchIndustryEmotions,
|
fetchIndustryEmotions,
|
||||||
|
|||||||
@ -108,9 +108,9 @@
|
|||||||
<p class="cts !mr-16px flex-shrink-0 w-60px">原始来源</p>
|
<p class="cts !mr-16px flex-shrink-0 w-60px">原始来源</p>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div v-for="item in topicInfo.user_pain_point_sources" :key="item" class="mb-18px flex items-center">
|
<div v-for="item in topicInfo.user_pain_point_sources" :key="item" class="mb-18px flex items-center">
|
||||||
<a-link style="background-color: initial" :href="item.link" target="_blank" class="!text-12px">{{
|
<Link :href="item.link" target="_blank" class="!text-12px">{{
|
||||||
item.title
|
item.title
|
||||||
}}</a-link>
|
}}</Link>
|
||||||
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
<img src="@/assets/img/hottranslation/xhs.png" width="16" height="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -127,7 +127,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import topHeader from './topHeader.vue';
|
import topHeader from './topHeader.vue';
|
||||||
import { Modal, Button, Tooltip, Space, Table, Tag } from 'ant-design-vue';
|
import { Modal, Button, Tooltip, Space, Table, Tag, Typography } from 'ant-design-vue';
|
||||||
|
const { Link } = Typography;
|
||||||
import { fetchUserPainPointsDetail, fetchUserPainPointsList } from '@/api/all/index';
|
import { fetchUserPainPointsDetail, fetchUserPainPointsList } from '@/api/all/index';
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import top1 from '@/assets/img/captcha/top1.svg';
|
import top1 from '@/assets/img/captcha/top1.svg';
|
||||||
|
|||||||
@ -65,9 +65,9 @@
|
|||||||
<Space class="text-12px color-#737478 justify-start items-center">
|
<Space class="text-12px color-#737478 justify-start items-center">
|
||||||
<Checkbox v-model:checked="hasCheck" class="!text-12px mr-8px"></Checkbox>
|
<Checkbox v-model:checked="hasCheck" class="!text-12px mr-8px"></Checkbox>
|
||||||
<span class="text-12px color-#737478">{{ isLogin ? '登录' : '注册' }}即代表同意</span>
|
<span class="text-12px color-#737478">{{ isLogin ? '登录' : '注册' }}即代表同意</span>
|
||||||
<a-link href="link" class="form-link color-#211F24" target="_blank">用户协议</a-link>
|
<Link href="link" class="form-link color-#211F24" target="_blank">用户协议</Link>
|
||||||
<span class="text-12px color-#737478">和</span>
|
<span class="text-12px color-#737478">和</span>
|
||||||
<a-link href="link" class="form-link color-#211f24" target="_blank">隐私政策</a-link>
|
<Link href="link" class="form-link color-#211f24" target="_blank">隐私政策</Link>
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
@ -87,13 +87,13 @@
|
|||||||
<span style="text-align: left; width: 100%">选择账号</span>
|
<span style="text-align: left; width: 100%">选择账号</span>
|
||||||
</template>
|
</template>
|
||||||
<div class="account-bind-container">
|
<div class="account-bind-container">
|
||||||
<a-card :bordered="false" class="bind-card">
|
<Card :bordered="false" class="bind-card">
|
||||||
<div class="bind-header">
|
<div class="bind-header">
|
||||||
<a-typography-text class="mobile-number">{{ mobileNumber }} 已在以下企业绑定了账号</a-typography-text>
|
<Typography.Text class="mobile-number">{{ mobileNumber }} 已在以下企业绑定了账号</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-list :bordered="false" :split="false" class="account-list">
|
<List :bordered="false" :split="false" class="account-list">
|
||||||
<a-list-item
|
<List.Item
|
||||||
v-for="(account, index) in accounts"
|
v-for="(account, index) in accounts"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="account-item"
|
class="account-item"
|
||||||
@ -104,17 +104,17 @@
|
|||||||
}"
|
}"
|
||||||
@click="selectAccount(account, index)"
|
@click="selectAccount(account, index)"
|
||||||
>
|
>
|
||||||
<a-list-item-meta>
|
<List.Item.Meta>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div style="display: flex; align-items: center; gap: 12px">
|
<div style="display: flex; align-items: center; gap: 12px">
|
||||||
<Checkbox :checked="selectedAccountIndex === index" />
|
<Checkbox :checked="selectedAccountIndex === index" />
|
||||||
<a-typography-text>{{ account.name || '-' }}</a-typography-text>
|
<Typography.Text>{{ account.name || '-' }}</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-list-item-meta>
|
</List.Item.Meta>
|
||||||
</a-list-item>
|
</List.Item>
|
||||||
</a-list>
|
</List>
|
||||||
</a-card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@ -125,7 +125,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Checkbox, Modal, Button, Form, FormItem, Input, Space, message } from 'ant-design-vue';
|
import { Checkbox, Modal, Button, Form, FormItem, Input, Space, message, Typography, Card, List } from 'ant-design-vue';
|
||||||
|
const { Link } = Typography;
|
||||||
import PuzzleVerification from './components/PuzzleVerification.vue';
|
import PuzzleVerification from './components/PuzzleVerification.vue';
|
||||||
import { fetchLoginCaptCha, fetchAuthorizationsCaptcha, fetchProfileInfo } from '@/api/all/login';
|
import { fetchLoginCaptCha, fetchAuthorizationsCaptcha, fetchProfileInfo } from '@/api/all/login';
|
||||||
import { joinEnterpriseByInviteCode } from '@/api/all';
|
import { joinEnterpriseByInviteCode } from '@/api/all';
|
||||||
|
|||||||
@ -69,6 +69,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bind-header {
|
.bind-header {
|
||||||
@ -111,6 +112,9 @@
|
|||||||
background-color: rgba(109, 76, 254, 0.1);
|
background-color: rgba(109, 76, 254, 0.1);
|
||||||
box-shadow: 0 2px 4px 0 rgba(109, 76, 254, 0.5);
|
box-shadow: 0 2px 4px 0 rgba(109, 76, 254, 0.5);
|
||||||
}
|
}
|
||||||
|
:deep(.ant-list-item-meta-title) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-item:deep(.arco-list-item-main) {
|
.account-item:deep(.arco-list-item-main) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<Table.Column title="用户信息" dataIndex="info">
|
<Table.Column title="用户信息" dataIndex="info">
|
||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
<div class="pt-3px pb-3px">
|
<div class="pt-3px pb-3px">
|
||||||
<a-avatar :image-url="record.head_image" :size="32" />
|
<Avatar :src="record.head_image" :size="32" />
|
||||||
{{ record.name || '-' }}
|
{{ record.name || '-' }}
|
||||||
<icon-edit size="13" class="ml-8px" @click="openEditInfoModal" />
|
<icon-edit size="13" class="ml-8px" @click="openEditInfoModal" />
|
||||||
</div>
|
</div>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
>
|
>
|
||||||
<FormItem name="head_image" label="头像">
|
<FormItem name="head_image" label="头像">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<a-avatar :image-url="userInfoForm.file_url" :size="48" />
|
<Avatar :src="userInfoForm.file_url" :size="48" />
|
||||||
<span class="upload-button" @click="triggerFileInput">
|
<span class="upload-button" @click="triggerFileInput">
|
||||||
<input
|
<input
|
||||||
ref="uploadInputRef"
|
ref="uploadInputRef"
|
||||||
@ -85,7 +85,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Button, Form, FormItem, Input, Table, message } from 'ant-design-vue';
|
import { Button, Form, FormItem, Input, Table, message, Avatar } from 'ant-design-vue';
|
||||||
import Container from '@/components/container.vue';
|
import Container from '@/components/container.vue';
|
||||||
import Modal from '@/components/modal.vue';
|
import Modal from '@/components/modal.vue';
|
||||||
import PuzzleVerification from '@/views/components/login/components/PuzzleVerification.vue';
|
import PuzzleVerification from '@/views/components/login/components/PuzzleVerification.vue';
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<div class="m-auto mt-24px max-w-1000px">
|
<div class="m-auto mt-24px max-w-1000px">
|
||||||
<Container title="推荐产品" class="container-body">
|
<Container title="推荐产品" class="container-body">
|
||||||
<div class="grid grid-cols-3 gap-20px">
|
<div class="grid grid-cols-3 gap-20px">
|
||||||
<Product v-for="product in products" :key="product.id" :product="product" @refresh="getProductList" />
|
<!-- <Product v-for="product in products" :key="product.id" :product="product" @refresh="getProductList" /> -->
|
||||||
</div>
|
</div>
|
||||||
<NoData v-if="products.length === 0" />
|
<NoData v-if="products.length === 0" />
|
||||||
</Container>
|
</Container>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Container from '@/components/container.vue';
|
import Container from '@/components/container.vue';
|
||||||
import Product from '@/views/components/workplace/modules/product.vue';
|
// import Product from '@/views/components/workplace/modules/product.vue';
|
||||||
import Case from '@/views/components/workplace/modules/case.vue';
|
import Case from '@/views/components/workplace/modules/case.vue';
|
||||||
import { fetchProductList, fetchSuccessCaseList } from '@/api/all/index';
|
import { fetchProductList, fetchSuccessCaseList } from '@/api/all/index';
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
|||||||
@ -6,12 +6,11 @@
|
|||||||
<Tag v-if="props.product.status === Status.Disable" class="status status-disable">未开通</Tag>
|
<Tag v-if="props.product.status === Status.Disable" class="status status-disable">未开通</Tag>
|
||||||
<Tag v-if="props.product.status === Status.EXPIRED" class="status status-expired">已到期</Tag>
|
<Tag v-if="props.product.status === Status.EXPIRED" class="status status-expired">已到期</Tag>
|
||||||
<Tag v-if="props.product.status === Status.TRIAL_ENDS" class="status status-expired">试用结束</Tag>
|
<Tag v-if="props.product.status === Status.TRIAL_ENDS" class="status status-expired">试用结束</Tag>
|
||||||
<a-countdown
|
<Countdown
|
||||||
v-if="props.product.status === Status.ON_TRIAL"
|
v-if="props.product.status === Status.ON_TRIAL"
|
||||||
class="status-on-trill"
|
class="status-on-trill"
|
||||||
title="试用中"
|
title="试用中"
|
||||||
:value="1000 * (props.product.expired_at ?? 0)"
|
:value="1000 * (props.product.expired_at ?? 0)"
|
||||||
:now="now()"
|
|
||||||
format="D天H时m分s秒"
|
format="D天H时m分s秒"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -60,9 +59,10 @@
|
|||||||
>
|
>
|
||||||
联系客服
|
联系客服
|
||||||
</Button>
|
</Button>
|
||||||
<a-popconfirm focusLock title="试用产品" content="确定试用该产品吗?" @ok="handleTrial(props.product.id)">
|
<Popconfirm title="试用产品" ok-text="确定" cancel-text="取消" @confirm="handleTrial(props.product.id)">
|
||||||
|
<template #description>确定试用该产品吗?</template>
|
||||||
<Button v-if="props.product.status === Status.Disable" size="small" type="default" ghost> 免费试用7天 </Button>
|
<Button v-if="props.product.status === Status.Disable" size="small" type="default" ghost> 免费试用7天 </Button>
|
||||||
</a-popconfirm>
|
</Popconfirm>
|
||||||
</div>
|
</div>
|
||||||
<CustomerServiceModal v-model:open="visible" centered/>
|
<CustomerServiceModal v-model:open="visible" centered/>
|
||||||
</div>
|
</div>
|
||||||
@ -73,7 +73,8 @@ import { now } from '@vueuse/core';
|
|||||||
import { trialProduct } from '@/api/all';
|
import { trialProduct } from '@/api/all';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import CustomerServiceModal from '@/components/customer-service-modal.vue';
|
import CustomerServiceModal from '@/components/customer-service-modal.vue';
|
||||||
import { Button, message, Tag } from 'ant-design-vue';
|
import { Button, message, Tag, Statistic, Popconfirm } from 'ant-design-vue';
|
||||||
|
const { Countdown } = Statistic;
|
||||||
|
|
||||||
import { useSidebarStore } from '@/stores/modules/side-bar';
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
@ -177,7 +178,7 @@ const gotoModule = (menuId: number) => {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(255, 245, 222, 1);
|
background: rgba(255, 245, 222, 1);
|
||||||
|
|
||||||
:deep(.arco-statistic-title) {
|
:deep(.ant-statistic-title) {
|
||||||
font-family: $font-family-medium;
|
font-family: $font-family-medium;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -187,7 +188,7 @@ const gotoModule = (menuId: number) => {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-statistic-value) {
|
:deep(.ant-statistic-content) {
|
||||||
font-family: $font-family-medium;
|
font-family: $font-family-medium;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item" v-if="query.audit_status === AuditStatus.Pending">
|
<div class="filter-row-item" v-if="query.audit_status === AuditStatus.Pending">
|
||||||
<span class="label">上传时间</span>
|
<span class="label">上传时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="created_at"
|
v-model="created_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -69,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">审核时间</span>
|
<span class="label">审核时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="audit_started_at"
|
v-model="audit_started_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Input, Select, Space } from 'ant-design-vue';
|
import { Button, Input, Select, Space, DatePicker } from 'ant-design-vue';
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
import { defineEmits, defineProps } from 'vue';
|
import { defineEmits, defineProps } from 'vue';
|
||||||
import { PLATFORMS } from '@/views/material-center/components/finished-products/manuscript/check-list/constants';
|
import { PLATFORMS } from '@/views/material-center/components/finished-products/manuscript/check-list/constants';
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script lang="jsx">
|
<script lang="jsx">
|
||||||
import { Drawer, Image } from '@arco-design/web-vue';
|
import { Drawer, Image } from 'ant-design-vue';
|
||||||
import TextOverTips from '@/components/text-over-tips';
|
import TextOverTips from '@/components/text-over-tips';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/error-img.png';
|
import icon1 from '@/assets/img/error-img.png';
|
||||||
@ -32,12 +32,12 @@ export default {
|
|||||||
return () => (
|
return () => (
|
||||||
<Drawer
|
<Drawer
|
||||||
title="审核列表"
|
title="审核列表"
|
||||||
visible={visible.value}
|
v-model:open={visible.value}
|
||||||
width={420}
|
width={420}
|
||||||
class="check-list-drawer-xt"
|
rootClassName="check-list-drawer-xt"
|
||||||
footer={false}
|
footer={null}
|
||||||
header={false}
|
closable={false}
|
||||||
onCancel={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
<div class="flex justify-between items-center h-56px px-24px">
|
<div class="flex justify-between items-center h-56px px-24px">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@ -61,13 +61,12 @@ export default {
|
|||||||
height={48}
|
height={48}
|
||||||
preview={false}
|
preview={false}
|
||||||
src={item.cover}
|
src={item.cover}
|
||||||
class="!rounded-4px mr-8px"
|
class="!rounded-4px"
|
||||||
fit="cover"
|
|
||||||
v-slots={{
|
v-slots={{
|
||||||
error: () => <img src={icon1} class="w-full h-full" />,
|
error: () => <img src={icon1} class="w-full h-full" />,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 overflow-hidden flex flex-col items-start">
|
<div class="flex-1 overflow-hidden flex flex-col items-start ml-8px">
|
||||||
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
|
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
|
||||||
<p class="cts !text-14px">{`合规程度:${
|
<p class="cts !text-14px">{`合规程度:${
|
||||||
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
|
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
|
||||||
|
|||||||
@ -1,43 +1,41 @@
|
|||||||
.check-list-drawer-xt {
|
.check-list-drawer-xt {
|
||||||
.arco-drawer-mask {
|
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
.ant-drawer-mask {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.arco-drawer {
|
.ant-drawer-body {
|
||||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
overflow: hidden;
|
||||||
.arco-drawer-body {
|
display: flex;
|
||||||
overflow: hidden;
|
flex-direction: column;
|
||||||
display: flex;
|
padding: 0 0 24px;
|
||||||
flex-direction: column;
|
.cts {
|
||||||
padding: 0 0 24px;
|
color: var(--Text-1, #939499);
|
||||||
.cts {
|
|
||||||
color: var(--Text-1, #939499);
|
|
||||||
|
|
||||||
font-family: $font-family-regular;
|
font-family: $font-family-regular;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
&.bold {
|
&.bold {
|
||||||
color: var(--Text-1, #211f24);
|
color: var(--Text-1, #211f24);
|
||||||
font-family: $font-family-medium;
|
font-family: $font-family-medium;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.card-item {
|
}
|
||||||
cursor: pointer;
|
.card-item {
|
||||||
border: 1px solid transparent;
|
cursor: pointer;
|
||||||
transition: all;
|
border: 1px solid transparent;
|
||||||
&:hover {
|
transition: all;
|
||||||
background-color: #e6e6e8;
|
&:hover {
|
||||||
}
|
background-color: #e6e6e8;
|
||||||
&:not(:last-child) {
|
}
|
||||||
margin-bottom: 12px;
|
&:not(:last-child) {
|
||||||
}
|
margin-bottom: 12px;
|
||||||
&.active {
|
}
|
||||||
border-color: #6d4cfe;
|
&.active {
|
||||||
background-color: #f0edff;
|
border-color: #6d4cfe;
|
||||||
:deep(.overflow-text) {
|
background-color: #f0edff;
|
||||||
font-family: $font-family-medium !important;
|
:deep(.overflow-text) {
|
||||||
}
|
font-family: $font-family-medium !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -137,9 +137,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const uploadImage = async (option, action = 'upload') => {
|
const uploadImage = async (option, action = 'upload') => {
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
|
|
||||||
const { name, size, type } = file;
|
const { name, size, type } = file;
|
||||||
const response = await getImagePreSignedUrl({ suffix: getFileExtension(name) });
|
const response = await getImagePreSignedUrl({ suffix: getFileExtension(name) });
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script lang="jsx">
|
<script lang="jsx">
|
||||||
import { Image } from '@arco-design/web-vue';
|
import { Image } from 'ant-design-vue';
|
||||||
import { Swiper, SwiperSlide } from 'swiper/vue';
|
import { Swiper, SwiperSlide } from 'swiper/vue';
|
||||||
import TextOverTips from '@/components/text-over-tips';
|
import TextOverTips from '@/components/text-over-tips';
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ export default {
|
|||||||
height={48}
|
height={48}
|
||||||
preview={false}
|
preview={false}
|
||||||
src={item.cover}
|
src={item.cover}
|
||||||
class="!rounded-4px mr-8px"
|
class="!rounded-4px"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
v-slots={{
|
v-slots={{
|
||||||
error: () => <img src={icon1} class="w-full h-full" />,
|
error: () => <img src={icon1} class="w-full h-full" />,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 overflow-hidden flex flex-col items-start">
|
<div class="flex-1 overflow-hidden flex flex-col items-start ml-8px">
|
||||||
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
|
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
|
||||||
<p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
|
<p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -23,25 +23,23 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-upload
|
<Upload
|
||||||
v-if="files.length < 18"
|
v-if="files.length < 18"
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
action="/"
|
action="/"
|
||||||
draggable
|
:customRequest="(option) => emit('upload', option)"
|
||||||
:custom-request="(option) => emit('upload', option)"
|
|
||||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||||
:show-file-list="false"
|
:showUploadList="false"
|
||||||
multiple
|
multiple
|
||||||
class="!flex !items-center"
|
class="!flex !items-center"
|
||||||
:limit="18 - files.length"
|
|
||||||
>
|
>
|
||||||
<template #upload-button>
|
<template #default>
|
||||||
<div class="upload-box">
|
<div class="upload-box">
|
||||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||||
<span class="cts !color-#211F24">上传图片</span>
|
<span class="cts !color-#211F24">上传图片</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
</Upload>
|
||||||
</VueDraggable>
|
</VueDraggable>
|
||||||
</div>
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -49,7 +47,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { VueDraggable } from 'vue-draggable-plus';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
import { FormItem} from 'ant-design-vue';
|
import { FormItem, Upload } from 'ant-design-vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
files: {
|
files: {
|
||||||
|
|||||||
@ -131,9 +131,7 @@ export default {
|
|||||||
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
|
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
|
||||||
emit('updateVideoInfo', formData.value.videoInfo);
|
emit('updateVideoInfo', formData.value.videoInfo);
|
||||||
|
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
setVideoInfo(file);
|
setVideoInfo(file);
|
||||||
|
|
||||||
const response = await getVideoPreSignedUrl({ suffix: getFileExtension(file.name) });
|
const response = await getVideoPreSignedUrl({ suffix: getFileExtension(file.name) });
|
||||||
@ -164,9 +162,7 @@ export default {
|
|||||||
};
|
};
|
||||||
// 文件上传处理
|
// 文件上传处理
|
||||||
const uploadImage = async (option) => {
|
const uploadImage = async (option) => {
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
|
|
||||||
// 验证文件数量
|
// 验证文件数量
|
||||||
if (formData.value.files?.length >= 18) {
|
if (formData.value.files?.length >= 18) {
|
||||||
|
|||||||
@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">上传时间</span>
|
<span class="label">上传时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="created_at"
|
v-model="created_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -80,7 +80,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Input } from 'ant-design-vue';
|
import { Button, Input, DatePicker } from 'ant-design-vue';
|
||||||
import { defineEmits, defineProps } from 'vue';
|
import { defineEmits, defineProps } from 'vue';
|
||||||
import { CHECK_STATUS } from '@/views/material-center/components/finished-products/manuscript/list/constants';
|
import { CHECK_STATUS } from '@/views/material-center/components/finished-products/manuscript/list/constants';
|
||||||
import CommonSelect from '@/components/common-select';
|
import CommonSelect from '@/components/common-select';
|
||||||
|
|||||||
@ -25,8 +25,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">上传时间</span>
|
<span class="label">上传时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="created_at"
|
v-model:value="created_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits, defineProps, ref, nextTick } from 'vue';
|
import { defineEmits, defineProps, ref, nextTick } from 'vue';
|
||||||
import { Button, Input } from 'ant-design-vue';
|
import { Button, Input, DatePicker } from 'ant-design-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -92,15 +92,14 @@
|
|||||||
<Table.Column :width="80" title="操作" dataIndex="optional">
|
<Table.Column :width="80" title="操作" dataIndex="optional">
|
||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
<Space>
|
<Space>
|
||||||
<a-popconfirm
|
<Popconfirm
|
||||||
content="确定删除吗?"
|
title="确定删除吗?"
|
||||||
type="warning"
|
okText="确认删除"
|
||||||
ok-text="确认删除"
|
cancelText="取消"
|
||||||
cancel-text="取消"
|
@confirm="deleteBrand(record.id)"
|
||||||
@ok="deleteBrand(record.id)"
|
|
||||||
>
|
>
|
||||||
<icon-delete></icon-delete>
|
<icon-delete></icon-delete>
|
||||||
</a-popconfirm>
|
</Popconfirm>
|
||||||
<Button type="outline" class="edit-btn" size="small" @click="handleEdit(record.id)">编辑</Button>
|
<Button type="outline" class="edit-btn" size="small" @click="handleEdit(record.id)">编辑</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
@ -127,7 +126,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, reactive, onMounted } from 'vue';
|
import { ref, computed, reactive, onMounted } from 'vue';
|
||||||
import { IconDelete } from '@arco-design/web-vue/es/icon';
|
import { IconDelete } from '@arco-design/web-vue/es/icon';
|
||||||
import { Button, Modal, Space, Form, FormItem, Pagination, Input, Table, message } from 'ant-design-vue';
|
import { Button, Modal, Space, Form, FormItem, Pagination, Input, Table, message, Popconfirm } from 'ant-design-vue';
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|||||||
@ -37,6 +37,9 @@
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
:deep(.ant-popconfirm-buttons) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.arco-input-wrapper),
|
:deep(.arco-input-wrapper),
|
||||||
:deep(.arco-select-view-single),
|
:deep(.arco-select-view-single),
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">时间筛选</span>
|
<span class="label">时间筛选</span>
|
||||||
<Space class="w-240px">
|
<Space class="w-240px">
|
||||||
<a-range-picker size="medium" allow-clear format="YYYY-MM-DD HH:mm" class="w-100%" />
|
<DatePicker.RangePicker allowClear format="YYYY-MM-DD HH:mm" class="w-100%" />
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -70,7 +70,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { Button, Input, Space, Table, Pagination } from 'ant-design-vue';
|
import { Button, Input, Space, Table, Pagination, DatePicker } from 'ant-design-vue';
|
||||||
|
|
||||||
const pageInfo = reactive({
|
const pageInfo = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">时间筛选</span>
|
<span class="label">时间筛选</span>
|
||||||
<Space class="w-240px">
|
<Space class="w-240px">
|
||||||
<a-range-picker size="medium" allow-clear format="YYYY-MM-DD HH:mm" class="w-100%" />
|
<DatePicker.RangePicker allow-clear format="YYYY-MM-DD HH:mm" class="w-100%" />
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Button, Input, Space, Pagination, Table } from 'ant-design-vue';
|
import { Button, Input, Space, Pagination, Table, DatePicker } from 'ant-design-vue';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
const pageInfo = reactive({
|
const pageInfo = reactive({
|
||||||
|
|||||||
@ -23,8 +23,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">发布日期</span>
|
<span class="label">发布日期</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="published_at"
|
v-model:value="published_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
class="!w-260px"
|
class="!w-260px"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -105,7 +105,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Input, Tooltip, Table, Pagination } from 'ant-design-vue';
|
import { Button, Input, Tooltip, Table, Pagination, DatePicker } from 'ant-design-vue';
|
||||||
import { TABLE_COLUMNS, INITIAL_QUERY, INITIAL_PAGE_INFO } from './constants';
|
import { TABLE_COLUMNS, INITIAL_QUERY, INITIAL_PAGE_INFO } from './constants';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { formatTableField, exactFormatTime, formatNumberShow } from '@/utils/tools';
|
import { formatTableField, exactFormatTime, formatNumberShow } from '@/utils/tools';
|
||||||
|
|||||||
@ -4,20 +4,17 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="card-container">
|
<div class="card-container">
|
||||||
<a-spin
|
<Spin
|
||||||
v-for="(item, index) in dataSource"
|
v-for="(item, index) in dataSource"
|
||||||
:key="index"
|
:key="index"
|
||||||
:loading="isSyncing(item)"
|
:spinning="isSyncing(item)"
|
||||||
tip="更新数据中..."
|
tip="更新数据中..."
|
||||||
class="card-item"
|
:wrapperClassName="`card-item ${isSelected(item) ? 'checked' : ''}`"
|
||||||
:class="{
|
|
||||||
checked: isSelected(item),
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-sync size="24" />
|
<icon-sync size="24" />
|
||||||
</template>
|
</template>
|
||||||
<Checkbox :checked="isSelected(item)" :value="item.id" @change="toggleSelect(item)"></Checkbox>
|
<Checkbox :checked="isSelected(item)" :value="item.id" @change="toggleSelect(item)" class="relative top--2px"></Checkbox>
|
||||||
<div class="ml-8px flex-1">
|
<div class="ml-8px flex-1">
|
||||||
<Tooltip title="点击查看账号详情">
|
<Tooltip title="点击查看账号详情">
|
||||||
<p class="name cursor-pointer hover:!color-#6d4cfe" @click="goDetail(item)">{{ item.name || '-' }}</p>
|
<p class="name cursor-pointer hover:!color-#6d4cfe" @click="goDetail(item)">{{ item.name || '-' }}</p>
|
||||||
@ -121,7 +118,7 @@
|
|||||||
}}</Button>
|
}}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</Spin>
|
||||||
<PauseAccountPatchModal ref="pauseAccountPatchModalRef" @success="emits('update')" />
|
<PauseAccountPatchModal ref="pauseAccountPatchModalRef" @success="emits('update')" />
|
||||||
<ReauthorizeAccountModal ref="reauthorizeAccountModalRef" @update="emits('update')" />
|
<ReauthorizeAccountModal ref="reauthorizeAccountModalRef" @update="emits('update')" />
|
||||||
<AuthorizedAccountModal ref="authorizedAccountModalRef" @update="emits('update')" />
|
<AuthorizedAccountModal ref="authorizedAccountModalRef" @update="emits('update')" />
|
||||||
@ -130,7 +127,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineProps, ref, computed, inject } from 'vue';
|
import { defineProps, ref, computed, inject } from 'vue';
|
||||||
import { Checkbox, Button, Tooltip } from 'ant-design-vue';
|
import { Checkbox, Button, Tooltip, Spin } from 'ant-design-vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { deleteSyncStatus } from '@/api/all/propertyMarketing';
|
import { deleteSyncStatus } from '@/api/all/propertyMarketing';
|
||||||
import { exactFormatTime } from '@/utils/tools';
|
import { exactFormatTime } from '@/utils/tools';
|
||||||
|
|||||||
@ -4,13 +4,17 @@
|
|||||||
// grid-template-rows: repeat(2, 1fr); /* 2行 */
|
// grid-template-rows: repeat(2, 1fr); /* 2行 */
|
||||||
grid-template-columns: repeat(4, 1fr); /* 4列 */
|
grid-template-columns: repeat(4, 1fr); /* 4列 */
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
:deep(.ant-spin-container) {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
.card-item {
|
.card-item {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
// border: 1px solid var(--BG-300, #e6e6e8);
|
// border: 1px solid var(--BG-300, #e6e6e8);
|
||||||
background: var(--BG-white, #fff);
|
background: var(--BG-white, #fff);
|
||||||
padding: 12px 16px 16px;
|
padding: 12px 16px 16px;
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
.name {
|
.name {
|
||||||
color: var(--Text-1, #211f24);
|
color: var(--Text-1, #211f24);
|
||||||
|
|||||||
@ -16,12 +16,12 @@
|
|||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<!-- 加载中状态 -->
|
<!-- 加载中状态 -->
|
||||||
<template v-if="modalState === MODAL_STATE.LOADING">
|
<template v-if="modalState === MODAL_STATE.LOADING">
|
||||||
<a-progress
|
<Progress
|
||||||
:percent="progress"
|
:percent="progress"
|
||||||
color="#6D4CFE"
|
strokeColor="#6D4CFE"
|
||||||
trackColor="#E6E6E8"
|
trailColor="#E6E6E8"
|
||||||
size="large"
|
size="default"
|
||||||
:stroke-width="4"
|
:strokeWidth="4"
|
||||||
type="circle"
|
type="circle"
|
||||||
/>
|
/>
|
||||||
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<!-- 二维码加载中或失败 -->
|
<!-- 二维码加载中或失败 -->
|
||||||
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
||||||
<div class="relative w-160px h-160px">
|
<div class="relative w-160px h-160px">
|
||||||
<a-image :src="icon1" width="160" height="160" />
|
<Image :src="icon1" :width="160" :height="160" />
|
||||||
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
||||||
<img
|
<img
|
||||||
v-if="modalState === MODAL_STATE.QR_FAILED"
|
v-if="modalState === MODAL_STATE.QR_FAILED"
|
||||||
@ -63,7 +63,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 正常二维码 -->
|
<!-- 正常二维码 -->
|
||||||
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
<Image v-else :src="qrCodeUrl" :width="160" :height="160" />
|
||||||
<!-- 二维码失效遮罩 -->
|
<!-- 二维码失效遮罩 -->
|
||||||
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
||||||
<icon-refresh size="24" class="mb-13px" />
|
<icon-refresh size="24" class="mb-13px" />
|
||||||
@ -94,7 +94,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref, computed } from 'vue';
|
import { defineExpose, ref, computed } from 'vue';
|
||||||
import { Button, Modal, message } from 'ant-design-vue';
|
import { Button, Modal, message, Image, Progress } from 'ant-design-vue';
|
||||||
import { getAuthorizedImage, getMediaAccountsAuthorizedStatus } from '@/api/all/propertyMarketing';
|
import { getAuthorizedImage, getMediaAccountsAuthorizedStatus } from '@/api/all/propertyMarketing';
|
||||||
import SyncDataModal from '../sync-data-modal';
|
import SyncDataModal from '../sync-data-modal';
|
||||||
|
|
||||||
@ -242,12 +242,12 @@ const getAuthorizedStatus = async () => {
|
|||||||
const startFakeProgressPolling = () => {
|
const startFakeProgressPolling = () => {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
if (modalState.value === MODAL_STATE.LOADING && progress.value < 0.99) {
|
if (modalState.value === MODAL_STATE.LOADING && progress.value < 99) {
|
||||||
const step = Math.random() * 0.04 + 0.01;
|
const step = Math.random() * 4 + 1;
|
||||||
progress.value = Math.min(progress.value + step, 0.99);
|
progress.value = Math.min(progress.value + step, 99);
|
||||||
progress.value = Number(progress.value.toFixed(2));
|
progress.value = Number(progress.value.toFixed(2));
|
||||||
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 0.99) {
|
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 99) {
|
||||||
progress.value = 0.99; // 卡在99%
|
progress.value = 99; // 卡在99%
|
||||||
} else {
|
} else {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
clearStatusPollingTimer();
|
clearStatusPollingTimer();
|
||||||
|
|||||||
@ -16,12 +16,12 @@
|
|||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<!-- 加载中状态 -->
|
<!-- 加载中状态 -->
|
||||||
<template v-if="modalState === MODAL_STATE.LOADING">
|
<template v-if="modalState === MODAL_STATE.LOADING">
|
||||||
<a-progress
|
<Progress
|
||||||
:percent="progress"
|
:percent="progress"
|
||||||
color="#6D4CFE"
|
strokeColor="#6D4CFE"
|
||||||
trackColor="#E6E6E8"
|
trailColor="#E6E6E8"
|
||||||
size="large"
|
size="default"
|
||||||
:stroke-width="4"
|
:strokeWidth="4"
|
||||||
type="circle"
|
type="circle"
|
||||||
/>
|
/>
|
||||||
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
<!-- 二维码加载中或失败 -->
|
<!-- 二维码加载中或失败 -->
|
||||||
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
||||||
<div class="relative w-160px h-160px">
|
<div class="relative w-160px h-160px">
|
||||||
<a-image :src="icon1" width="160" height="160" />
|
<Image :src="icon1" :width="160" :height="160" />
|
||||||
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
||||||
<img
|
<img
|
||||||
v-if="modalState === MODAL_STATE.QR_FAILED"
|
v-if="modalState === MODAL_STATE.QR_FAILED"
|
||||||
@ -78,7 +78,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 正常二维码 -->
|
<!-- 正常二维码 -->
|
||||||
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
<Image v-else :src="qrCodeUrl" :width="160" :height="160" />
|
||||||
|
|
||||||
<!-- 二维码失效遮罩 -->
|
<!-- 二维码失效遮罩 -->
|
||||||
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
||||||
@ -112,7 +112,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref, computed } from 'vue';
|
import { defineExpose, ref, computed } from 'vue';
|
||||||
import { Button, Modal, message } from 'ant-design-vue';
|
import { Button, Modal, message, Image, Progress } from 'ant-design-vue';
|
||||||
import { getMediaAccountsAuthorizedStatus, getAuthorizedImage } from '@/api/all/propertyMarketing';
|
import { getMediaAccountsAuthorizedStatus, getAuthorizedImage } from '@/api/all/propertyMarketing';
|
||||||
import SyncDataModal from '../sync-data-modal';
|
import SyncDataModal from '../sync-data-modal';
|
||||||
|
|
||||||
@ -259,12 +259,12 @@ const getAuthorizedStatus = async () => {
|
|||||||
const startFakeProgressPolling = () => {
|
const startFakeProgressPolling = () => {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
if (modalState.value === MODAL_STATE.LOADING && progress.value < 0.99) {
|
if (modalState.value === MODAL_STATE.LOADING && progress.value < 99) {
|
||||||
const step = Math.random() * 0.04 + 0.01;
|
const step = Math.random() * 4 + 1;
|
||||||
progress.value = Math.min(progress.value + step, 0.99);
|
progress.value = Math.min(progress.value + step, 99);
|
||||||
progress.value = Number(progress.value.toFixed(2));
|
progress.value = Number(progress.value.toFixed(2));
|
||||||
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 0.99) {
|
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 99) {
|
||||||
progress.value = 0.99; // 卡在99%
|
progress.value = 99; // 卡在99%
|
||||||
} else {
|
} else {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
clearStatusPollingTimer();
|
clearStatusPollingTimer();
|
||||||
|
|||||||
@ -9,9 +9,9 @@
|
|||||||
@cancel="onClose"
|
@cancel="onClose"
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<a-steps changeable :current="currentStep" @change="setCurrent" class="mb-24px mx-79px">
|
<Steps changeable :current="currentStep" @change="setCurrent" class="mb-24px mx-79px w-full">
|
||||||
<a-step v-for="(step, index) in STEPS" :key="index">{{ step.label }}</a-step>
|
<Steps.Step v-for="(step, index) in STEPS" :key="index" :title="step.label" />
|
||||||
</a-steps>
|
</Steps>
|
||||||
|
|
||||||
<component :is="activeComp" v-model:formQuery="formQuery" ref="compRef" />
|
<component :is="activeComp" v-model:formQuery="formQuery" ref="compRef" />
|
||||||
</div>
|
</div>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { postAddProject, putProject, getProjectDetail } from '@/api/all/propertyMarketing';
|
import { postAddProject, putProject, getProjectDetail } from '@/api/all/propertyMarketing';
|
||||||
import { Button, Modal } from 'ant-design-vue';
|
import { Button, Modal, Steps } from 'ant-design-vue';
|
||||||
|
|
||||||
import StepOne from './stepOne.vue';
|
import StepOne from './stepOne.vue';
|
||||||
import StepTwo from './stepTwo.vue';
|
import StepTwo from './stepTwo.vue';
|
||||||
|
|||||||
@ -1,21 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-card :bordered="false" class="chart-container" ref="chartContainer">
|
<Card :bordered="false" class="chart-container !p-0" ref="chartContainer">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span class="a-card-title">{{ title.name }}</span>
|
<span class="a-card-title">{{ title.name }}</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" :title="title.popover">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">{{ title.popover }}</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</template>
|
</template>
|
||||||
<NoData v-if="isChartEmpty" text="暂无数据" />
|
<NoData v-if="isChartEmpty" text="暂无数据" />
|
||||||
|
|
||||||
<div v-else class="chart" ref="chartEl" :style="{ height: height + 'px' }"></div>
|
<div v-else class="chart" ref="chartEl" :style="{ height: height + 'px' }"></div>
|
||||||
</a-card>
|
</Card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { Tooltip, Card } from "ant-design-vue"
|
||||||
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
|
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
<div class="filter-row flex">
|
<div class="filter-row flex">
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">时间筛选</span>
|
<span class="label">时间筛选</span>
|
||||||
<a-range-picker v-model="query.data_time" size="medium" allow-clear format="YYYY-MM-DD" class="!w-240px" />
|
<DatePicker.RangePicker v-model:value="query.data_time" allowClear format="YYYY-MM-DD" class="!w-240px" />
|
||||||
</div>
|
</div>
|
||||||
<Button type="primary" ghost class="mr-12px" @click="handleSearch">
|
<Button type="primary" ghost class="mr-12px" @click="handleSearch">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -51,23 +51,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-wrap rounded-8px py-5px flex-1 flex flex-col" v-if="onLoading == false">
|
<div class="table-wrap rounded-8px py-5px flex-1 flex flex-col" v-if="onLoading == false">
|
||||||
<a-row :gutter="[24, 24]">
|
<Row :gutter="[24, 24]">
|
||||||
<a-col v-for="(chart, key) in chartConfigs" :key="chart.dataKey" :span="12">
|
<Col v-for="(chart, key) in chartConfigs" :key="chart.dataKey" :span="12">
|
||||||
<div>
|
<div>
|
||||||
<EchartsItem
|
<EchartsItem
|
||||||
:chartData="{ date: chart.date, series_data: chart.series_data }"
|
:chartData="{ date: chart.date, series_data: chart.series_data }"
|
||||||
:title="{ name: chart.title.name, popover: chart.title.popover }"
|
:title="{ name: chart.title.name, popover: chart.title.popover }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import EchartsItem from './components/echarts-item/index';
|
import EchartsItem from './components/echarts-item/index';
|
||||||
import { PLATFORM_LIST } from '@/utils/platform';
|
import { PLATFORM_LIST } from '@/utils/platform';
|
||||||
import { Button, Select, Tabs } from 'ant-design-vue';
|
import { Button, Select, Tabs, Row, Col, DatePicker } from 'ant-design-vue';
|
||||||
import {
|
import {
|
||||||
getPlacementAccountsTrend,
|
getPlacementAccountsTrend,
|
||||||
getPlacementAccountProjectsTrend,
|
getPlacementAccountProjectsTrend,
|
||||||
|
|||||||
@ -52,8 +52,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">时间筛选</span>
|
<span class="label">时间筛选</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="query.data_time"
|
v-model:value="query.data_time"
|
||||||
size="medium"
|
size="medium"
|
||||||
:allow-clear="false"
|
:allow-clear="false"
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, defineEmits, defineProps } from 'vue';
|
import { reactive, defineEmits, defineProps } from 'vue';
|
||||||
import { Button, Input } from 'ant-design-vue';
|
import { Button, Input, DatePicker } from 'ant-design-vue';
|
||||||
import {
|
import {
|
||||||
getPlacementAccountProjectGroupsList,
|
getPlacementAccountProjectGroupsList,
|
||||||
getPlacementAccountsList,
|
getPlacementAccountsList,
|
||||||
|
|||||||
@ -35,22 +35,21 @@
|
|||||||
<!-- 默认状态 -->
|
<!-- 默认状态 -->
|
||||||
<div class="upload-block">
|
<div class="upload-block">
|
||||||
<template v-if="uploadStatus === UploadStatus.DEFAULT">
|
<template v-if="uploadStatus === UploadStatus.DEFAULT">
|
||||||
<a-upload
|
<Upload
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
action="/"
|
action="/"
|
||||||
draggable
|
:customRequest="handleUpload"
|
||||||
:custom-request="handleUpload"
|
|
||||||
accept=".xlsx,.xls,.docx,.doc"
|
accept=".xlsx,.xls,.docx,.doc"
|
||||||
:show-file-list="false"
|
:showUploadList="false"
|
||||||
>
|
>
|
||||||
<template #upload-button>
|
<template #default>
|
||||||
<div class="upload-box">
|
<div class="upload-box">
|
||||||
<icon-plus size="14" class="mb-16px" />
|
<icon-plus size="14" class="mb-16px" />
|
||||||
<span class="text mb-4px">点击或拖拽文件到此处上传</span>
|
<span class="text mb-4px">点击或拖拽文件到此处上传</span>
|
||||||
<span class="tip">支持 xls, xlsx格式</span>
|
<span class="tip">支持 xls, xlsx格式</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
</Upload>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@ -138,7 +137,7 @@
|
|||||||
<icon-question-circle size="14" class="ml-4px color-#737478" />
|
<icon-question-circle size="14" class="ml-4px color-#737478" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-switch v-model="form.is_sync_project" size="medium" :checked-value="1" :unchecked-value="0" />
|
<Switch v-model:checked="form.is_sync_project" size="middle" :checkedValue="1" :unCheckedValue="0" />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
</Form>
|
</Form>
|
||||||
@ -155,7 +154,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Modal, Form, FormItem, Button, Input, RadioGroup, Radio, Tooltip, message } from 'ant-design-vue';
|
import { Modal, Form, FormItem, Button, Input, RadioGroup, Radio, Tooltip, message, Switch, Upload } from 'ant-design-vue';
|
||||||
import { ref, defineEmits } from 'vue';
|
import { ref, defineEmits } from 'vue';
|
||||||
|
|
||||||
import AuthorizedAccountModal from '../authorized-account-modal';
|
import AuthorizedAccountModal from '../authorized-account-modal';
|
||||||
@ -239,12 +238,12 @@ const confirmBtnText = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleUpload = async (option) => {
|
const handleUpload = async (option) => {
|
||||||
const { fileItem } = option;
|
const { file: uploadedFile } = option;
|
||||||
|
|
||||||
uploadStatus.value = UploadStatus.WAITING;
|
uploadStatus.value = UploadStatus.WAITING;
|
||||||
|
|
||||||
file.value = fileItem.file;
|
file.value = uploadedFile;
|
||||||
fileName.value = fileItem.name;
|
fileName.value = uploadedFile.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeFile() {
|
function removeFile() {
|
||||||
|
|||||||
@ -36,8 +36,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.arco-upload-drag {
|
.ant-upload {
|
||||||
height: 120px;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -47,6 +47,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.upload-box {
|
.upload-box {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
|
|||||||
@ -15,12 +15,12 @@
|
|||||||
>
|
>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<template v-if="isLoading">
|
<template v-if="isLoading">
|
||||||
<a-progress
|
<Progress
|
||||||
:percent="progress"
|
:percent="progress"
|
||||||
color="#6D4CFE"
|
strokeColor="#6D4CFE"
|
||||||
trackColor="#E6E6E8"
|
trailColor="#E6E6E8"
|
||||||
size="large"
|
size="default"
|
||||||
:stroke-width="4"
|
:strokeWidth="4"
|
||||||
type="circle"
|
type="circle"
|
||||||
/>
|
/>
|
||||||
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
||||||
@ -61,7 +61,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
// 添加Modal导入
|
// 添加Modal导入
|
||||||
import { Modal, Form, FormItem, Input } from 'ant-design-vue';
|
import { Modal, Form, FormItem, Input, Progress } from 'ant-design-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
import { defineExpose, ref, computed, defineEmits } from 'vue';
|
import { defineExpose, ref, computed, defineEmits } from 'vue';
|
||||||
@ -217,12 +217,12 @@ const startLoading = async () => {
|
|||||||
const startFakeProgressPolling = () => {
|
const startFakeProgressPolling = () => {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
if (!isCompleted.value && progress.value < 0.99) {
|
if (!isCompleted.value && progress.value < 99) {
|
||||||
const step = Math.random() * 0.04 + 0.01;
|
const step = Math.random() * 4 + 1;
|
||||||
progress.value = Math.min(progress.value + step, 0.99);
|
progress.value = Math.min(progress.value + step, 99);
|
||||||
progress.value = Number(progress.value.toFixed(2));
|
progress.value = Number(progress.value.toFixed(2));
|
||||||
} else if (!isCompleted.value && progress.value >= 0.99) {
|
} else if (!isCompleted.value && progress.value >= 99) {
|
||||||
progress.value = 0.99; // 卡在99%
|
progress.value = 99; // 卡在99%
|
||||||
} else {
|
} else {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
clearStatusPollingTimer();
|
clearStatusPollingTimer();
|
||||||
|
|||||||
@ -3,25 +3,19 @@
|
|||||||
<div class="part-div">
|
<div class="part-div">
|
||||||
<div class="part-div-header">
|
<div class="part-div-header">
|
||||||
<span class="part-div-header-title">投放行动指南</span>
|
<span class="part-div-header-title">投放行动指南</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="投放建议优化。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>投放建议优化。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</div>
|
</div>
|
||||||
<Space>
|
<Space>
|
||||||
<span class="player-title">表现分析</span>
|
<span class="player-title">表现分析</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="表现分析。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>表现分析。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
<div style="margin-right: 24px">
|
<div style="margin-right: 24px">
|
||||||
<a-row :gutter="24">
|
<Row :gutter="24">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">人群分析</span>
|
<span class="placement-optimization-title">人群分析</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -34,8 +28,8 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">投放素材</span>
|
<span class="placement-optimization-title">投放素材</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -48,10 +42,10 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
<a-row class="grid-demo" :gutter="24">
|
<Row class="grid-demo" :gutter="24">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">投放时段</span>
|
<span class="placement-optimization-title">投放时段</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -64,9 +58,9 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
|
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">平台表现</span>
|
<span class="placement-optimization-title">平台表现</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -79,20 +73,17 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
<Space>
|
<Space>
|
||||||
<span class="player-title">新投放建议生成</span>
|
<span class="player-title">新投放建议生成</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="新投放建议生成。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">新投放建议生成。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
<a-row class="grid-demo" :gutter="24">
|
<Row class="grid-demo" :gutter="24">
|
||||||
<a-col :span="24">
|
<Col :span="24">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">人群建议</span>
|
<span class="placement-optimization-title">人群建议</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -105,10 +96,10 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
<a-row class="grid-demo" :gutter="24">
|
<Row class="grid-demo" :gutter="24">
|
||||||
<a-col :span="24">
|
<Col :span="24">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">素材建议</span>
|
<span class="placement-optimization-title">素材建议</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -121,11 +112,11 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
|
|
||||||
<a-row class="grid-demo" :gutter="24">
|
<Row class="grid-demo" :gutter="24">
|
||||||
<a-col :span="24">
|
<Col :span="24">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title">投放策略建议</span>
|
<span class="placement-optimization-title">投放策略建议</span>
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
@ -138,14 +129,14 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Space } from "ant-design-vue"
|
import { Space, Tooltip, Row, Col } from "ant-design-vue"
|
||||||
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -2,12 +2,9 @@
|
|||||||
<div class="part-div">
|
<div class="part-div">
|
||||||
<div class="part-div-header">
|
<div class="part-div-header">
|
||||||
<span class="part-div-header-title">总体摘要</span>
|
<span class="part-div-header-title">总体摘要</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="于筛选出来的投流账户/计划的情况生成的总体描述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">基于筛选出来的投流账户/计划的情况生成的总体描述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
<span @click="copyData" class="copybtn">
|
<span @click="copyData" class="copybtn">
|
||||||
<icon-copy :style="{ fontSize: '14px' }" />
|
<icon-copy :style="{ fontSize: '14px' }" />
|
||||||
复制
|
复制
|
||||||
@ -29,7 +26,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
import { IconQuestionCircle } from '@arco-design/web-vue/es/icon';
|
||||||
import { defineProps } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
import { Space, message } from "ant-design-vue"
|
import { Space, message, Tooltip } from "ant-design-vue"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
overview: {
|
overview: {
|
||||||
|
|||||||
@ -2,97 +2,80 @@
|
|||||||
<div class="part-div">
|
<div class="part-div">
|
||||||
<div class="part-div-header">
|
<div class="part-div-header">
|
||||||
<span class="part-div-header-title">投放建议优化</span>
|
<span class="part-div-header-title">投放建议优化</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="基于筛选出来的投流账户/计划的情况生成的优化建议。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">基于筛选出来的投流账户/计划的情况生成的优化建议。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</div>
|
</div>
|
||||||
<NoData v-if="isEmptyData" style="height: 100px" text="暂无数据" />
|
<NoData v-if="isEmptyData" style="height: 100px" text="暂无数据" />
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<a-row class="grid-demo" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
<Row class="grid-demo" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
||||||
<a-col :span="24">
|
<Col :span="24">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title"
|
<span class="placement-optimization-title"
|
||||||
>总体策略
|
>总体策略
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="优化建议的整体调整概述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">优化建议的整体调整概述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</span>
|
</span>
|
||||||
<span class="placement-optimization-str">{{ props.optimization?.[0]?.['content'] }}</span>
|
<span class="placement-optimization-str">{{ props.optimization?.[0]?.['content'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
<a-row class="grid-demo" style="margin-right: 10px" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
<Row class="grid-demo" style="margin-right: 10px" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title"
|
<span class="placement-optimization-title"
|
||||||
>预算分配
|
>预算分配
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="优化建议在预算分配部分的详细描述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">优化建议在预算分配部分的详细描述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</span>
|
</span>
|
||||||
<span class="placement-optimization-str">{{ props.optimization?.[1]?.['content'] }}</span>
|
<span class="placement-optimization-str">{{ props.optimization?.[1]?.['content'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title"
|
<span class="placement-optimization-title"
|
||||||
>时段优化
|
>时段优化
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="优化建议在时段优化部分的详细描述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">优化建议在时段优化部分的详细描述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</span>
|
</span>
|
||||||
<span class="placement-optimization-str">{{ props.optimization?.[2]?.['content'] }}</span>
|
<span class="placement-optimization-str">{{ props.optimization?.[2]?.['content'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
<a-row class="grid-demo" style="margin-right: 10px" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
<Row class="grid-demo" style="margin-right: 10px" :gutter="{ md: 8, lg: 24, xl: 32 }">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title"
|
<span class="placement-optimization-title"
|
||||||
>人群包优化
|
>人群包优化
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="优化建议在人群包优化部分的详细描述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">优化建议在人群包优化部分的详细描述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</span>
|
</span>
|
||||||
<span class="placement-optimization-str">{{ props?.optimization?.[3]?.['content'] }}</span>
|
<span class="placement-optimization-str">{{ props?.optimization?.[3]?.['content'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="overall-strategy">
|
<div class="overall-strategy">
|
||||||
<span class="placement-optimization-title"
|
<span class="placement-optimization-title"
|
||||||
>素材优化
|
>素材优化
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="优化建议在素材优化部分的详细描述。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p style="margin: 0">优化建议在素材优化部分的详细描述。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</span>
|
</span>
|
||||||
<span class="placement-optimization-str">{{ props?.optimization?.[4]?.['content'] }}</span>
|
<span class="placement-optimization-str">{{ props?.optimization?.[4]?.['content'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Tooltip, Row, Col } from "ant-design-vue"
|
||||||
import { defineProps } from 'vue';
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -42,15 +42,14 @@
|
|||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
<Space>
|
<Space>
|
||||||
<Space>
|
<Space>
|
||||||
<a-popconfirm
|
<Popconfirm
|
||||||
content="确定删除吗?"
|
title="确定删除吗?"
|
||||||
type="warning"
|
okText="确认删除"
|
||||||
ok-text="确认删除"
|
cancelText="取消"
|
||||||
cancel-text="取消"
|
@confirm="deleteData(record.id)"
|
||||||
@ok="deleteData(record.id)"
|
|
||||||
>
|
>
|
||||||
<icon-delete></icon-delete>
|
<icon-delete></icon-delete>
|
||||||
</a-popconfirm>
|
</Popconfirm>
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
<Button type="primary" ghost @click="downLoad(record.file_url)" class="operation-btn">下载</Button>
|
<Button type="primary" ghost @click="downLoad(record.file_url)" class="operation-btn">下载</Button>
|
||||||
@ -63,7 +62,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Button, Space, Table, message } from 'ant-design-vue';
|
import { Button, Space, Table, message, Popconfirm } from 'ant-design-vue';
|
||||||
import { IconDelete } from '@arco-design/web-vue/es/icon';
|
import { IconDelete } from '@arco-design/web-vue/es/icon';
|
||||||
import { PLATFORM_LIST } from '@/utils/platform';
|
import { PLATFORM_LIST } from '@/utils/platform';
|
||||||
|
|
||||||
@ -122,4 +121,7 @@ const props = defineProps({
|
|||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
:deep(.ant-popconfirm-buttons) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<!--表单搜索组件-->
|
<!--表单搜索组件-->
|
||||||
<template>
|
<template>
|
||||||
<div class="container px-24px">
|
<div class="container px-24px pt-24px">
|
||||||
<div class="filter-row flex mb-20px">
|
<div class="filter-row flex mb-20px">
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">账户名称</span>
|
<span class="label">账户名称</span>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<div class="filter-row flex mb-20px">
|
<div class="filter-row flex mb-20px">
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
<span class="label">时间筛选</span>
|
<span class="label">时间筛选</span>
|
||||||
<a-range-picker v-model="query.data_time" size="medium" allow-clear format="YYYY-MM-DD" class="w-310" />
|
<DatePicker.RangePicker v-model:value="query.data_time" size="medium" allowClear format="YYYY-MM-DD" class="w-310" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="filter-row-item flex items-center">
|
<div class="filter-row-item flex items-center">
|
||||||
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineEmits, defineProps } from 'vue';
|
import { defineEmits, defineProps } from 'vue';
|
||||||
import { Button, Select } from 'ant-design-vue';
|
import { Button, Select, DatePicker } from 'ant-design-vue';
|
||||||
import { PLATFORM_LIST } from '@/utils/platform';
|
import { PLATFORM_LIST } from '@/utils/platform';
|
||||||
import AccountSelect from '@/views/components/common/AccountSelect.vue';
|
import AccountSelect from '@/views/components/common/AccountSelect.vue';
|
||||||
import PlanSelect from '@/views/components/common/PlanSelect.vue';
|
import PlanSelect from '@/views/components/common/PlanSelect.vue';
|
||||||
|
|||||||
@ -46,12 +46,9 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<Space>
|
<Space>
|
||||||
<span>本周总消耗</span>
|
<span>本周总消耗</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="当前周内所有投流账户的累计广告花费,反映整体投放规模。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>当前周内所有投流账户的累计广告花费,反映整体投放规模。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
@ -68,16 +65,13 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<Space>
|
<Space>
|
||||||
<span>本周总消耗环比</span>
|
<span>本周总消耗环比</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="本周消耗金额与上周对比的变化百分比,用于衡量预算投放趋势。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>本周消耗金额与上周对比的变化百分比,用于衡量预算投放趋势。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
<a-statistic
|
<Statistic
|
||||||
:value="record.pre_total_use_amount_chain * 100"
|
:value="record.pre_total_use_amount_chain * 100"
|
||||||
:value-style="{
|
:value-style="{
|
||||||
color: record.pre_total_use_amount_chain > 0 ? '#F64B31' : '#25C883',
|
color: record.pre_total_use_amount_chain > 0 ? '#F64B31' : '#25C883',
|
||||||
@ -90,7 +84,7 @@
|
|||||||
<icon-arrow-down v-else />
|
<icon-arrow-down v-else />
|
||||||
</template>
|
</template>
|
||||||
<template #suffix>%</template>
|
<template #suffix>%</template>
|
||||||
</a-statistic>
|
</Statistic>
|
||||||
</template>
|
</template>
|
||||||
</Table.Column>
|
</Table.Column>
|
||||||
<Table.Column
|
<Table.Column
|
||||||
@ -103,12 +97,9 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<Space>
|
<Space>
|
||||||
<span>ROI</span>
|
<span>ROI</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="投资回报率(ROI)= 收益 ÷ 投入成本,反映整体投流账户的收益效率。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>投资回报率(ROI)= 收益 ÷ 投入成本,反映整体投流账户的收益效率。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
</Table.Column>
|
</Table.Column>
|
||||||
@ -122,12 +113,9 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<Space>
|
<Space>
|
||||||
<span>CTR</span>
|
<span>CTR</span>
|
||||||
<a-popover position="tl">
|
<Tooltip position="tl" title="点击率(CTR)= 点击量 ÷ 展示量,是衡量广告素材吸引力的关键指标。">
|
||||||
<icon-question-circle />
|
<icon-question-circle />
|
||||||
<template #content>
|
</Tooltip>
|
||||||
<p>点击率(CTR)= 点击量 ÷ 展示量,是衡量广告素材吸引力的关键指标。</p>
|
|
||||||
</template>
|
|
||||||
</a-popover>
|
|
||||||
</Space>
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
<template #customRender="{ record }">
|
<template #customRender="{ record }">
|
||||||
@ -138,7 +126,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Space, Table } from "ant-design-vue"
|
import { Space, Table, Tooltip, Statistic } from "ant-design-vue"
|
||||||
import { PLATFORM_LIST } from '@/utils/platform';
|
import { PLATFORM_LIST } from '@/utils/platform';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@ -6,27 +6,27 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container px-24px pt-12px pb-24px">
|
<div class="container px-24px pt-12px pb-24px">
|
||||||
<a-row class="grid-demo" :gutter="24">
|
<Row class="grid-demo" :gutter="24">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="">
|
<div class="">
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
<span class="span-title">账户</span>
|
<span class="span-title">账户</span>
|
||||||
<span class="span-content">{{ detailData?.account }}</span>
|
<span class="span-content">{{ detailData?.account }}</span>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
|
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="">
|
<div class="">
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
<span class="span-title">计划</span>
|
<span class="span-title">计划</span>
|
||||||
<span class="span-content">{{detailData.plan}}</span>
|
<span class="span-content">{{detailData.plan}}</span>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
<a-row class="grid-demo" :gutter="24" style="margin-top: 30px">
|
<Row class="grid-demo" :gutter="24" style="margin-top: 30px">
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="">
|
<div class="">
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
<span class="span-title">平台</span>
|
<span class="span-title">平台</span>
|
||||||
@ -42,17 +42,17 @@
|
|||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
|
|
||||||
<a-col :span="12">
|
<Col :span="12">
|
||||||
<div class="">
|
<div class="">
|
||||||
<Space direction="vertical">
|
<Space direction="vertical">
|
||||||
<span class="span-title">生成时间</span>
|
<span class="span-title">生成时间</span>
|
||||||
<span class="span-content">{{ detailData.created_at }}</span>
|
<span class="span-content">{{ detailData.created_at }}</span>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</Col>
|
||||||
</a-row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MonthData :overview="aiResult.overview"></MonthData>
|
<MonthData :overview="aiResult.overview"></MonthData>
|
||||||
@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { Button, Space, message } from 'ant-design-vue';
|
import { Button, Space, message, Row, Col } from 'ant-design-vue';
|
||||||
import MonthData from './components/month-data/index.vue';
|
import MonthData from './components/month-data/index.vue';
|
||||||
import PlacementSuggestions from './components/placement-suggestions/index.vue';
|
import PlacementSuggestions from './components/placement-suggestions/index.vue';
|
||||||
import { PLATFORM_LIST } from '@/utils/platform';
|
import { PLATFORM_LIST } from '@/utils/platform';
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
@onSearch="onSearch"
|
@onSearch="onSearch"
|
||||||
@updateQuery="handleUpdateQuery"
|
@updateQuery="handleUpdateQuery"
|
||||||
/>
|
/>
|
||||||
<a-spin v-if="loading" tip="AI分析中" />
|
<Spin v-if="loading" tip="AI分析中" />
|
||||||
|
|
||||||
<div v-if="listData.total > 0" class="pagination-box flex justify-end ignore-export">
|
<div v-if="listData.total > 0" class="pagination-box flex justify-end ignore-export">
|
||||||
<Pagination
|
<Pagination
|
||||||
@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { Button, Tabs, Space, Pagination } from 'ant-design-vue';
|
import { Button, Tabs, Space, Pagination, Spin } from 'ant-design-vue';
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
import PlacementGuideList from './components/table-data/placementGuideList.vue';
|
import PlacementGuideList from './components/table-data/placementGuideList.vue';
|
||||||
import listSearchForm from './components/table-data/listSearchForm.vue';
|
import listSearchForm from './components/table-data/listSearchForm.vue';
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item" v-if="query.audit_status === AuditStatus.Pending">
|
<div class="filter-row-item" v-if="query.audit_status === AuditStatus.Pending">
|
||||||
<span class="label">上传时间</span>
|
<span class="label">上传时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="created_at"
|
v-model="created_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -69,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">审核时间</span>
|
<span class="label">审核时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="audit_started_at"
|
v-model="audit_started_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -100,7 +100,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits, defineProps } from 'vue';
|
import { defineEmits, defineProps } from 'vue';
|
||||||
import { Button, Input, Select, Space } from 'ant-design-vue';
|
import { Button, Input, Select, Space, DatePicker } from 'ant-design-vue';
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
import { PLATFORMS } from '@/views/writer-material-center/components/finished-products/manuscript/check-list/constants';
|
import { PLATFORMS } from '@/views/writer-material-center/components/finished-products/manuscript/check-list/constants';
|
||||||
import { AuditStatus } from '@/views/writer-material-center/components/finished-products/constants';
|
import { AuditStatus } from '@/views/writer-material-center/components/finished-products/constants';
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script lang="jsx">
|
<script lang="jsx">
|
||||||
import { Drawer, Image } from '@arco-design/web-vue';
|
import { Drawer, Image } from 'ant-design-vue';
|
||||||
import TextOverTips from '@/components/text-over-tips';
|
import TextOverTips from '@/components/text-over-tips';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/error-img.png';
|
import icon1 from '@/assets/img/error-img.png';
|
||||||
@ -32,12 +32,12 @@ export default {
|
|||||||
return () => (
|
return () => (
|
||||||
<Drawer
|
<Drawer
|
||||||
title="审核列表"
|
title="审核列表"
|
||||||
visible={visible.value}
|
v-model:open={visible.value}
|
||||||
width={420}
|
width={420}
|
||||||
class="check-list-drawer-xt"
|
rootClassName="check-list-drawer-xt"
|
||||||
footer={false}
|
footer={null}
|
||||||
header={false}
|
closable={false}
|
||||||
onCancel={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
<div class="flex justify-between items-center h-56px px-24px">
|
<div class="flex justify-between items-center h-56px px-24px">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@ -61,13 +61,13 @@ export default {
|
|||||||
height={48}
|
height={48}
|
||||||
preview={false}
|
preview={false}
|
||||||
src={item.cover}
|
src={item.cover}
|
||||||
class="!rounded-4px mr-8px"
|
class="!rounded-4px"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
v-slots={{
|
v-slots={{
|
||||||
error: () => <img src={icon1} class="w-full h-full" />,
|
error: () => <img src={icon1} class="w-full h-full" />,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 overflow-hidden flex flex-col items-start">
|
<div class="flex-1 overflow-hidden flex flex-col items-start ml-8px">
|
||||||
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
|
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
|
||||||
<p class="cts !text-14px">{`合规程度:${
|
<p class="cts !text-14px">{`合规程度:${
|
||||||
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
|
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
|
||||||
|
|||||||
@ -1,43 +1,40 @@
|
|||||||
.check-list-drawer-xt {
|
.check-list-drawer-xt {
|
||||||
.arco-drawer-mask {
|
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
.ant-drawer-mask {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
.arco-drawer {
|
.ant-drawer-body {
|
||||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
overflow: hidden;
|
||||||
.arco-drawer-body {
|
display: flex;
|
||||||
overflow: hidden;
|
flex-direction: column;
|
||||||
display: flex;
|
padding: 0 0 24px;
|
||||||
flex-direction: column;
|
.cts {
|
||||||
padding: 0 0 24px;
|
color: var(--Text-1, #939499);
|
||||||
.cts {
|
font-family: $font-family-regular;
|
||||||
color: var(--Text-1, #939499);
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
font-family: $font-family-regular;
|
font-weight: 400;
|
||||||
font-size: 16px;
|
line-height: 24px;
|
||||||
font-style: normal;
|
&.bold {
|
||||||
font-weight: 400;
|
color: var(--Text-1, #211f24);
|
||||||
line-height: 24px;
|
font-family: $font-family-medium;
|
||||||
&.bold {
|
|
||||||
color: var(--Text-1, #211f24);
|
|
||||||
font-family: $font-family-medium;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.card-item {
|
}
|
||||||
cursor: pointer;
|
.card-item {
|
||||||
border: 1px solid transparent;
|
cursor: pointer;
|
||||||
transition: all;
|
border: 1px solid transparent;
|
||||||
&:hover {
|
transition: all;
|
||||||
background-color: #e6e6e8;
|
&:hover {
|
||||||
}
|
background-color: #e6e6e8;
|
||||||
&:not(:last-child) {
|
}
|
||||||
margin-bottom: 12px;
|
&:not(:last-child) {
|
||||||
}
|
margin-bottom: 12px;
|
||||||
&.active {
|
}
|
||||||
border-color: #6d4cfe;
|
&.active {
|
||||||
background-color: #f0edff;
|
border-color: #6d4cfe;
|
||||||
:deep(.overflow-text) {
|
background-color: #f0edff;
|
||||||
font-family: $font-family-medium !important;
|
:deep(.overflow-text) {
|
||||||
}
|
font-family: $font-family-medium !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -138,9 +138,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const uploadImage = async (option, action = 'upload') => {
|
const uploadImage = async (option, action = 'upload') => {
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
|
|
||||||
const { name, size, type } = file;
|
const { name, size, type } = file;
|
||||||
const response = await getImagePreSignedUrl({ suffix: getFileExtension(name) });
|
const response = await getImagePreSignedUrl({ suffix: getFileExtension(name) });
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script lang="jsx">
|
<script lang="jsx">
|
||||||
import { Image } from '@arco-design/web-vue';
|
import { Image } from 'ant-design-vue';
|
||||||
import { Swiper, SwiperSlide } from 'swiper/vue';
|
import { Swiper, SwiperSlide } from 'swiper/vue';
|
||||||
import TextOverTips from '@/components/text-over-tips';
|
import TextOverTips from '@/components/text-over-tips';
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ export default {
|
|||||||
height={48}
|
height={48}
|
||||||
preview={false}
|
preview={false}
|
||||||
src={item.cover}
|
src={item.cover}
|
||||||
class="!rounded-4px mr-8px"
|
class="!rounded-4px"
|
||||||
fit="cover"
|
fit="cover"
|
||||||
v-slots={{
|
v-slots={{
|
||||||
error: () => <img src={icon1} class="w-full h-full" />,
|
error: () => <img src={icon1} class="w-full h-full" />,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 overflow-hidden flex flex-col items-start">
|
<div class="flex-1 overflow-hidden flex flex-col items-start ml-8px">
|
||||||
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
|
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
|
||||||
<p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
|
<p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -23,25 +23,23 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-upload
|
<Upload
|
||||||
v-if="files.length < 18"
|
v-if="files.length < 18"
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
action="/"
|
action="/"
|
||||||
draggable
|
:customRequest="(option) => emit('upload', option)"
|
||||||
:custom-request="(option) => emit('upload', option)"
|
|
||||||
accept=".jpg,.jpeg,.png,.gif,.webp"
|
accept=".jpg,.jpeg,.png,.gif,.webp"
|
||||||
:show-file-list="false"
|
:showUploadList="false"
|
||||||
multiple
|
multiple
|
||||||
class="!flex !items-center"
|
class="!flex !items-center"
|
||||||
:limit="18 - files.length"
|
|
||||||
>
|
>
|
||||||
<template #upload-button>
|
<template #default>
|
||||||
<div class="upload-box">
|
<div class="upload-box">
|
||||||
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
<icon-plus size="14" class="mb-16px color-#3C4043" />
|
||||||
<span class="cts !color-#211F24">上传图片</span>
|
<span class="cts !color-#211F24">上传图片</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
</Upload>
|
||||||
</VueDraggable>
|
</VueDraggable>
|
||||||
</div>
|
</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -49,7 +47,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { VueDraggable } from 'vue-draggable-plus';
|
import { VueDraggable } from 'vue-draggable-plus';
|
||||||
import { FormItem} from 'ant-design-vue';
|
import { FormItem, Upload } from 'ant-design-vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
files: {
|
files: {
|
||||||
|
|||||||
@ -132,9 +132,7 @@ export default {
|
|||||||
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
|
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
|
||||||
emit('updateVideoInfo', formData.value.videoInfo);
|
emit('updateVideoInfo', formData.value.videoInfo);
|
||||||
|
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
setVideoInfo(file);
|
setVideoInfo(file);
|
||||||
|
|
||||||
const response = await getVideoPreSignedUrlWriter(writerCode.value, { suffix: getFileExtension(file.name) });
|
const response = await getVideoPreSignedUrlWriter(writerCode.value, { suffix: getFileExtension(file.name) });
|
||||||
@ -165,9 +163,7 @@ export default {
|
|||||||
};
|
};
|
||||||
// 文件上传处理
|
// 文件上传处理
|
||||||
const uploadImage = async (option) => {
|
const uploadImage = async (option) => {
|
||||||
const {
|
const { file } = option;
|
||||||
fileItem: { file },
|
|
||||||
} = option;
|
|
||||||
|
|
||||||
// 验证文件数量
|
// 验证文件数量
|
||||||
if (formData.value.files?.length >= 18) {
|
if (formData.value.files?.length >= 18) {
|
||||||
|
|||||||
@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-row-item">
|
<div class="filter-row-item">
|
||||||
<span class="label">上传时间</span>
|
<span class="label">上传时间</span>
|
||||||
<a-range-picker
|
<DatePicker.RangePicker
|
||||||
v-model="created_at"
|
v-model="created_at"
|
||||||
size="medium"
|
size="medium"
|
||||||
allow-clear
|
allow-clear
|
||||||
@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits, defineProps } from 'vue';
|
import { defineEmits, defineProps } from 'vue';
|
||||||
import { Button, Input, Space } from 'ant-design-vue';
|
import { Button, Input, Space, DatePicker } from 'ant-design-vue';
|
||||||
import { CHECK_STATUS } from '@/views/writer-material-center/components/finished-products/manuscript/list/constants';
|
import { CHECK_STATUS } from '@/views/writer-material-center/components/finished-products/manuscript/list/constants';
|
||||||
import CommonSelect from '@/components/common-select';
|
import CommonSelect from '@/components/common-select';
|
||||||
// import { getProjectList } from '@/api/all/propertyMarketing';
|
// import { getProjectList } from '@/api/all/propertyMarketing';
|
||||||
|
|||||||
Reference in New Issue
Block a user