文件的分开

This commit is contained in:
lq
2025-09-12 17:46:01 +08:00
parent a1f2bb0519
commit b3d1a4789d
6 changed files with 312 additions and 90 deletions

View File

@ -14,19 +14,30 @@
:maxTagCount="maxTagCount" :maxTagCount="maxTagCount"
@change="handleChange" @change="handleChange"
> >
<Option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name"> <Option v-for="(item, index) in validOptions" :key="index" :value="item.value" :label="item.label">
<div class="flex items-center"> <div class="flex items-center">
<img v-if="item.icon" :src="item.icon" class="w-16px h-16px mr-8px rounded-4px" /> <img v-if="item.icon" :src="item.icon" class="w-16px h-16px mr-4px rounded-4px" />
{{ item.name }} <span>{{ item.label }}</span>
</div> </div>
</Option> </Option>
<template #tag="{ label, icon }">
<div class="flex items-center">
<img v-if="icon" :src="icon" class="w-16px h-16px mr-4px rounded-4px" />
<span>{{ label }}</span>
</div>
</template>
<template v-if="!allowSearch" #empty>
<div v-if="validOptions.length === 0" class="empty-placeholder">
{{ placeholder || '暂无数据' }}
</div>
</template>
</Select> </Select>
</template> </template>
<script setup> <script setup>
import { Select } from 'ant-design-vue'; import { Select } from 'ant-design-vue';
const { Option } = Select; const { Option } = Select;
import { ref, watch } from 'vue'; import { ref, watch, computed } from 'vue';
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@ -48,7 +59,7 @@ const props = defineProps({
maxTagCount: { maxTagCount: {
type: Number, type: Number,
default: 3, default: 3,
}, },
allClear: { allClear: {
type: Boolean, type: Boolean,
default: true, default: true,
@ -56,13 +67,28 @@ const props = defineProps({
allowSearch: { allowSearch: {
type: Boolean, type: Boolean,
default: false, default: false,
} },
}); });
const emits = defineEmits(['update:modelValue', 'change']); const emits = defineEmits(['update:modelValue', 'change']);
const selectedValues = ref(props.multiple ? [] : ''); const selectedValues = ref(props.multiple ? [] : '');
// 计算有效选项,兼容不同的数据格式
const validOptions = computed(() => {
if (!props.options || !Array.isArray(props.options)) {
return [];
}
return props.options
.filter(item => item && (item.id !== undefined || item.value !== undefined) && (item.name !== undefined || item.label !== undefined))
.map(item => ({
...item,
value: item.id !== undefined ? item.id : item.value,
label: item.name !== undefined ? item.name : item.label
}));
});
watch( watch(
() => props.modelValue, () => props.modelValue,
(newVal) => { (newVal) => {
@ -79,4 +105,12 @@ const handleChange = (value) => {
selectedValues.value = value; selectedValues.value = value;
emits('change', value); emits('change', value);
}; };
</script> </script>
<style scoped>
.empty-placeholder {
padding: 8px 12px;
color: #8f959e;
text-align: center;
}
</style>

View File

@ -0,0 +1,90 @@
<!-- // 新增内容: -->
<template>
<a-trigger trigger="click" :style="triggerStyle">
<a-button size="small">
<template #icon>
<icon-filter size="16" class="color-#55585F" />
</template>
<template #default>筛选</template>
</a-button>
<template #content>
<div>
<!-- 运营人员 -->
<div class="flex items-center mb-24px">
<div class="w-70px">运营人员</div>
<a-space class="w-200px">
<CommonSelect
placeholder="请选择运营人员"
:options="operators"
v-model="localQuery.operator"
@change="(val) => handleChange('operator_id', val)"
class="!w-200px"
/>
</a-space>
</div>
<!-- 发布平台 -->
<div class="flex items-center mb-24px">
<div class="w-70px">发布平台</div>
<a-space class="w-200px">
<CommonSelect
:options="platformOptions"
v-model="localQuery.platform"
@change="(val) => handleChange('platform', val)"
class="!w-200px"
placeholder="请选择发布平台"
/>
</a-space>
</div>
<!-- 账号名称 -->
<div class="flex items-center">
<div class="w-80px">账号名称</div>
<a-space class="w-200px">
<CommonSelect
v-model="localQuery.accounts"
:options="accountList"
:multiple="true"
@change="(val) => handleChange('account_id', val)"
class="!w-200px"
placeholder="请选择账号名称"
/>
</a-space>
</div>
</div>
</template>
</a-trigger>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
operators: Array,
platformOptions: Array,
accountList: Array,
query: Object,
});
const emit = defineEmits(['update:query']);
// 初始化本地查询对象
const localQuery = ref({ ...props.query });
// 监听外部 query 变化并同步到本地状态
watch(
() => props.query,
(newQuery) => {
localQuery.value = { ...newQuery };
},
{ deep: true },
);
// 处理筛选变化
const handleChange = (field, value) => {
localQuery.value[field] = value;
emit('update:query', { ...localQuery.value });
};
</script>
<style scoped>
/* 样式保持不变 */
</style>

View File

@ -0,0 +1,38 @@
<template>
<a-trigger
trigger="click"
style="
background-color: #ffffff;
border: 1px solid #d9d9d9;
border-radius: 4px;
box-shadow: #00000010 0px 2px 8px;
padding: 8px;
margin-top: 8px;
"
>
<a-button size="small" class="mr-12px color-scheme-btn" :bordered="false">
<template #icon>
<icon-info-circle-fill size="16" class="color-#55585F" />
</template>
<template #default>颜色示意</template>
</a-button>
<template #content>
<div class="flex items-center mt-8px w-104px mr-8px">
<div style="background-color: #ffae00; width: 16px; height: 16px; margin-right: 5px; border-radius: 4px"></div>
<div>待生成</div>
</div>
<div class="flex items-center mt-8px w-104px mr-8px">
<div style="background-color: #6d4cfe; width: 16px; height: 16px; margin-right: 5px; border-radius: 4px"></div>
<div>待发布</div>
</div>
<div class="flex items-center mt-8px w-104px mr-8px">
<div style="background-color: #939499; width: 16px; height: 16px; margin-right: 5px; border-radius: 4px"></div>
<div>已发布</div>
</div>
<div class="flex items-center mt-8px mb-4px w-104px mr-8px">
<div style="background-color: #f64b31; width: 16px; height: 16px; margin-right: 5px; border-radius: 4px"></div>
<div>发布失败</div>
</div>
</template>
</a-trigger>
</template>

View File

@ -0,0 +1,119 @@
<!-- // 新增内容: -->
<template>
<a-trigger trigger="click" :clickOutsideToClose="true" :clickToClose="false">
<a-button size="small">
<template #icon>
<icon-filter size="16" class="color-#55585F" />
</template>
<template #default>筛选</template>
</a-button>
<template #content>
<div class="filter-popup-content">
<!-- 运营人员 -->
<div class="flex items-center mb-24px">
<div class="w-70px">运营人员</div>
<a-space class="w-240px">
<CommonSelect
placeholder="请选择运营人员"
:options="operators || []"
v-model="localQuery.operator"
@change="(val) => handleChange('operator_id', val)"
class="!w-240px"
:allowSearch="true"
popup-container=".filter-popup-content"
/>
</a-space>
</div>
<!-- 发布平台 -->
<div class="flex items-center mb-24px">
<div class="w-70px">发布平台</div>
<a-space class="w-240px">
<CommonSelect
:options="platformOptions || []"
v-model="localQuery.platform"
@change="(val) => handleChange('platform', val)"
class="!w-240px"
placeholder="请选择发布平台"
:allowSearch="true"
popup-container=".filter-popup-content"
/>
</a-space>
</div>
<!-- 账号名称 -->
<div class="flex items-center">
<div class="w-70px">账号名称</div>
<a-space class="w-240px">
<CommonSelect
v-model="localQuery.accounts"
:options="accountList || []"
:multiple="true"
@change="(val) => handleChange('account_id', val)"
class="!w-240px"
placeholder="请选择账号名称"
:allowSearch="true"
popup-container=".filter-popup-content"
/>
</a-space>
</div>
</div>
</template>
</a-trigger>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
operators: Array,
platformOptions: Array,
accountList: Array,
query: Object,
});
onMounted(() => {});
const emit = defineEmits(['update:query']);
// 初始化本地查询对象,只设置非空值
const localQuery = ref({});
// 监听外部 query 变化并同步到本地状态
watch(
() => props.query,
(newQuery) => {
if (newQuery) {
// 只有当值不为空时才设置到localQuery中
const filteredQuery = {};
if (newQuery.operator) {
filteredQuery.operator = newQuery.operator;
}
if (newQuery.platform) {
filteredQuery.platform = newQuery.platform;
}
if (newQuery.accounts && newQuery.accounts.length > 0) {
filteredQuery.accounts = newQuery.accounts;
}
localQuery.value = { ...filteredQuery };
}
},
{ deep: true, immediate: true },
);
// 处理筛选变化
const handleChange = (field, value) => {
localQuery.value[field] = value;
emit('update:query', { ...localQuery.value });
};
</script>
<style scoped>
.filter-popup-content {
background-color: #ffffff;
border: 1px solid #d9d9d9;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow-y: auto;
padding: 24px;
margin-top: 8px;
margin-right: 25px;
}
</style>

View File

@ -53,7 +53,7 @@
</div> </div>
</div> </div>
<div class="flex items-start"> <div class="flex items-start">
<a-trigger <!-- <a-trigger
trigger="click" trigger="click"
style=" style="
background-color: #ffffff; background-color: #ffffff;
@ -86,82 +86,14 @@
<div>内容稿件</div> <div>内容稿件</div>
</div> </div>
</template> </template>
</a-trigger> </a-trigger> -->
<colorTip />
<a-trigger <FilterPopup
trigger="click" :operators="operators"
style=" :platformOptions="platformOptions"
background-color: #ffffff; :accountList="accountList"
border: 1px solid #d9d9d9; :query="query"
border-radius: 4px; />
box-shadow: #00000010 0px 2px 8px;
width: 308px;
max-height: 400px;
overflow-y: auto;
padding: 24px;
margin-top: 8px;
"
>
<a-button size="small">
<template #icon>
<icon-filter size="16" class="color-#55585F" />
</template>
<template #default>筛选</template>
</a-button>
<template #content>
<div>
<div class="flex items-center mb-24px">
<div class="w-70px">运营人员</div>
<a-space class="w-200px">
<CommonSelect
placeholder="请选择运营人员"
:options="operators"
v-model="query.operator"
@change="
(val) => {
handleFilterChange('operator_id', val, operators);
}
"
class="!w-200px"
/>
</a-space>
</div>
<div class="flex items-center mb-24px">
<div class="w-70px">发布平台</div>
<a-space class="w-200px">
<CommonSelect
:options="platformOptions"
v-model="query.platform"
@change="
(val) => {
handleFilterChange('platform', val, platformOptions);
}
"
class="!w-200px"
placeholder="请选择发布平台"
/>
</a-space>
</div>
<div class="flex items-center">
<div class="w-80px">账号名称</div>
<a-space class="w-200px">
<CommonSelect
v-model="query.accounts"
:options="accountList"
:multiple="true"
@change="
(val) => {
handleFilterChange('account_id', val, accountList);
}
"
class="!w-200px"
placeholder="请选择账号名称"
/>
</a-space>
</div>
</div>
</template>
</a-trigger>
</div> </div>
</div> </div>
<div class="flex justify-between items-start mt-16px" style="width: 100%"> <div class="flex justify-between items-start mt-16px" style="width: 100%">
@ -345,6 +277,8 @@ import TaskDetail from './components/TaskDetail.vue';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination'; import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import emptyIcon from '@/assets/img/media-account/icon-empty.png'; import emptyIcon from '@/assets/img/media-account/icon-empty.png';
import router from '@/router'; import router from '@/router';
import colorTip from './components/colorTip.vue';
import FilterPopup from './components/filter-popup.vue';
const { const {
dataSource, dataSource,
@ -359,13 +293,13 @@ const {
DEFAULT_PAGE_INFO, DEFAULT_PAGE_INFO,
} = useTableSelectionWithPagination({ } = useTableSelectionWithPagination({
onPageChange: () => { onPageChange: () => {
query.page = pageInfo.page; query.page = pageInfo.value.page;
query.page_size = pageInfo.page_size; query.page_size = pageInfo.value.page_size;
handleSearch(); handleSearch();
}, },
onPageSizeChange: () => { onPageSizeChange: () => {
query.page = pageInfo.page; query.page = pageInfo.value.page;
query.page_size = pageInfo.page_size; query.page_size = pageInfo.value.page_size;
handleSearch(); handleSearch();
}, },
}); });
@ -867,8 +801,8 @@ const handleFilterChange = (field: string, value: any, options?: any[]) => {
// 获取数据 // 获取数据
const handleSearch = () => { const handleSearch = () => {
console.log('handleSearch查询参数:', query); console.log('handleSearch查询参数:', query);
query.page = pageInfo.page; query.page = pageInfo.value.page;
query.page_size = pageInfo.page_size; query.page_size = pageInfo.value.page_size;
getTaskSchedules(query) getTaskSchedules(query)
.then((response) => { .then((response) => {
if (response.data) { if (response.data) {
@ -892,6 +826,7 @@ const getOperators = async () => {
value: op.id, value: op.id,
name: op.name, name: op.name,
})); }));
console.log('获取运营人员数据成功:', operatorsData, operators.value);
} }
} catch (error) { } catch (error) {
console.error('获取运营人员数据失败:', error); console.error('获取运营人员数据失败:', error);
@ -919,6 +854,7 @@ const getAccountList = async () => {
platform: account.platform, platform: account.platform,
icon: getPlatformIcon(account.platform), icon: getPlatformIcon(account.platform),
})); }));
console.log('获取账号数据成功:', accountData, accountList.value);
} }
} catch (error) {} } catch (error) {}
}; };

View File

@ -8936,6 +8936,11 @@ vue-eslint-parser@^9.0.0, vue-eslint-parser@^9.0.1, vue-eslint-parser@^9.1.0, vu
lodash "^4.17.21" lodash "^4.17.21"
semver "^7.3.6" semver "^7.3.6"
vue-lazyload@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/vue-lazyload/-/vue-lazyload-3.0.0.tgz"
integrity sha512-h2keL/Rj550dLgesgOtXJS9qOiSMmuJNeVlfNAYV1/IYwOQYaWk5mFJlwRxmZDK9YC5gECcFLYYj7z1lKSf9ug==
vue-router@^4.4.0: vue-router@^4.4.0:
version "4.5.1" version "4.5.1"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz" resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz"