feat: 自动回复迁移

This commit is contained in:
hw
2025-11-04 16:53:08 +08:00
parent 7a5f4b01e2
commit 84795d10cd
28 changed files with 2060 additions and 103 deletions

View File

@@ -1,23 +1,26 @@
<script lang="ts" setup>
import type { MpAccountApi } from '#/api/mp/account';
import { onMounted, reactive, ref, unref } from 'vue';
import { computed, onMounted, reactive, ref, unref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useTabs } from '@vben/hooks';
import { message, Select } from 'ant-design-vue';
import { message, Select, SelectOption } from 'ant-design-vue';
import { getSimpleAccountList } from '#/api/mp/account';
import { useTagsViewStore } from '#/store/tagsView';
defineOptions({ name: 'WxAccountSelect' });
const emit = defineEmits<{
(e: 'change', id: number, name: string): void;
const props = defineProps<{
modelValue?: number;
}>();
// 消息弹窗
const { closeCurrentTab } = useTabs(); // 视图操作
const emit = defineEmits<{
(e: 'change', id: number, name: string): void;
(e: 'update:modelValue', id: number): void;
}>();
const { delView } = useTagsViewStore(); // 视图操作
const { push, currentRoute } = useRouter();
const account: MpAccountApi.AccountSimple = reactive({
@@ -27,37 +30,78 @@ const account: MpAccountApi.AccountSimple = reactive({
const accountList = ref<MpAccountApi.AccountSimple[]>([]);
// 计算当前选中的 ID优先使用 modelValue表单绑定否则使用内部 account.id
const currentId = computed({
get: () => {
// 如果外部传入了 modelValue优先使用外部的值
if (props.modelValue !== undefined && props.modelValue !== null) {
return props.modelValue;
}
return account.id;
},
set: (value: number) => {
// 更新内部状态
account.id = value;
// 同步到外部(表单系统)
emit('update:modelValue', value);
// 触发 change 事件(保持向后兼容)
const found = accountList.value.find(
(v: MpAccountApi.AccountSimple) => v.id === value,
);
if (found) {
account.name = found.name;
emit('change', value, found.name);
}
},
});
// 监听外部 modelValue 变化,同步到内部状态
watch(
() => props.modelValue,
(newValue) => {
if (
newValue !== undefined &&
newValue !== null &&
newValue !== account.id
) {
account.id = newValue;
const found = accountList.value.find(
(v: MpAccountApi.AccountSimple) => v.id === newValue,
);
if (found) {
account.name = found.name;
}
}
},
);
/** 查询公众号列表 */
async function handleQuery() {
accountList.value = await getSimpleAccountList();
if (accountList.value.length === 0) {
message.error('未配置公众号,请在【公众号管理 -> 账号管理】菜单,进行配置');
await closeCurrentTab(unref(currentRoute));
delView(unref(currentRoute));
await push({ name: 'MpAccount' });
return;
}
// 默认选中第一个
const firstAccount = accountList.value[0];
if (firstAccount) {
account.id = firstAccount.id;
if (account.id) {
account.name = firstAccount.name;
emit('change', account.id, account.name);
}
}
}
/** 公众号变化 */
function onChanged(value: any) {
if (value === undefined || Array.isArray(value)) return;
const id = typeof value === 'number' ? value : Number(value);
account.id = id;
const found = accountList.value.find(
(v: MpAccountApi.AccountSimple) => v.id === id,
);
if (account.id && found) {
account.name = found.name;
emit('change', account.id, account.name);
// 如果外部没有传入值modelValue 为空),默认选中第一个
if (props.modelValue === undefined || props.modelValue === null) {
const firstAccount = accountList.value[0];
if (firstAccount) {
currentId.value = firstAccount.id;
account.name = firstAccount.name;
emit('change', firstAccount.id, firstAccount.name);
}
} else {
// 如果外部有值,同步到内部状态
const found = accountList.value.find(
(v: MpAccountApi.AccountSimple) => v.id === props.modelValue,
);
if (found) {
account.id = props.modelValue;
account.name = found.name;
}
}
}
@@ -69,23 +113,12 @@ onMounted(() => {
<template>
<Select
v-model:value="account.id"
v-model:value="currentId"
placeholder="请选择公众号"
class="!w-240px"
@change="onChanged"
style="width: 240px"
>
<Select.Option
v-for="item in accountList"
:key="item.id"
:label="item.name"
:value="item.id"
>
<SelectOption v-for="item in accountList" :key="item.id" :value="item.id">
{{ item.name }}
</Select.Option>
</SelectOption>
</Select>
</template>
<style lang="scss" scoped>
:deep(.ant-select-selector) {
width: 240px !important;
}
</style>