065acdf5fd02cab9ef1f7be460a5b0776d996532..85f7bdb64b1f8b0fdaf58355a4f3fc389ec26ad0
2025-11-18 zhengyiming
feat: 新增审核撤回日志
85f7bd 对比 | 目录
2025-11-18 zhengyiming
fix: s
44f10c 对比 | 目录
8个文件已修改
3个文件已添加
523 ■■■■■ 已修改文件
src/constants/enum.ts 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/reward.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/log.ts 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useOpenLogHooks.ts 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/ParkBountyApply.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/typings.d.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/MaterialReview/MaterialReReviewList.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/MaterialReview/MaterialReview.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/MaterialReview/MaterialReviewDetail.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/MaterialReview/components/ParkBountyApplyRedoDialog.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/enum.ts
@@ -98,3 +98,98 @@
  [ExternalSystem.JYB]: '江佑共保运营端',
  [ExternalSystem.flexjob]: '灵工系统运营端',
};
export enum OperateHistoryTypeEnum {
  /**
   * 认证用户日志
   */
  CertifiedUser = 10,
  /**
   * 平台用户日志
   */
  PlatformUser = 11,
  /**
   * 用户认证审核日志
   */
  UserCertificationAudit = 12,
  /**
   * 公告日志
   */
  SystemNotice = 13,
  /**
   * 资讯管理日志
   */
  InformationForManage = 14,
  /**
   * 资讯审核日志
   */
  InformationWaitForCheck = 15,
  /**
   * 开户管理日志
   */
  WalletAccountOpen = 16,
  /**
   * 转账审核对单日志
   */
  alletSingleTransfer = 17,
  /**
   * 充值审核
   */
  WalletRecharge = 18,
  /**
   * 账户管理
   */
  AccountManage = 19,
  /**
   * 认证管理
   */
  UserCertificationManage = 20,
  /**
   * 批量转账审核日志
   */
  AuditWalletBatchTransfer = 21,
  /**
   * 行业机构审核日志
   */
  IndustryBodyAudit = 22,
  /**
   * 行业配套审核日志
   */
  IndustryMatingAudit = 23,
  /**
   * 甲方企业审核日志
   */
  FirstPartyCompanyAudit = 24,
  /**
   * 人资公司审核日志
   */
  ParkOrHRAudit = 25,
  /**
   * 行业机构管理日志
   */
  IndustryBodyManage = 26,
  /**
   * 行业配套管理日志
   */
  IndustryMatingManage = 27,
  /**
   * 甲方企业管理日志
   */
  FirstPartyCompanyManage = 28,
  /**
   * 人资公司管理日志
   */
  ParkOrHRManage = 29,
  /**
   * 客户管理日志
   */
  CustomerManage = 30,
  /**
   * 奖励配置日志
   */
  ParkRewardManage = 31,
  /**
   * 客户模板操作日志
   */
  CustomerContractTemplate = 32,
}
src/constants/reward.ts
@@ -22,6 +22,7 @@
}
export const BountyCheckStatusEnumText = {
  [BountyCheckStatusEnum.Redoed]: '已撤回',
  [BountyCheckStatusEnum.WaitCheck]: '待审核',
  [BountyCheckStatusEnum.CheckPassed]: '审核通过',
  [BountyCheckStatusEnum.CheckReject]: '审核未通过',
src/hooks/index.ts
@@ -11,3 +11,5 @@
export * from './table';
export * from './fourStreams';
export * from './industrialPark';
export * from './log';
export * from './useOpenLogHooks';
src/hooks/log.ts
New file
@@ -0,0 +1,145 @@
import * as operateHistoryServices from '@/services/api/OperateHistory';
import { OrderInputType } from '@bole-core/core';
import { useTable } from '@bole-core/components';
import { MaybeRef } from 'vue';
import { OperateHistoryTypeEnum } from '@/constants';
export enum OperateType {
  /**
   * 审核
   */
  Audit = 1,
  /**
   * 入账
   */
  Account = 2,
  /**
   * 上传发票
   */
  Invoice = 3,
}
export const OperateTypeText = {
  [OperateType.Audit]: '审核',
  [OperateType.Account]: '入账',
  [OperateType.Invoice]: '上传发票',
};
export type UseTableLogListOptions = {
  relationId: MaybeRef<string>;
  operateType?: MaybeRef<number>;
};
export function useTableLogList({ relationId, operateType }: UseTableLogListOptions) {
  const BaseState = {
    loading: true,
  };
  const state = reactive({ ...BaseState });
  const { getDataSource: getList, proTableProps } = useTable(
    async ({ pageIndex, pageSize }) => {
      try {
        let params: API.GetOperateHistoryInput = {
          pageModel: {
            rows: pageSize,
            page: pageIndex,
            orderInput: [{ property: 'creationTime', order: OrderInputType.Desc }],
          },
          relationId: unref(relationId),
        };
        const _operateType = unref(operateType);
        if (_operateType) {
          params.operateName = OperateTypeText[_operateType];
        }
        let res = await operateHistoryServices.getOperateHistoryByRelationId(params, {
          showLoading: !state.loading,
        });
        return res;
      } catch (error) {}
    },
    {
      queryKey: ['operateHistoryServices/getOperateHistoryByRelationId'],
      columnsRenderProps: {
        creationTime: {
          type: 'date',
          format: 'YYYY-MM-DD HH:mm:ss',
        },
      },
    }
  );
  const OperateHistoryTableColumns: API.CustomModuleColumnDto[] = [
    { id: '1', enCode: 'creatorName', name: '操作人' },
    { id: '2', enCode: 'creationTime', name: '操作时间', width: 180 },
    { id: '3', enCode: 'operateName', name: '操作' },
    { id: '4', enCode: 'operateContent', name: '操作内容' },
  ];
  return {
    state,
    getList,
    proTableProps,
    OperateHistoryTableColumns,
  };
}
export type UseTableLogListByTypeOptions = {
  relationId: MaybeRef<string>;
  operateHistoryType?: MaybeRef<OperateHistoryTypeEnum>;
};
export function useTableLogListByType({
  relationId,
  operateHistoryType,
}: UseTableLogListByTypeOptions) {
  const BaseState = {
    loading: true,
  };
  const state = reactive({ ...BaseState });
  const { getDataSource: getList, proTableProps } = useTable(
    async ({ pageIndex, pageSize }) => {
      try {
        let params: API.QueryOperateHistoryByTypeInput = {
          pageModel: {
            rows: pageSize,
            page: pageIndex,
            orderInput: [{ property: 'creationTime', order: OrderInputType.Desc }],
          },
          typeId: unref(relationId),
          operateHistoryType: unref(operateHistoryType),
        };
        let res = await operateHistoryServices.getOperateHistoryByType(params, {
          showLoading: !state.loading,
        });
        return res;
      } catch (error) {}
    },
    {
      queryKey: ['operateHistoryServices/getOperateHistoryByRelationId'],
      columnsRenderProps: {
        creationTime: {
          type: 'date',
          format: 'YYYY-MM-DD HH:mm:ss',
        },
      },
    }
  );
  const OperateHistoryTableColumns: API.CustomModuleColumnDto[] = [
    { id: '1', enCode: 'creatorName', name: '操作人' },
    { id: '2', enCode: 'creationTime', name: '操作时间', width: 180 },
    { id: '3', enCode: 'operateName', name: '操作' },
    { id: '4', enCode: 'operateContent', name: '操作内容' },
  ];
  return {
    state,
    getList,
    proTableProps,
    OperateHistoryTableColumns,
  };
}
src/hooks/useOpenLogHooks.ts
New file
@@ -0,0 +1,62 @@
import { useDialog } from '@bole-core/components';
import { OperateHistoryTypeEnum } from '@/constants';
type UseAdvertisementListOptions = {
  operateType?: MaybeRef<number>;
};
export function useOpenLogDialog(options: UseAdvertisementListOptions = {}) {
  const { operateType } = options;
  const relationId = ref('');
  const { dialogProps, dialogState } = useDialog();
  async function openLogDialog(_relationId: string) {
    relationId.value = _relationId;
    await nextTick();
    dialogState.dialogVisible = true;
  }
  const logDialogProps = computed(() => {
    return {
      ...dialogProps.value,
      relationId: relationId.value,
      operateType: unref(operateType),
    };
  });
  return {
    logDialogProps,
    openLogDialog,
  };
}
type UseOpenLogByTypeDialogOptions = {
  operateHistoryType?: MaybeRef<OperateHistoryTypeEnum>;
};
export function useOpenLogByTypeDialog(options: UseOpenLogByTypeDialogOptions = {}) {
  const { operateHistoryType } = options;
  const relationId = ref('');
  const { dialogProps, dialogState } = useDialog();
  async function openLogDialog(_relationId: string) {
    relationId.value = _relationId;
    await nextTick();
    dialogState.dialogVisible = true;
  }
  const logDialogProps = computed(() => {
    return {
      ...dialogProps.value,
      relationId: relationId.value,
      operateHistoryType: unref(operateHistoryType),
    };
  });
  return {
    logDialogProps,
    openLogDialog,
  };
}
src/services/api/ParkBountyApply.ts
@@ -931,6 +931,36 @@
  });
}
/** 政务端-材料审核-外部审核撤回 POST /api/ParkBountyApply/OutcheckParkBountyApplyRedoed */
export async function outcheckParkBountyApplyRedoed(
  body: API.OutcheckParkBountyApplyRedoedInput,
  options?: API.RequestConfig
) {
  return request<number>('/api/ParkBountyApply/OutcheckParkBountyApplyRedoed', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 外部审核撤回-复审撤回 POST /api/ParkBountyApply/OutcheckParkBountyApplyReRedoed */
export async function outcheckParkBountyApplyReRedoed(
  body: API.OutcheckParkBountyApplyRedoedInput,
  options?: API.RequestConfig
) {
  return request<number>('/api/ParkBountyApply/OutcheckParkBountyApplyReRedoed', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 政务端-材料审核-外部复审核 POST /api/ParkBountyApply/OutReCheckParkBountyApply */
export async function outReCheckParkBountyApply(
  body: API.OutReCheckParkBountyApplyInput,
src/services/api/typings.d.ts
@@ -9374,6 +9374,8 @@
    outReCheckStatus?: BountyCheckStatusEnum;
    /** 政务端复审时间 */
    outReCheckTime?: string;
    /** 撤回原因 */
    reasonForWithdrawal?: string;
  }
  interface GetParkBountyApplyListOutputPageOutput {
@@ -16676,6 +16678,12 @@
    extraListFiles?: CustomerUploadMonthApplyFileTypeDto[];
  }
  interface OutcheckParkBountyApplyRedoedInput {
    parkBountyApplyId?: string;
    /** 撤回原因 */
    reasonForWithdrawal?: string;
  }
  interface OutReCheckParkBountyApplyInput {
    parkBountyApplyId?: string;
    outReCheckStatus?: BountyCheckStatusEnum;
src/views/MaterialReview/MaterialReReviewList.vue
@@ -59,7 +59,9 @@
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
      <ParkBountyApplyRedoDialog v-bind="dialogProps" />
    </AppContainer>
    <OperateHistoryLogDialog v-bind="logDialogProps" />
  </LoadingLayout>
</template>
@@ -76,14 +78,21 @@
  QueryFilterItem,
  FieldDatePicker,
  FieldSelect,
  useFormDialog,
} from '@bole-core/components';
import { OrderInputType } from '@bole-core/core';
import { Message, OrderInputType } from '@bole-core/core';
import { format } from '@/utils';
import { BountyCheckStatusEnum, BountyCheckStatusEnumText, DataRangeEnumText } from '@/constants';
import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
import _ from 'lodash';
import { ModelValueType } from 'element-plus';
import { useAccess, useGlobalEventContext, useIndustrialParkDropDownList } from '@/hooks';
import {
  useAccess,
  useGlobalEventContext,
  useIndustrialParkDropDownList,
  useOpenLogDialog,
} from '@/hooks';
import ParkBountyApplyRedoDialog from './components/ParkBountyApplyRedoDialog.vue';
defineOptions({
  name: 'MaterialReviewList',
@@ -106,13 +115,14 @@
  },
  redoBtn: {
    emits: {
      onClick: (role) => goAudit(role),
      onClick: (role) => openDialog(role),
    },
    extraProps: {
      hide: (row: API.GetParkBountyApplyListOutput) =>
        row.outReCheckStatus !== BountyCheckStatusEnum.CheckPassed,
    },
  },
  logBtn: { emits: { onClick: (role) => openLogDialog(role.id) } },
};
const { checkSubModuleItemShow, column, operationBtns } = useAccess({
@@ -212,4 +222,34 @@
    },
  });
}
function openDialog(row: API.GetParkBountyApplyListOutput) {
  handleAdd({
    parkBountyApplyId: row.id,
  });
}
const { dialogProps, handleAdd, editForm } = useFormDialog({
  onConfirm: outcheckParkBountyApplyReRedoed,
  defaultFormParams: {
    reasonForWithdrawal: '',
    parkBountyApplyId: '',
  },
});
async function outcheckParkBountyApplyReRedoed() {
  try {
    let params: API.OutcheckParkBountyApplyRedoedInput = {
      parkBountyApplyId: editForm.parkBountyApplyId,
      reasonForWithdrawal: editForm.reasonForWithdrawal,
    };
    let res = await parkBountyApplyServices.outcheckParkBountyApplyReRedoed(params);
    if (res) {
      Message.successMessage('操作成功');
      getList(paginationState.pageIndex);
    }
  } catch (error) {}
}
const { openLogDialog, logDialogProps } = useOpenLogDialog();
</script>
src/views/MaterialReview/MaterialReview.vue
@@ -59,7 +59,9 @@
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
      <ParkBountyApplyRedoDialog v-bind="dialogProps" />
    </AppContainer>
    <OperateHistoryLogDialog v-bind="logDialogProps" />
  </LoadingLayout>
</template>
@@ -76,14 +78,21 @@
  QueryFilterItem,
  FieldDatePicker,
  FieldSelect,
  useFormDialog,
} from '@bole-core/components';
import { OrderInputType } from '@bole-core/core';
import { Message, OrderInputType } from '@bole-core/core';
import { format } from '@/utils';
import { BountyCheckStatusEnum, BountyCheckStatusEnumText, DataRangeEnumText } from '@/constants';
import * as parkBountyApplyServices from '@/services/api/ParkBountyApply';
import _ from 'lodash';
import { ModelValueType } from 'element-plus';
import { useAccess, useGlobalEventContext, useIndustrialParkDropDownList } from '@/hooks';
import {
  useAccess,
  useGlobalEventContext,
  useIndustrialParkDropDownList,
  useOpenLogDialog,
} from '@/hooks';
import ParkBountyApplyRedoDialog from './components/ParkBountyApplyRedoDialog.vue';
defineOptions({
  name: 'MaterialReviewList',
@@ -106,13 +115,14 @@
  },
  redoBtn: {
    emits: {
      onClick: (role) => goAudit(role),
      onClick: (role) => openDialog(role),
    },
    extraProps: {
      hide: (row: API.GetParkBountyApplyListOutput) =>
        row.outCheckStatus !== BountyCheckStatusEnum.CheckPassed,
    },
  },
  logBtn: { emits: { onClick: (role) => openLogDialog(role.id) } },
};
const { checkSubModuleItemShow, column, operationBtns } = useAccess({
@@ -203,6 +213,36 @@
    },
  });
}
function openDialog(row: API.GetParkBountyApplyListOutput) {
  handleAdd({
    parkBountyApplyId: row.id,
  });
}
const { dialogProps, handleAdd, editForm } = useFormDialog({
  onConfirm: outcheckParkBountyApplyRedoed,
  defaultFormParams: {
    reasonForWithdrawal: '',
    parkBountyApplyId: '',
  },
});
async function outcheckParkBountyApplyRedoed() {
  try {
    let params: API.OutcheckParkBountyApplyRedoedInput = {
      parkBountyApplyId: editForm.parkBountyApplyId,
      reasonForWithdrawal: editForm.reasonForWithdrawal,
    };
    let res = await parkBountyApplyServices.outcheckParkBountyApplyRedoed(params);
    if (res) {
      Message.successMessage('操作成功');
      getList(paginationState.pageIndex);
    }
  } catch (error) {}
}
const { openLogDialog, logDialogProps } = useOpenLogDialog();
</script>
<style lang="scss" scoped>
src/views/MaterialReview/MaterialReviewDetail.vue
@@ -13,8 +13,11 @@
                >
              </span>
              <span class="page-form-layout-title-item remark">
                <TextOverTooltip v-if="form.outCheckStatus === BountyCheckStatusEnum.CheckReject">
                  {{ `复审未通过原因:${form.outCheckRemark ?? ''}` }}
                <TextOverTooltip v-if="form.outReCheckStatus === BountyCheckStatusEnum.CheckReject">
                  {{ `复审未通过原因:${form.outReCheckRemark ?? ''}` }}
                </TextOverTooltip>
                <TextOverTooltip v-if="form.outReCheckStatus === BountyCheckStatusEnum.Redoed">
                  {{ `撤回原因:${form.reasonForWithdrawal ?? ''}` }}
                </TextOverTooltip>
              </span>
            </template>
@@ -28,6 +31,9 @@
              <span class="page-form-layout-title-item remark">
                <TextOverTooltip v-if="form.outCheckStatus === BountyCheckStatusEnum.CheckReject">
                  {{ `审核未通过原因:${form.outCheckRemark ?? ''}` }}
                </TextOverTooltip>
                <TextOverTooltip v-if="form.outCheckStatus === BountyCheckStatusEnum.Redoed">
                  {{ `撤回原因:${form.reasonForWithdrawal ?? ''}` }}
                </TextOverTooltip>
              </span>
            </template>
@@ -112,6 +118,7 @@
  outReCheckStatus: '' as any as BountyCheckStatusEnum,
  outReCheckRemark: '',
  reasonForWithdrawal: '',
  suportPlatRecharge: false,
  suportFinance: false,
@@ -165,6 +172,7 @@
    form.suportPlatRecharge = data.suportPlatRecharge;
    form.suportFinance = data.suportFinance;
    form.reasonForWithdrawal = data.reasonForWithdrawal ?? '';
    getList();
  },
src/views/MaterialReview/components/ParkBountyApplyRedoDialog.vue
New file
@@ -0,0 +1,76 @@
<template>
  <ProDialog title="撤回申报" v-model="visible" @close="onDialogClose" destroy-on-close draggable>
    <ProForm :model="form" ref="dialogForm" label-width="110px">
      <ProFormItemV2
        label="撤回原因"
        prop="reasonForWithdrawal"
        :check-rules="[{ message: '请输入撤回原因' }]"
      >
        <ProFormTextArea
          placeholder="请输入"
          v-model="form.reasonForWithdrawal"
          :maxlength="150"
          show-word-limit
        ></ProFormTextArea>
      </ProFormItemV2>
    </ProForm>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="emit('onCancel')">取 消</el-button>
        <el-button type="primary" @click="handleConfirm">确 定</el-button>
      </span>
    </template>
  </ProDialog>
</template>
<script setup lang="ts">
import { FormInstance } from 'element-plus';
import {
  ProDialog,
  ProForm,
  ProFormItemV2,
  ProFormTextArea,
  UploadUserFile,
} from '@bole-core/components';
defineOptions({
  name: 'ParkBountyApplyRedoDialog',
});
// type Props = {};
// const props = withDefaults(defineProps<Props>(), {});
const visible = defineModel({ type: Boolean });
type Form = {
  title?: string;
  reasonForWithdrawal: string;
  parkBountyApplyId: string;
};
const form = defineModel<Form>('form');
const emit = defineEmits<{
  (e: 'onConfirm'): void;
  (e: 'onCancel'): void;
}>();
const dialogForm = ref<FormInstance>();
function onDialogClose() {
  if (!dialogForm.value) return;
  dialogForm.value.resetFields();
}
function handleConfirm() {
  if (!dialogForm.value) return;
  dialogForm.value.validate((valid) => {
    if (valid) {
      emit('onConfirm');
    } else {
      return;
    }
  });
}
</script>