Merge remote-tracking branch 'origin/main' into feature/0724_新媒体账号状态重构

# Conflicts:
#	src/views/property-marketing/media-account/account-manage/components/account-table/index.vue
#	src/views/property-marketing/put-account/account-data/components/filter-block/index.vue
#	src/views/property-marketing/put-account/account-manage/components/account-table/index.vue
#	src/views/property-marketing/put-account/account-manage/components/filter-block/index.vue
This commit is contained in:
rd
2025-07-25 10:33:58 +08:00
106 changed files with 2231 additions and 537 deletions

View File

@ -15,11 +15,11 @@
>
</div>
<div class="flex items-center">
<a-button class="w-110px search-btn mr-12px" size="medium" @click="handleExport">
<a-button type="outline" class="w-110px mr-12px" size="medium" @click="handleExport">
<template #icon> <icon-download /> </template>
<template #default>导出数据</template>
</a-button>
<a-button class="w-110px search-btn" size="medium" @click="openCustomColumn">
<a-button type="outline" class="w-110px" size="medium" @click="openCustomColumn">
<template #icon>
<img :src="icon1" width="14" height="14" />
</template>
@ -115,7 +115,7 @@
}}
</template>
<template v-else-if="column.dataIndex === 'operation'" #cell="{ record }">
<a-button type="outline" size="small" class="search-btn" @click="handleDetail(record)">详情</a-button>
<a-button type="outline" size="small" @click="handleDetail(record)">详情</a-button>
</template>
<template v-else-if="column.isRateField" #cell="{ record }">
@ -144,7 +144,7 @@
</a-table-column>
<a-table-column data-index="operation" fixed="right" width="100" title="操作">
<template #cell="{ record }">
<a-button type="outline" size="small" class="search-btn" @click="handleDetail(record)">详情</a-button>
<a-button type="outline" size="small" @click="handleDetail(record)">详情</a-button>
</template>
</a-table-column>
</template>

View File

@ -65,7 +65,7 @@
<template #footer>
<div style="text-align: right">
<a-button class="mr-8px cancel-btn" size="medium" @click="close">取消</a-button>
<a-button class="mr-8px" size="medium" @click="close">取消</a-button>
<a-button type="primary" size="medium" @click="onSubmit">确定</a-button>
</div>
</template>

View File

@ -87,13 +87,5 @@
}
}
.arco-modal-footer {
.cancel-btn {
border-radius: 4px;
border: 1px solid var(--BG-500, #b1b2b5);
background: var(--BG-white, #fff);
&:hover {
border: 1px solid var(--BG-500, #b1b2b5);
}
}
}
}

View File

@ -19,7 +19,7 @@
<div class="filter-row-item flex items-center">
<span class="label">分组</span>
<a-space class="w-200px">
<GroupSelect v-model="query.group_ids" multiple :options="groups" @change="handleSearch" />
<CommonSelect v-model="query.group_ids" :options="groups" @change="handleSearch" />
</a-space>
</div>
<div class="filter-row-item flex items-center">
@ -31,7 +31,7 @@
<div class="filter-row-item flex items-center">
<span class="label">运营人员</span>
<a-space class="w-160px">
<OperatorSelect v-model="query.operator_id" :options="operators" @change="handleSearch" />
<CommonSelect v-model="query.operator_id" :multiple="false" :options="operators" @change="handleSearch" />
</a-space>
</div>
</div>
@ -47,13 +47,13 @@
</a-select>
</a-space>
</div>
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
<a-button type="outline" class="w-84px mr-12px" size="medium" @click="handleSearch">
<template #icon>
<icon-search />
</template>
<template #default>搜索</template>
</a-button>
<a-button class="w-84px reset-btn" size="medium" @click="handleReset">
<a-button class="w-84px" size="medium" @click="handleReset">
<template #icon>
<icon-refresh />
</template>
@ -66,9 +66,8 @@
<script setup>
import { reactive, defineEmits, defineProps } from 'vue';
import { fetchAccountGroups, fetchAccountOperators } from '@/api/all/propertyMarketing';
import GroupSelect from '@/views/property-marketing/media-account/components/group-select';
import OperatorSelect from '@/views/property-marketing/media-account/components/operator-select';
import StatusSelect from '@/views/property-marketing/media-account/components/status-select';
import CommonSelect from '@/components/common-select';
const props = defineProps({
query: {

View File

@ -2,16 +2,6 @@
height: 100%;
display: flex;
flex-direction: column;
:deep(.search-btn) {
border-radius: 4px;
border: 1px solid var(--Brand-Brand-6, #6d4cfe);
color: #6d4cfe;
}
:deep(.reset-btn) {
border-radius: 4px;
border: 1px solid var(--BG-500, #b1b2b5);
background: var(--BG-white, #fff);
}
.filter-wrap {
border-radius: 8px;
border: 1px solid #e6e6e8;

View File

@ -36,13 +36,13 @@
/>
</a-space>
</div>
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
<a-button type="outline" class="w-84px mr-12px" size="medium" @click="handleSearch">
<template #icon>
<icon-search />
</template>
<template #default>搜索</template>
</a-button>
<a-button class="w-84px reset-btn" size="medium" @click="handleReset">
<a-button class="w-84px" size="medium" @click="handleReset">
<template #icon>
<icon-refresh />
</template>

View File

@ -19,16 +19,6 @@
padding: 10px 0;
align-items: center;
}
:deep(.search-btn) {
border-radius: 4px;
border: 1px solid var(--Brand-Brand-6, #6d4cfe);
color: #6d4cfe;
}
:deep(.reset-btn) {
border-radius: 4px;
border: 1px solid var(--BG-500, #b1b2b5);
background: var(--BG-white, #fff);
}
.table-wrap {
width: 100%;

View File

@ -15,7 +15,7 @@
<span>确认删除 {{ accountName }} 这个账号吗</span>
</div>
<template #footer>
<a-button class="cancel-btn" size="large" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px danger-btn" status="danger" size="large" @click="onDelete"
>确认删除</a-button
>

View File

@ -46,6 +46,30 @@
<span class="label">运营人员</span>
<span class="cts">{{ item.operator?.name || '-' }}</span>
</div>
<div class="field-row">
<span class="label">所属项目</span>
<span v-if="!item.projects.length" class="cts">-</span>
<div v-else class="flex items-center">
<a-tooltip
v-if="item.projects.length > 2"
position="bottom"
:content="
item.projects
.slice(2)
.map((v) => v.name)
.join(',')
"
>
<div class="tag-box">
<span class="text">{{ `+${item.projects.length - 2}` }}</span>
</div>
</a-tooltip>
<div v-for="(project, index) in item.projects.slice(0, 2)" :key="index" class="tag-box">
<span class="text">{{ project.name }}</span>
</div>
</div>
</div>
<div class="field-row">
<span class="label">分组</span>
<span class="cts">{{ item.group?.name || '-' }}</span>

View File

@ -9,7 +9,7 @@
<span>确认暂停同步 {{ accountName }} 这个账号的数据吗</span>
</div>
<template #footer>
<a-button class="cancel-btn" size="large" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px" size="large" @click="onConfirm">确定</a-button>
</template>
</a-modal>

View File

@ -1,9 +1,3 @@
@mixin ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-container {
flex: 1;
display: grid;

View File

@ -19,12 +19,11 @@ import {
Message as AMessage,
Textarea,
} from '@arco-design/web-vue';
import TagSelect from '@/views/property-marketing/media-account/components/tag-select';
import GroupSelect from '@/views/property-marketing/media-account/components/group-select';
import AuthorizedAccountModal from '../authorized-account-modal';
// import ImportPromptModal from '../import-prompt-modal';
import StatusBox from '@/views/property-marketing/media-account/components/status-select/status-box.tsx';
import SyncDataModal from '../sync-data-modal';
import CommonSelect from '@/components/common-select';
// import { downloadByUrl } from '@/utils/tools';
import { showExportNotification } from '@/utils/arcoD';
@ -37,6 +36,7 @@ import {
putMediaAccounts,
getTemplateUrl,
batchMediaAccounts,
getProjectList,
} from '@/api/all/propertyMarketing';
import icon1 from '@/assets/img/media-account/icon-download.png';
@ -58,6 +58,7 @@ const INITIAL_FORM = {
platform: 1,
group_id: undefined,
tag_ids: [],
project_ids: [],
end_work_link: undefined,
cookie: undefined,
};
@ -66,6 +67,7 @@ export default {
setup(props, { emit, expose }) {
const groupOptions = ref([]);
const tagOptions = ref([]);
const projects = ref([]);
const visible = ref(false);
const uploadType = ref('manual');
const uploadStatus = ref(UploadStatus.DEFAULT);
@ -126,6 +128,12 @@ export default {
tagOptions.value = data;
}
};
const getProjects = async () => {
const { code, data } = await getProjectList();
if (code === 200) {
projects.value = data;
}
};
function handleUpload(option) {
const { fileItem } = option;
uploadStatus.value = UploadStatus.WAITING;
@ -141,6 +149,9 @@ export default {
const reset = () => {
formRef.value?.resetFields();
formRef.value?.clearValidate();
groupOptions.value = [];
tagOptions.value = [];
projects.value = [];
form.value = cloneDeep(INITIAL_FORM);
fileName.value = '';
file.value = null;
@ -162,6 +173,7 @@ export default {
}
getGroups();
getTags();
getProjects();
visible.value = true;
};
const getAccountDetail = async () => {
@ -364,8 +376,16 @@ export default {
<FormItem label="号码持有人" field="holder_name">
<Input v-model={form.value.holder_name} placeholder="请输入..." class="w-240px" size="large" />
</FormItem>
<FormItem label="所属项目">
<CommonSelect
v-model={form.value.project_ids}
options={projects.value}
placeholder="请选择…"
size="large"
/>
</FormItem>
<FormItem label="选择分组">
<GroupSelect
<CommonSelect
v-model={form.value.group_id}
multiple={false}
options={groupOptions.value}
@ -373,8 +393,9 @@ export default {
size="large"
/>
</FormItem>
<FormItem label="选择标签">
<TagSelect v-model={form.value.tag_ids} options={tagOptions.value} placeholder="请选择…" size="large" />
<CommonSelect v-model={form.value.tag_ids} options={tagOptions.value} placeholder="请选择…" size="large" />
</FormItem>
<FormItem
label="笔记链接"
@ -406,7 +427,6 @@ export default {
v-model={form.value.cookie}
placeholder="请输入..."
size="large"
max-length={500}
auto-size={{ minRows: 5, maxRows: 8 }}
/>
</FormItem>
@ -415,7 +435,7 @@ export default {
)}
</Form>
<div style="display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px;">
<Button size="large" class="cancel-btn" onClick={onClose}>
<Button size="large" onClick={onClose}>
取消
</Button>
<Button type="primary" size="large" loading={importLoading.value} onClick={onSubmit}>

View File

@ -76,15 +76,10 @@
</div>
<template #footer>
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" class="cancel-btn" @click="handleRefreshQrCode">
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" @click="handleRefreshQrCode">
重新生成
</a-button>
<a-button
v-if="[MODAL_STATE.SUCCESS, MODAL_STATE.FAILED].includes(modalState)"
size="large"
class="cancel-btn"
@click="close"
>
<a-button v-if="[MODAL_STATE.SUCCESS, MODAL_STATE.FAILED].includes(modalState)" size="large" @click="close">
取消
</a-button>
<a-button type="primary" size="large" @click="handleOk">

View File

@ -30,7 +30,7 @@
<a-form-item label="选择分组" required>
<template v-if="editType === 'all'">
<div class="flex items-center w-100%">
<GroupSelect v-model="form.group_id" :options="groupOptions" :multiple="false" class="flex-1" />
<CommonSelect v-model="form.group_id" :options="groupOptions" :multiple="false" class="flex-1" />
</div>
</template>
</a-form-item>
@ -47,7 +47,7 @@
<a-table-column title="选择分组" data-index="group_id">
<template #cell="{ record }">
<div class="flex items-center w-100%">
<GroupSelect v-model="record.group_id" :options="groupOptions" :multiple="false" />
<CommonSelect v-model="record.group_id" :options="groupOptions" :multiple="false" />
</div>
</template>
</a-table-column>
@ -56,7 +56,7 @@
</template>
</a-form>
<template #footer>
<a-button size="large" class="mr-16px cancel-btn" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" size="large" @click="onSubmit">确定</a-button>
</template>
</a-modal>
@ -65,7 +65,7 @@
<script setup>
import { ref, reactive } from 'vue';
import { fetchAccountGroups, batchPutGroup } from '@/api/all/propertyMarketing';
import GroupSelect from '@/views/property-marketing/media-account/components/group-select';
import CommonSelect from '@/components/common-select';
import icon1 from '@/assets/img/icon-question.png';

View File

@ -76,7 +76,7 @@
</template>
</a-form>
<template #footer>
<a-button size="large" class="mr-16px cancel-btn" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" size="large" @click="onSubmit">确定</a-button>
</template>
</a-modal>

View File

@ -33,16 +33,20 @@
<span class="label">平台</span>
<a-space class="w-160px">
<a-select v-model="query.platform" size="medium" placeholder="全部" allow-clear @change="handleSearch">
<a-option v-for="(item, index) in PLATFORM_LIST" :key="index" :value="item.value" :label="item.label">{{
item.label
}}</a-option>
<a-option
v-for="(item, index) in MEDIA_ACCOUNT_PLATFORMS"
:key="index"
:value="item.value"
:label="item.label"
>{{ item.label }}</a-option
>
</a-select>
</a-space>
</div>
<div class="filter-row-item flex items-center">
<span class="label">运营人员</span>
<a-space class="w-160px">
<OperatorSelect v-model="query.operator_id" :options="operators" @change="handleSearch" />
<CommonSelect v-model="query.operator_id" :multiple="false" :options="operators" @change="handleSearch" />
</a-space>
</div>
</div>
@ -50,22 +54,28 @@
<div class="filter-row-item flex items-center">
<span class="label">分组</span>
<a-space class="w-200px">
<GroupSelect v-model="query.group_ids" multiple :options="groups" @change="handleSearch" />
<CommonSelect v-model="query.group_ids" multiple :options="groups" @change="handleSearch" />
</a-space>
</div>
<div class="filter-row-item flex items-center">
<span class="label">所属项目</span>
<a-space class="w-200px">
<CommonSelect v-model="query.project_ids" :options="projects" @change="handleSearch" />
</a-space>
</div>
<div class="filter-row-item flex items-center">
<span class="label">标签</span>
<a-space class="w-320px">
<TagSelect v-model="query.tag_ids" :options="tags" @change="handleSearch" />
<CommonSelect v-model="query.tag_ids" :options="tags" @change="handleSearch" />
</a-space>
</div>
<a-button class="w-84px search-btn mr-12px" size="medium" @click="handleSearch">
<a-button type="outline" class="w-84px mr-12px" size="medium" @click="handleSearch">
<template #icon>
<icon-search />
</template>
<template #default>搜索</template>
</a-button>
<a-button class="w-84px reset-btn" size="medium" @click="handleReset">
<a-button class="w-84px" size="medium" @click="handleReset">
<template #icon>
<icon-refresh />
</template>
@ -77,13 +87,17 @@
<script setup>
import { reactive, defineEmits, defineProps } from 'vue';
import { fetchAccountTags, fetchAccountGroups, fetchAccountOperators } from '@/api/all/propertyMarketing';
import TagSelect from '@/views/property-marketing/media-account/components/tag-select';
import GroupSelect from '@/views/property-marketing/media-account/components/group-select';
import OperatorSelect from '@/views/property-marketing/media-account/components/operator-select';
import {
fetchAccountTags,
getProjectList,
fetchAccountGroups,
fetchAccountOperators,
} from '@/api/all/propertyMarketing';
import StatusSelect from '@/views/property-marketing/media-account/components/status-select';
import CommonSelect from '@/components/common-select';
import { INITIAL_QUERY, PLATFORM_LIST } from '@/views/property-marketing/media-account/account-manage/constants';
import { INITIAL_QUERY } from '@/views/property-marketing/media-account/account-manage/constants';
import { MEDIA_ACCOUNT_PLATFORMS } from '@/utils/platform';
const props = defineProps({
query: {
@ -97,6 +111,7 @@ const emits = defineEmits('onSearch', 'onReset', 'update:query');
const tags = ref([]);
const groups = ref([]);
const operators = ref([]);
const projects = ref([]);
const handleSearch = () => {
emits('update:query', props.query);
@ -127,11 +142,18 @@ const getOperators = async () => {
operators.value = data;
}
};
const getProjects = async () => {
const { code, data } = await getProjectList();
if (code === 200) {
projects.value = data;
}
};
onMounted(() => {
getTags();
getGroups();
getOperators();
getProjects();
});
defineExpose({

View File

@ -16,7 +16,7 @@
</a-form-item>
</a-form>
<template #footer>
<a-button class="cancel-btn" @click="onClose">取消</a-button>
<a-button @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px" @click="onSubmit">确认</a-button>
</template>
</a-modal>

View File

@ -9,7 +9,7 @@
<span>确认删除 "{{ groupName }}" 这个分组吗</span>
</div>
<template #footer>
<a-button class="cancel-btn" size="large" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px danger-btn" status="danger" size="large" @click="onDelete"
>确认删除</a-button
>

View File

@ -21,7 +21,7 @@
</div>
</div>
<template #footer>
<a-button size="large" class="cancel-btn" @click="close">取消</a-button>
<a-button size="large" @click="close">取消</a-button>
<a-button type="primary" size="large" @click="handleOk"> 去授权 </a-button>
</template>
</a-modal>

View File

@ -92,13 +92,12 @@
</div>
<template #footer>
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" class="cancel-btn" @click="handleRefreshQrCode">
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" @click="handleRefreshQrCode">
重新生成
</a-button>
<a-button
v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED"
size="large"
class="cancel-btn"
@click="close"
>
取消

View File

@ -20,7 +20,7 @@
</div>
</div>
<template #footer>
<a-button size="large" class="cancel-btn" @click="close">稍后再说</a-button>
<a-button size="large" @click="close">稍后再说</a-button>
<a-button type="primary" size="large" @click="handleOk"> 更新数据 </a-button>
</template>
</a-modal>

View File

@ -1,7 +1,3 @@
<!--
* @Author: AI
* @Date: 2025-06-27
-->
<template>
<a-modal
v-model:visible="visible"
@ -16,7 +12,7 @@
</a-form-item>
</a-form>
<template #footer>
<a-button class="cancel-btn" @click="onClose">取消</a-button>
<a-button @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px" @click="onSubmit">确认</a-button>
</template>
</a-modal>

View File

@ -9,7 +9,7 @@
<span>确认删除 "{{ tagName }}" 这个标签吗</span>
</div>
<template #footer>
<a-button class="cancel-btn" size="large" @click="onClose">取消</a-button>
<a-button size="large" @click="onClose">取消</a-button>
<a-button type="primary" class="ml-16px danger-btn" status="danger" size="large" @click="onDelete"
>确认删除</a-button
>

View File

@ -9,6 +9,7 @@ export const INITIAL_QUERY = {
operator_id: '',
group_ids: [],
tag_ids: [],
project_ids: [],
};
export const INITIAL_PAGE_INFO = {

View File

@ -8,19 +8,19 @@
<div class="top flex h-64px px-24px py-10px justify-between items-center">
<p class="text-18px font-400 lh-26px color-#211F24 title">账号管理</p>
<div class="flex items-center">
<a-button class="w-112px mr-12px search-btn" size="medium" @click="handleOpenTagsModal">
<a-button class="w-112px mr-12px" type="outline" size="medium" @click="handleOpenTagsModal">
<template #icon>
<img :src="icon3" width="16" height="16" />
</template>
<template #default>标签管理</template>
</a-button>
<a-button class="w-112px mr-12px search-btn" size="medium" @click="handleOpenGroupModal">
<a-button class="w-112px mr-12px" type="outline" size="medium" @click="handleOpenGroupModal">
<template #icon>
<img :src="icon2" width="16" height="16" />
</template>
<template #default>分组管理</template>
</a-button>
<a-button type="primary" class="w-112px search-btn" size="medium" @click="handleOpenAccountModal">
<a-button type="primary" class="w-112px" size="medium" @click="handleOpenAccountModal">
<template #icon>
<img :src="icon1" width="16" height="16" />
</template>
@ -70,7 +70,7 @@
</template>
<div v-else>
<a-space v-if="isAbNormalStatus" class="flex items-center">
<a-button class="w-96px err-btn" size="mini" @click="handleOpenAbnormalAccount">
<a-button type="primary" status="danger" size="mini" @click="handleOpenAbnormalAccount">
<template #default>查看异常账号</template>
</a-button>
</a-space>

View File

@ -2,16 +2,6 @@
height: 100%;
display: flex;
flex-direction: column;
:deep(.search-btn) {
border-radius: 4px;
border: 1px solid var(--Brand-Brand-6, #6d4cfe);
color: #6d4cfe;
}
:deep(.reset-btn) {
border-radius: 4px;
border: 1px solid var(--BG-500, #b1b2b5);
background: var(--BG-white, #fff);
}
.filter-wrap {
.top {
.title {
@ -47,15 +37,6 @@
color: #211f24;
}
}
.err-btn {
background-color: #f64b31 !important;
color: var(--BG-white, #fff);
font-family: 'PingFang SC';
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 20px; /* 166.667% */
}
.operation-btn {
padding: 0;
cursor: pointer;

View File

@ -1,64 +0,0 @@
<!--
* @Author: RenXiaoDong
* @Date: 2025-06-25 14:02:40
-->
<template>
<a-select
v-model="selectedGroups"
:multiple="multiple"
size="medium"
:placeholder="placeholder"
allow-clear
:max-tag-count="3"
@change="handleChange"
>
<a-option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name">
{{ item.name }}
</a-option>
</a-select>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: {
type: [Array, String, Number],
default: () => [],
},
multiple: {
type: Boolean,
default: true,
},
placeholder: {
type: String,
default: '全部',
},
options: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['update:modelValue', 'change']);
const selectedGroups = ref(props.multiple ? [] : '');
// 监听外部传入的值变化
watch(
() => props.modelValue,
(newVal) => {
selectedGroups.value = newVal;
},
{ immediate: true },
);
// 监听内部值变化,向外部发送更新
watch(selectedGroups, (newVal) => {
emits('update:modelValue', newVal);
});
const handleChange = (value) => {
selectedGroups.value = value;
emits('change', value);
};
</script>

View File

@ -1,64 +0,0 @@
<!--
* @Author: RenXiaoDong
* @Date: 2025-06-25 14:02:40
-->
<template>
<a-select
v-model="selectedOperators"
:multiple="multiple"
size="medium"
:placeholder="placeholder"
allow-clear
@change="handleChange"
>
<a-option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name">
{{ item.name }}
</a-option>
</a-select>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: {
type: [Array, String, Number],
default: () => [],
},
multiple: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: '全部',
},
options: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['update:modelValue', 'change']);
const selectedOperators = ref(props.multiple ? [] : '');
// 监听外部传入的值变化
watch(
() => props.modelValue,
(newVal) => {
selectedOperators.value = newVal;
},
{ immediate: true },
);
// 监听内部值变化,向外部发送更新
watch(selectedOperators, (newVal) => {
emits('update:modelValue', newVal);
});
const handleChange = (value) => {
selectedOperators.value = value;
emits('change', value);
};
</script>

View File

@ -1,65 +0,0 @@
<!--
* @Author: RenXiaoDong
* @Date: 2025-06-25 14:02:40
-->
<template>
<a-select
v-model="selectedTags"
:multiple="multiple"
size="medium"
:placeholder="placeholder"
allow-clear
:max-tag-count="3"
@change="handleChange"
>
<a-option v-for="(item, index) in options" :key="index" :value="item.id" :label="item.name">
{{ item.name }}
</a-option>
</a-select>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: {
type: [Array, String, Number],
default: () => [],
},
multiple: {
type: Boolean,
default: true,
},
placeholder: {
type: String,
default: '全部',
},
options: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['update:modelValue', 'change']);
const selectedTags = ref(props.multiple ? [] : '');
// 监听外部传入的值变化
watch(
() => props.modelValue,
(newVal) => {
selectedTags.value = newVal;
},
{ immediate: true },
);
// 监听内部值变化,向外部发送更新
watch(selectedTags, (newVal) => {
emits('update:modelValue', newVal);
});
const handleChange = (value) => {
selectedTags.value = value;
emits('change', value);
};
</script>