123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912 |
- // @ts-check
- /**
- * @this {import('@/views/announcement/types').AnnouncementComponent & Vue}
- */
- /**
- * @typedef {import("@/api/announcement").NoticeRecord} NoticeRecord
- */
- import { getList, update, add, getAnnouncement, getCategoryList, deleteNotice } from "@/api/announcement";
- import { getCustomerList } from "@/api/common/index";
- import { mapGetters } from "vuex";
- import {
- ROLE_OPTIONS,
- STATUS_OPTIONS,
- ANNOUNCEMENT_STATUS,
- ROLE_TYPES,
- getRoleLabel,
- getRoleTagType,
- getStatusLabel,
- getStatusTagType,
- calculateRolesMask,
- parseRolesMask,
- getVisibleRolesText,
- getVisibleRolesTextArray
- } from '@/views/announcement/constants';
- /**
- * 角色类型定义
- * @typedef {import('@/views/announcement/constants').RoleType} RoleType
- */
- /**
- * 可见角色掩码类型定义
- * @typedef {import('@/views/announcement/constants').VisibleRolesMask} VisibleRolesMask
- */
- /**
- * 角色选项类型定义
- * @typedef {import('@/views/announcement/constants').RoleOption} RoleOption
- */
- /**
- * 公告状态类型定义
- * @typedef {import('@/views/announcement/constants').AnnouncementStatus} AnnouncementStatus
- */
- /**
- * 公告数据项类型定义
- * @typedef {import('@/api/types/announcement').NoticeRecord} NoticeItem
- */
- /**
- * 分类选项类型定义
- * @typedef {import('@/api/types/announcement').CategoryOption} CategoryOption
- */
- /**
- * 分页信息类型定义
- * @typedef {Object} PageInfo
- * @property {number} pageSize - 页大小(默认10)
- * @property {number} currentPage - 当前页(从1开始)
- * @property {number} total - 总记录数
- */
- /**
- * 查询参数类型定义
- * @typedef {import('@/api/types/announcement').NoticeQueryParams} QueryParams
- */
- /**
- * 表格配置列定义
- * @typedef {Object} TableColumn
- * @property {string} label - 列标签
- * @property {string} prop - 属性名
- * @property {string} [type] - 输入类型
- * @property {number} [span] - 栅格占位
- * @property {boolean} [search] - 是否可搜索
- * @property {boolean} [overHidden] - 是否超出隐藏
- * @property {Array<Object>} [rules] - 验证规则
- * @property {Array<Object>} [dicData] - 字典数据
- * @property {Object} [props] - 属性配置
- * @property {boolean} [slot] - 是否使用插槽
- * @property {boolean} [addDisplay] - 新增时是否显示
- * @property {boolean} [editDisplay] - 编辑时是否显示
- * @property {boolean} [hide] - 是否隐藏
- * @property {number} [width] - 列宽度
- * @property {boolean} [multiple] - 是否多选
- * @property {string} [format] - 格式化
- * @property {string} [valueFormat] - 值格式化
- * @property {boolean} [showColumn] - 是否显示列
- * @property {number} [minRows] - 最小行数
- * @property {string} [component] - 组件名称
- * @property {Object} [options] - 组件选项
- */
- /**
- * 表格配置选项
- * @typedef {Object} TableOption
- * @property {string} height - 表格高度
- * @property {number} calcHeight - 计算高度
- * @property {number} dialogWidth - 对话框宽度
- * @property {number} labelWidth - 标签宽度
- * @property {boolean} tip - 是否显示提示
- * @property {boolean} searchShow - 是否显示搜索
- * @property {number} searchMenuSpan - 搜索菜单占位
- * @property {boolean} border - 是否显示边框
- * @property {boolean} index - 是否显示序号
- * @property {boolean} viewBtn - 是否显示查看按钮
- * @property {boolean} selection - 是否显示选择框
- * @property {boolean} excelBtn - 是否显示导出按钮
- * @property {boolean} columnBtn - 是否显示列设置按钮
- * @property {boolean} delBtn - 是否显示删除按钮
- * @property {boolean} dialogClickModal - 对话框点击遮罩是否关闭
- * @property {Array<TableColumn>} column - 列配置
- */
- /**
- * 公告管理混入
- * @mixin AnnouncementIndexMixin
- */
- /**
- * 客户黑名单选项类型定义
- * @typedef {import('@/api/types/announcement').CustomerBlacklistItem} CustomerBlacklistOption
- */
- export default {
- name: 'AnnouncementIndexMixin',
- data() {
- return {
- /** @type {Partial<NoticeRecord>} 表单数据 */
- form: {},
- /** @type {Partial<QueryParams>} 查询参数 */
- query: {},
- /** @type {boolean} 加载状态 */
- loading: true,
- /** @type {boolean} 详情对话框显示状态 */
- detailVisible: false,
- /** 用于全屏预览的可见性控制 */
- announcementPreviewVisible: false,
- /** @type {Partial<NoticeRecord>} 当前查看的详情数据 */
- currentDetail: {},
- /** @type {PageInfo} 分页信息 */
- page: {
- pageSize: 10,
- currentPage: 1,
- total: 0
- },
- /** @type {Array<NoticeItem>} 选中的数据列表 */
- selectionList: [],
- /** @type {Array<CategoryOption>} 分类选项列表 */
- categoryOptions: [],
- /** @type {Array<RoleOption>} 角色选项列表 */
- roleOptions: ROLE_OPTIONS,
- /** @type {Array<CustomerBlacklistOption>} 客户黑名单选项列表 */
- customerBlacklistOptions: [],
- /** @type {Array<import("@/api/types/announcement").CustomerBlacklistItem>} 当前客户黑名单 */
- currentCustomerBlacklist: [],
- /** @type {boolean} 客户选项加载状态 */
- customerOptionsLoading: false,
- /** @type {boolean} 公告表单组件显示状态 */
- announcementFormVisible: false,
- /** @type {boolean} 是否为编辑模式 */
- isEditMode: false,
- /** @type {string|null} 编辑的公告ID */
- editAnnouncementId: null,
- /** @type {TableOption} 表格配置选项 */
- option: {
- height: 'auto',
- calcHeight: 30,
- dialogWidth: 1000,
- labelWidth: 120,
- tip: false,
- searchShow: true,
- searchMenuSpan: 6,
- border: true,
- index: true,
- viewBtn: false,
- selection: true,
- excelBtn: false,
- columnBtn: false,
- delBtn: false,
- dialogClickModal: false,
- column: [
- {
- label: "公告标题",
- prop: "title",
- span: 12,
- search: true,
- overHidden: true,
- rules: [{
- required: true,
- message: "请输入公告标题",
- trigger: "blur"
- }]
- },
- {
- label: "分类",
- prop: "categoryName",
- type: "select",
- dicData: [],
- props: {
- label: "name",
- value: "name"
- },
- slot: true,
- search: true,
- span: 12,
- searchProp: "categoryId",
- rules: [{
- required: true,
- message: "请选择分类",
- trigger: "change"
- }]
- },
- {
- label: "组织名称",
- prop: "orgName",
- span: 12,
- overHidden: true,
- rules: [{
- required: true,
- message: "请输入组织名称",
- trigger: "blur"
- }]
- },
- {
- label: "组织ID",
- prop: "orgId",
- span: 12,
- type: "number",
- rules: [{
- required: true,
- message: "请输入组织ID",
- trigger: "blur"
- }]
- },
- {
- label: "组织编码",
- prop: "orgCode",
- span: 12,
- rules: [{
- required: true,
- message: "请输入组织编码",
- trigger: "blur"
- },{
- pattern: /^[A-Za-z0-9_-]+$/,
- message: "组织编码只能包含大写字母、数字、下划线和中横线",
- trigger: "blur"
- }]
- },
- {
- label: "可见角色",
- prop: "visibleRoles",
- type: "select",
- multiple: true,
- dicData: ROLE_OPTIONS,
- slot: true,
- span: 12,
- props: {
- label: "label",
- value: "value"
- },
- rules: [{
- required: true,
- message: "请选择可见角色",
- trigger: "change"
- }]
- },
- {
- label: "状态",
- prop: "status",
- type: "select",
- dicData: STATUS_OPTIONS,
- slot: true,
- addDisplay: true,
- editDisplay: true,
- // width: 80
- },
- {
- label: "创建时间",
- prop: "createTime",
- type: "datetime",
- format: "yyyy-MM-dd HH:mm:ss",
- valueFormat: "yyyy-MM-dd HH:mm:ss",
- addDisplay: false,
- editDisplay: false,
- overHidden: true,
- width: 150
- },
- {
- label: "分类名称",
- prop: "categoryName",
- hide: true,
- addDisplay: false,
- editDisplay: false
- },
- {
- label: "备注",
- prop: "remark",
- type: "textarea",
- span: 24,
- minRows: 3,
- hide: true
- },
- {
- label: "公告内容",
- prop: "content",
- component: 'AvueUeditor',
- options: {
- action: '/api/blade-resource/oss/endpoint/put-file',
- props: {
- res: "data",
- url: "link",
- }
- },
- showColumn: false,
- hide: true,
- minRows: 6,
- span: 24,
- rules: [{
- required: true,
- message: "请输入公告内容",
- trigger: "blur"
- }]
- },
- {
- label: "品牌范围",
- prop: "brandScope",
- type: "json",
- hide: true,
- span: 24
- },
- {
- label: "客户黑名单",
- prop: "customerBlacklist",
- slot: true,
- hide: true,
- span: 24
- }
- ]
- },
- /** @type {Array<NoticeItem>} 表格数据 */
- data: []
- };
- },
- computed: {
- ...mapGetters(["permission", "userInfo"]),
- /**
- * 权限列表
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @returns {Object} 权限配置对象
- */
- permissionList() {
- return {
- addBtn: true,
- viewBtn: false,
- delBtn: false,
- editBtn: true,
- };
- },
- /**
- * 选中的ID字符串
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @returns {string} 逗号分隔的ID字符串
- */
- ids() {
- /** @type {Array<string>} */
- const ids = [];
- this.selectionList.forEach((/** @type {NoticeItem} */ ele) => {
- ids.push(ele.id);
- });
- return ids.join(",");
- }
- },
- /**
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- */
- created() {
- this.loadCategoryOptions();
- },
- watch: {
- announcementFormVisible(val) {
- if (val === true) {
- // 打开表单时,立即重新加载分类列表(表单与列表都会受益)
- this.loadCategoryOptions();
- } else {
- // 关闭表单后,avue-crud 会通过 v-if 重新渲染,需等 DOM 恢复后再刷新字典
- this.$nextTick(() => this.loadCategoryOptions());
- }
- },
- announcementPreviewVisible(val) {
- if (val === true) {
- // 打开预览时不需要刷新列表
- } else {
- // 关闭预览后,avue-crud 会通过 v-if 重新渲染,需等 DOM 恢复后再刷新字典
- this.$nextTick(() => this.loadCategoryOptions());
- }
- }
- },
- methods: {
- // 导入常量工具函数
- calculateRolesMask,
- parseRolesMask,
- getVisibleRolesText,
- getVisibleRolesTextArray,
- getRoleLabel,
- getRoleTagType,
- getStatusTagType,
- getStatusLabel,
- getStatusText: getStatusLabel,
- // 页面显示时触发:刷新分类列表(最小改动)
- onShow() {
- // 打印触发标识,便于排查
- console.log('[公告] onShow 勾子触发');
- // 重新加载分类下拉数据
- this.loadCategoryOptions();
- },
- /**
- * 加载分类选项
- * @async
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @returns {Promise<void>}
- * @throws {Error} 当加载分类选项失败时抛出错误
- */
- async loadCategoryOptions() {
- try {
- const response = await getCategoryList();
- const categoryData = response.data?.data || [];
- /** @type {Array<CategoryOption>} */
- this.categoryOptions = categoryData
- .filter(item => item.status === 1 && item.isDeleted === 0)
- .map(item => ({
- id: item.id,
- name: item.name,
- value: item.name,
- label: item.name,
- orgId: item.orgId,
- orgName: item.orgName,
- sortOrder: item.sortOrder || 0
- }))
- .sort((a, b) => a.sortOrder - b.sortOrder);
- // 更新表格列配置中的字典数据
- const categoryColumn = this.option.column.find((/** @type {TableColumn} */ col) => col.prop === 'categoryName');
- if (categoryColumn) {
- categoryColumn.dicData = this.categoryOptions;
- // 重新初始化 avue-crud 的字典,确保搜索下拉及时更新
- if (this.$refs && this.$refs.crud && typeof this.$refs.crud.dicInit === 'function') {
- this.$nextTick(() => this.$refs.crud.dicInit());
- }
- }
- } catch (error) {
- console.error('加载分类选项失败:', error);
- this.$message.error('加载分类选项失败,使用默认分类');
- // 使用默认分类选项
- /** @type {Array<CategoryOption>} */
- this.categoryOptions = [
- { id: 1, name: '系统公告', value: '系统公告', label: '系统公告', sortOrder: 0 },
- { id: 2, name: '部门公告', value: '部门公告', label: '部门公告', sortOrder: 1 }
- ];
- const categoryColumn = this.option.column.find((/** @type {TableColumn} */ col) => col.prop === 'categoryName');
- if (categoryColumn) {
- categoryColumn.dicData = this.categoryOptions;
- // 重新初始化 avue-crud 的字典,确保搜索下拉及时更新
- if (this.$refs && this.$refs.crud && typeof this.$refs.crud.dicInit === 'function') {
- this.$nextTick(() => this.$refs.crud.dicInit());
- }
- }
- }
- },
- /**
- * 查看详情(支持行内操作)- 改为进入全屏预览模式
- * @async
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {Partial<NoticeRecord>} [row] - 可选,当前行数据
- * @returns {Promise<void>}
- * @throws {Error} 当获取详情失败时抛出错误
- */
- async handleDetail(row) {
- const id = row && row.id ? row.id : (this.selectionList[0] && this.selectionList[0].id);
- if (!id) {
- this.$message.warning("请选择一条数据查看详情");
- return;
- }
- try {
- const response = await getAnnouncement(id);
- this.currentDetail = response.data?.data || {};
- // 打开全屏预览
- this.announcementPreviewVisible = true;
- } catch (error) {
- console.error('获取详情失败:', error);
- this.$message.error('获取详情失败,请稍后重试');
- }
- },
- /**
- * 关闭全屏预览并返回列表
- */
- handlePreviewBack() {
- this.announcementPreviewVisible = false;
- // 可按需清理当前详情
- // this.currentDetail = {};
- },
- // 新增:单行删除(操作列按钮)
- /**
- * 行删除(操作列按钮)
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {Partial<NoticeItem>} row - 当前行数据
- * @returns {Promise<void>}
- */
- async handleRowDelete(row) {
- const id = row && row.id;
- if (!id) {
- this.$message.warning("缺少公告ID,无法删除");
- return;
- }
- try {
- await this.$confirm("确定将选择数据删除?", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- });
- await deleteNotice(id);
- this.$message({
- type: "success",
- message: "操作成功!"
- });
- // 刷新列表
- this.onLoad(this.page, this.query);
- } catch (error) {
- if (error !== 'cancel') {
- console.error('删除公告失败:', error);
- this.$message({
- type: "error",
- message: "删除失败,请稍后重试"
- });
- } else {
- this.$message({
- type: "info",
- message: "已取消删除"
- });
- }
- }
- },
- /**
- * 保存行数据
- * @async
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {NoticeItem} row - 行数据
- * @param {Function} done - 完成回调
- * @param {Function} loading - 加载回调
- * @returns {Promise<void>}
- * @throws {Error} 当保存失败时抛出错误
- */
- async rowSave(row, done, loading) {
- // 新增操作现在由表单组件处理,此方法已废弃
- console.warn('rowSave方法已废弃,请使用表单组件进行新增操作');
- done();
- },
- /**
- * 更新行数据
- * @async
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {NoticeItem} row - 行数据
- * @param {number} index - 行索引
- * @param {Function} done - 完成回调
- * @param {Function} loading - 加载回调
- * @returns {Promise<void>}
- * @throws {Error} 当更新失败时抛出错误
- */
- async rowUpdate(row, index, done, loading) {
- // 编辑操作现在由表单组件处理,此方法已废弃
- console.warn('rowUpdate方法已废弃,请使用表单组件进行编辑操作');
- done();
- },
- /**
- * 搜索变化事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {QueryParams} params - 搜索参数
- * @param {Function} done - 完成回调
- */
- searchChange(params, done) {
- /** @type {QueryParams} */
- this.query = params || {};
- this.onLoad(this.page, this.query);
- done();
- },
- /**
- * 搜索重置事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- */
- searchReset() {
- /** @type {QueryParams} */
- this.query = {};
- this.onLoad(this.page);
- },
- /**
- * 选择变化事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {Array<NoticeItem>} list - 选中的数据列表
- */
- selectionChange(list) {
- /** @type {Array<NoticeItem>} */
- this.selectionList = Array.isArray(list) ? list : [];
- },
- /**
- * 当前页变化事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {number} currentPage - 当前页码(从1开始)
- */
- currentChange(currentPage) {
- if (typeof currentPage === 'number' && currentPage > 0) {
- this.page.currentPage = currentPage;
- }
- },
- /**
- * 页大小变化事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {number} pageSize - 页大小
- */
- sizeChange(pageSize) {
- if (typeof pageSize === 'number' && pageSize > 0) {
- this.page.pageSize = pageSize;
- }
- },
- /**
- * 刷新变化事件
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- */
- refreshChange() {
- // 刷新列表与分类字典
- this.loadCategoryOptions();
- this.onLoad(this.page, this.query);
- },
- /**
- * 打开前回调
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @async
- * @param {Function} done - 完成回调
- * @param {string} type - 操作类型(add/edit/view)
- * @returns {Promise<void>}
- * @throws {Error} 当获取详情失败时抛出错误
- */
- async beforeOpen(done, type) {
- // 对于新增和编辑操作,使用表单组件
- if (type === "add") {
- this.isEditMode = false;
- this.editAnnouncementId = null;
- this.announcementFormVisible = true;
- done();
- return;
- } else if (type === "edit") {
- this.isEditMode = true;
- this.editAnnouncementId = this.form?.id || null;
- this.announcementFormVisible = true;
- done();
- return;
- }
- // 对于查看操作,保持原有逻辑
- if (type === "view") {
- try {
- if (!this.form?.id) {
- this.$message.error('缺少公告ID,无法获取详情');
- done();
- return;
- }
- const response = await getAnnouncement(this.form.id);
- const formData = response.data?.data || {};
- /** @type {{visibleRoles: Array<RoleType>, customerBlackList: Array<import("@/views/announcement/types").CustomerBlacklistItem>, BrandScope: Array<import("@/api/types/announcement").BrandScopeItem>}} */
- const convertType = {
- visibleRoles: [],
- customerBlackList: [],
- BrandScope: [],
- }
- // 将掩码值转换为数值数组格式供表单使用
- if (typeof formData.visibleRoles === 'number') {
- const roleObjects = this.parseRolesMask(formData.visibleRoles || 0);
- convertType.visibleRoles = roleObjects.map(role => role.value);
- } else if (typeof formData.visibleRoles === 'string') {
- const roleValues = formData.visibleRoles ? parseInt(formData.visibleRoles) : 0;
- let roleObjects = this.parseRolesMask(roleValues)
- convertType.visibleRoles = roleObjects.map(role => role.value);
- } else {
- convertType.visibleRoles = [];
- }
- // 确保客户黑名单是数组格式
- /** @type {Array<import("@/views/announcement/types").CustomerBlacklistItem>} */
- const tmpCustomerData = JSON.parse(formData.customerBlacklist || '[]')
- convertType.customerBlackList = tmpCustomerData.map(item => ({
- ...item,
- }))
- // 如果有客户黑名单数据,设置到选项中以便显示
- if (convertType.customerBlackList.length > 0) {
- /** @type {Array<CustomerBlacklistOption>} */
- this.customerBlacklistOptions = convertType.customerBlackList.map(item => ({
- id: item.ID,
- Customer_NAME: item.NAME,
- Customer_CODE: item.CODE,
- }))
- }
- /** @type {Array<import("@/api/types/announcement").BrandScopeItem>} */
- const tmpBrandData = JSON.parse(formData.brandScope || '[]')
- convertType.BrandScope = tmpBrandData.map(item => ({
- ...item,
- }))
- this.form = {
- ...formData,
- ...convertType,
- };
- } catch (error) {
- console.error('获取详情失败:', error);
- this.$message.error('获取详情失败,请稍后重试');
- }
- }
- done();
- },
- /**
- * 加载数据
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @async
- * @param {PageInfo} page - 分页信息
- * @param {QueryParams} [params={}] - 查询参数
- * @returns {Promise<void>}
- * @throws {Error} 当加载数据失败时抛出错误
- */
- async onLoad(page, params = {}) {
- this.loading = true;
- try {
- // 参数验证
- if (!page || typeof page.currentPage !== 'number' || typeof page.pageSize !== 'number') {
- throw new Error('分页参数无效');
- }
- /** @type {QueryParams} */
- const query = {
- ...params,
- current: page.currentPage,
- size: page.pageSize
- };
- const response = await getList(page.currentPage, page.pageSize, query);
- const data = response.data.data;
- if (!data) {
- throw new Error('响应数据格式错误');
- }
- this.page.total = data.total || 0;
- /** @type {Array<NoticeItem>} */
- this.data = Array.isArray(data.records) ? data.records : [];
- } catch (error) {
- console.error('加载数据失败:', error);
- this.$message.error(`加载数据失败: ${error.message || '未知错误'}`);
- // 设置默认值避免页面异常
- this.page.total = 0;
- /** @type {Array<NoticeItem>} */
- this.data = [];
- } finally {
- this.loading = false;
- }
- },
- /**
- * 远程搜索客户数据
- * @async
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {string} query - 搜索关键词
- * @returns {Promise<void>}
- * @throws {Error} 当搜索客户失败时抛出错误
- */
- async remoteSearchCustomers(query) {
- if (!query || typeof query !== 'string' || query.trim().length < 1) {
- /** @type {Array<CustomerBlacklistOption>} */
- this.customerBlacklistOptions = [];
- return;
- }
- this.customerOptionsLoading = true;
- try {
- const response = await getCustomerList(1, 50, {
- customerName: query.trim()
- });
- if (response.data && response.data.success && response.data.data) {
- const customers = response.data.data.records || [];
- this.currentCustomerBlacklist = customers.map(c => ({
- id: c.Customer_ID,
- Customer_NAME: c.Customer_NAME,
- Customer_CODE: c.Customer_CODE,
- Customer_ShortName: c.Customer_ShortName
- }))
- this.customerBlacklistOptions = customers.map(customer => ({
- id: customer.Customer_ID,
- Customer_NAME: customer.Customer_NAME,
- Customer_CODE: customer.Customer_CODE,
- Customer_ShortName: customer.Customer_ShortName
- }));
- } else {
- /** @type {Array<CustomerBlacklistOption>} */
- this.customerBlacklistOptions = [];
- }
- } catch (error) {
- console.error('获取客户列表失败:', error);
- this.$message.error('获取客户列表失败,请稍后重试');
- /** @type {Array<CustomerBlacklistOption>} */
- this.customerBlacklistOptions = [];
- } finally {
- this.customerOptionsLoading = false;
- }
- },
- /**
- * 客户黑名单选择变化处理
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {Array<CustomerBlacklistOption>} selectedCustomers - 选中的客户列表
- */
- handleCustomerBlacklistChange(selectedCustomers) {
- if (!Array.isArray(selectedCustomers)) {
- /** @type {Array<CustomerBlacklistOption>} */
- this.form.customerBlacklist = [];
- return;
- }
- /** @type {Array<CustomerBlacklistOption>} */
- this.form.customerBlacklist = selectedCustomers;
- },
- /**
- * 获取客户显示名称
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- * @param {CustomerBlacklistOption} customer - 客户对象
- * @returns {string} 显示名称
- */
- getCustomerDisplayName(customer) {
- if (!customer || typeof customer !== 'object') {
- return '';
- }
- const name = customer.Customer_NAME || '';
- const code = customer.Customer_CODE || '';
- return code ? `${name}(${code})` : name;
- },
- /**
- * 清空客户搜索结果
- * @this {import('@/views/announcement/types').AnnouncementComponent & import('vue').default}
- */
- clearCustomerOptions() {
- this.customerBlacklistOptions = [];
- },
- /**
- * 处理表单组件返回事件
- */
- handleFormBack() {
- this.announcementFormVisible = false;
- this.isEditMode = false;
- this.editAnnouncementId = null;
- },
- /**
- * 处理表单保存成功事件
- */
- handleFormSaveSuccess() {
- this.announcementFormVisible = false;
- this.isEditMode = false;
- this.editAnnouncementId = null;
- // 刷新分类字典
- this.loadCategoryOptions();
- // 刷新列表数据
- this.onLoad(this.page);
- }
- }
- };
|