This commit is contained in:
吴红兵
2025-12-02 10:37:49 +08:00
commit 1f645dad3e
1183 changed files with 147673 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
<template>
<el-dialog v-model="visible" :close-on-click-modal="false" :title="form.id ? $t('common.editBtn') : $t('common.addBtn')" draggable>
<el-form ref="dataFormRef" v-loading="loading" :model="form" :rules="dataRules" label-width="90px">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.wxAccountName')" prop="wxAccountName">
<el-input v-model="form.wxAccountName" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.wxAccountAppid')" prop="wxAccountAppid">
<el-input v-model="form.wxAccountAppid" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.openid')" prop="openid">
<el-input v-model="form.openid" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.nickname')" prop="nickname">
<el-input v-model="form.nickname" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.remark')" prop="remark">
<el-input v-model="form.remark" :placeholder="t('fans.inputremarkTip')" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('fans.tagIds')" prop="tagIds">
<el-select v-model="form.tagIds" :placeholder="t('fans.inputTagTip')" clearable multiple>
<el-option v-for="item in tagOption" :key="item.tagId" :label="item.tag" :value="item.tagId" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
<el-button type="primary" @click="onSubmit">{{ $t('common.confirmButtonText') }}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" name="wx-fans" setup>
import { addObj, getObj, putObj } from '/@/api/mp/wx-account-fans';
import { list } from '/@/api/mp/wx-account-tag';
import { useMessage } from '/@/hooks/message';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const visible = ref(false);
const loading = ref(false);
const wxAccountAppid = ref();
// 提交表单数据
const form = reactive({
id: '',
});
const dataRules = ref([]);
// 打开弹窗
const openDialog = (row: any, accountId: string) => {
visible.value = true;
form.id = row.id;
wxAccountAppid.value = accountId;
// 重置表单数据
if (dataFormRef.value) {
dataFormRef.value.resetFields();
}
if (form.id) {
getFansData();
}
getTagList();
};
const getFansData = () => {
loading.value = true;
getObj(form.id)
.then((res) => {
Object.assign(form, res.data);
})
.finally(() => {
loading.value = false;
});
};
// 提交
const onSubmit = () => {
dataFormRef.value.validate((valid: boolean) => {
if (!valid) {
return false;
}
loading.value = true;
if (form.id) {
putObj(form)
.then(() => {
useMessage().success(t('common.editSuccessText'));
visible.value = false; // 关闭弹窗
emit('refresh');
})
.catch((err: any) => {
useMessage().error(err.msg);
})
.finally(() => {
loading.value = false;
});
} else {
addObj(form)
.then(() => {
useMessage().success(t('common.addSuccessText'));
visible.value = false; // 关闭弹窗
emit('refresh');
})
.catch((err: any) => {
useMessage().error(err.msg);
})
.finally(() => {
loading.value = false;
});
}
});
};
const tagOption = ref([]);
const getTagList = () => {
list(wxAccountAppid.value).then((res) => {
tagOption.value = res.data;
});
};
// 暴露变量
defineExpose({
openDialog,
});
</script>
<style scoped></style>

View File

@@ -0,0 +1,24 @@
export default {
fans: {
index: '#',
importwxAccountFansTip: 'import WxAccountFans',
id: 'id',
openid: 'openid',
subscribeStatus: 'subscribeStatus',
subscribeTime: 'subscribeTime',
nickname: 'nickname',
gender: 'gender',
language: 'language',
country: 'country',
province: 'province',
isBlack: 'black',
city: 'city',
tagIds: 'tagIds',
headimgUrl: 'headimgUrl',
remark: 'remark',
wxAccountId: 'wxAccountId',
wxAccountName: 'wxAccountName',
wxAccountAppid: 'wxAccountAppid',
inputNicknameTip: 'input nickname',
},
};

View File

@@ -0,0 +1,26 @@
export default {
fans: {
index: '#',
importwxAccountFansTip: '导入微信公众号粉丝表',
id: '主键',
openid: '用户标识',
subscribeStatus: '订阅状态',
subscribeTime: '订阅时间',
nickname: '昵称',
gender: '性别',
language: '语言',
country: '国家',
province: '省份',
isBlack: '黑名单',
city: '城市',
tagIds: '分组',
headimgUrl: ' headimgUrl',
remark: '备注',
wxAccountId: '微信公众号ID',
wxAccountName: '微信公众号',
wxAccountAppid: '公众号appid',
inputremarkTip: '请输入备注',
inputTagTip: '请选择分组',
inputNicknameTip: '请输入粉丝昵称',
},
};

View File

@@ -0,0 +1,222 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-row v-show="showSearch">
<el-form ref="queryRef" :inline="true" :model="state.queryForm" @keyup.enter="getDataList">
<el-form-item :label="$t('fans.nickname')" prop="nickname">
<el-input v-model="state.queryForm.nickname" style="max-width: 180px" :placeholder="$t('fans.inputNicknameTip')" />
</el-form-item>
<el-form-item :label="$t('fans.wxAccountName')" prop="wxAccountAppid">
<el-select v-model="state.queryForm.wxAccountAppid" :placeholder="$t('fans.wxAccountName')" clearable>
<el-option v-for="item in accountList" :key="item.appid" :label="item.name" :value="item.appid" />
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
{{ $t('common.queryBtn') }}
</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button type="primary" class="ml10" icon="Sort" @click="asyncFans" v-auth="'mp_wxaccountfans_sync'">同步</el-button>
<right-toolbar
:export="'mp_wxaccountfans_sync'"
@exportExcel="exportExcel"
v-model:showSearch="showSearch"
class="ml10"
style="float: right; margin-right: 20px"
@queryTable="getDataList"
></right-toolbar>
</div>
</el-row>
<el-table
v-loading="state.loading"
:data="state.dataList"
style="width: 100%"
@sort-change="sortChangeHandle"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
>
<el-table-column :label="t('fans.index')" type="index" width="60" />
<el-table-column :label="t('fans.openid')" prop="openid" show-overflow-tooltip />
<el-table-column :label="t('fans.subscribeStatus')" prop="subscribeStatus" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="subscribe" :value="scope.row.subscribeStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="t('fans.subscribeTime')" prop="subscribeTime" show-overflow-tooltip />
<el-table-column :label="t('fans.nickname')" prop="nickname" show-overflow-tooltip />
<el-table-column :label="t('fans.language')" prop="language" show-overflow-tooltip />
<el-table-column :label="t('fans.isBlack')" prop="isBlack" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="blackList" :value="scope.row.isBlack"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="t('fans.tagIds')" prop="tagIds" show-overflow-tooltip>
<template #default="scope">
<span v-for="(tag, index) in scope.row.tagList" :key="index">
<el-tag>{{ tag.tag }} </el-tag>&nbsp;&nbsp;
</span>
</template>
</el-table-column>
<el-table-column :label="t('fans.remark')" prop="remark" show-overflow-tooltip />
<el-table-column :label="t('fans.wxAccountName')" prop="wxAccountName" show-overflow-tooltip />
<el-table-column :label="$t('common.action')" width="250" fixed="right">
<template #default="scope">
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog(scope.row, state.queryForm.wxAccountAppid)"
>{{ $t('common.editBtn') }}
</el-button>
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">{{ $t('common.delBtn') }} </el-button>
<el-button icon="CircleCheck" text type="primary" @click="handelUnBlack([scope.row.id])" v-if="scope.row.isBlack"> 取消拉黑 </el-button>
<el-button icon="warning" text type="primary" @click="handelBlack([scope.row.id])" v-else> 拉黑 </el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle" />
<form-dialog ref="formDialogRef" @refresh="getDataList"></form-dialog>
</div>
</div>
</template>
<script lang="ts" name="systemWxAccountFans" setup>
import { BasicTableProps, useTable } from '/@/hooks/table';
import { black, delObjs, fetchList, sync, unblack } from '/@/api/mp/wx-account-fans';
import { fetchAccountList } from '/@/api/mp/wx-account';
import { useMessage, useMessageBox } from '/@/hooks/message';
import { useI18n } from 'vue-i18n';
import { useDict } from '/@/hooks/dict';
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const { subscribe } = useDict('subscribe');
// 引入组件
const { t } = useI18n();
// 定义查询字典
const blackList = ref([
{
label: '是',
value: '1',
},
{
label: '否',
value: '0',
},
]);
// 定义变量内容
const formDialogRef = ref();
// 搜索变量
const queryRef = ref();
const showSearch = ref(true);
// 多选变量
const selectObjs = ref([]) as any;
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList,
createdIsNeed: false,
});
// table hook
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state);
const accountList = ref([]);
const getAccountList = () => {
fetchAccountList().then((res) => {
accountList.value = res.data;
if (accountList.value.length > 0) {
state.queryForm.wxAccountAppid = accountList.value[0].appid;
getDataList();
}
});
};
watch(
() => state.queryForm.wxAccountAppid,
() => {
getDataList();
}
);
const asyncFans = () => {
if (state.queryForm.wxAccountAppid) {
sync(state.queryForm.wxAccountAppid).then(() => {
useMessage().success('已开始从微信同步粉丝信息,建议等待后查询');
getDataList();
});
} else {
useMessage().error('请选择公众号');
}
};
onMounted(() => {
getAccountList();
});
// 清空搜索条件
const resetQuery = () => {
// 清空搜索条件
queryRef.value.resetFields();
// 清空多选
selectObjs.value = [];
getDataList();
};
// 导出excel
const exportExcel = () => {
downBlobFile('/mp/fans/export', state.queryForm, 'fans.xlsx');
};
// 删除操作
const handleDelete = (ids: string[]) => {
useMessageBox()
.confirm(t('common.delConfirmText'))
.then(() => {
delObjs(ids)
.then(() => {
getDataList();
useMessage().success(t('common.delSuccessText'));
})
.catch((err: any) => {
useMessage().error(err.msg);
});
});
};
const handelBlack = (ids: string[]) => {
useMessageBox()
.confirm('是否要拉黑用户')
.then(() => {
black(ids, state.queryForm.wxAccountAppid)
.then(() => {
getDataList();
useMessage().success('拉黑用户成功');
})
.catch((err: any) => {
useMessage().error(err.msg);
});
});
};
const handelUnBlack = (ids: string[]) => {
useMessageBox()
.confirm('是否要取消拉黑用户')
.then(() => {
unblack(ids, state.queryForm.wxAccountAppid)
.then(() => {
getDataList();
useMessage().success('设置成功');
})
.catch((err: any) => {
useMessage().error(err.msg);
});
});
};
</script>