wupengfei
7 天以前 a0c1d9021b1a65cc397a2c7a8a9d226c2d9f7539
feat: 企业
6个文件已添加
10个文件已修改
1026 ■■■■■ 已修改文件
.eslintrc-auto-import.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
auto-imports.d.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/portraitTable.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Account/AccountManageList.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CPersonManage/CPersonManageList.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CPersonManage/components/CPersonDetailDialog.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/FinanceManage/FinanceManageList.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/FinanceManage/components/FinanceDetailDialog.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/OperationManage/OperationManageList.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ProtocolManage/EditTemplate.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ProtocolManage/ProtocolManageList.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/TaskManage/TaskManageList.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/TaskManage/components/SignDetailView.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/TaskManage/components/TaskDetailView.vue 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.eslintrc-auto-import.json
@@ -91,6 +91,8 @@
    "ThemeColorName": true,
    "ThemeColors": true,
    "ThemeColorsType": true,
    "UsePortraitTableColumnsItem": true,
    "UsePortraitTableOptions": true,
    "VNode": true,
    "VerifyStatus": true,
    "VerifyStatusColor": true,
@@ -181,6 +183,8 @@
    "useModel": true,
    "useOmit": true,
    "useOmitProps": true,
    "usePortraitTable": true,
    "usePortraitTableWithAttachment": true,
    "useResizeHander": true,
    "useRoute": true,
    "useRouteView": true,
auto-imports.d.ts
@@ -180,6 +180,8 @@
  const useModel: typeof import('vue')['useModel']
  const useOmit: typeof import('./src/hooks/help')['useOmit']
  const useOmitProps: typeof import('./src/hooks/help')['useOmitProps']
  const usePortraitTable: typeof import('./src/hooks/portraitTable')['usePortraitTable']
  const usePortraitTableWithAttachment: typeof import('./src/hooks/portraitTable')['usePortraitTableWithAttachment']
  const useResizeHander: typeof import('./src/hooks/useResizeHander')['useResizeHander']
  const useRoute: typeof import('vue-router')['useRoute']
  const useRouteView: typeof import('./src/hooks/useRouteView')['useRouteView']
@@ -233,6 +235,9 @@
  // @ts-ignore
  export type { GlobalEvent, GlobalEventListener, GlobalEventContext } from './src/hooks/useEvent'
  import('./src/hooks/useEvent')
  // @ts-ignore
  export type { UsePortraitTableColumnsItem, UsePortraitTableOptions } from './src/hooks/portraitTable'
  import('./src/hooks/portraitTable')
}
// for vue template auto import
@@ -398,6 +403,8 @@
    readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
    readonly useOmit: UnwrapRef<typeof import('./src/hooks/help')['useOmit']>
    readonly useOmitProps: UnwrapRef<typeof import('./src/hooks/help')['useOmitProps']>
    readonly usePortraitTable: UnwrapRef<typeof import('./src/hooks/portraitTable')['usePortraitTable']>
    readonly usePortraitTableWithAttachment: UnwrapRef<typeof import('./src/hooks/portraitTable')['usePortraitTableWithAttachment']>
    readonly useResizeHander: UnwrapRef<typeof import('./src/hooks/useResizeHander')['useResizeHander']>
    readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
    readonly useRouteView: UnwrapRef<typeof import('./src/hooks/useRouteView')['useRouteView']>
src/hooks/index.ts
@@ -8,3 +8,4 @@
export * from './help';
export * from './dic';
export * from './menu';
export * from './portraitTable';
src/hooks/portraitTable.ts
New file
@@ -0,0 +1,50 @@
import { ColumnsRenderProps } from '@bole-core/components';
import { MaybeRef } from 'vue';
export type UsePortraitTableColumnsItem<TData extends object = object> = ColumnsRenderProps & {
  label?: string;
  key?: keyof TData;
};
export type UsePortraitTableOptions<TData extends object> = {
  data: Ref<TData>;
  columns?: UsePortraitTableColumnsItem<TData>[];
};
export function usePortraitTable<TData extends object>(options: UsePortraitTableOptions<TData>) {
  const portraitTableProps = computed(
    () =>
      ({
        data: options.data.value,
        columns: options.columns ?? [],
      } as any)
  );
  return {
    portraitTableProps,
  };
}
type UsePortraitTableWithAttachmentOptions<
  TData extends object,
  TAnnexItem extends object = object
> = UsePortraitTableOptions<TData> & {
  annexList: Ref<TAnnexItem[]>;
  columnsRenderProps?: { [key in keyof TAnnexItem]?: ColumnsRenderProps };
};
export function usePortraitTableWithAttachment<
  TData extends object,
  TAnnexItem extends object = object
>(options: UsePortraitTableWithAttachmentOptions<TData, TAnnexItem>) {
  const { annexList, columnsRenderProps } = options;
  const { portraitTableProps } = usePortraitTable(options);
  const portraitTableWithAttachmentProps = computed(() => ({
    annexList: annexList.value,
    portraitTableProps: portraitTableProps.value,
    columnsRenderProps,
  }));
  return { portraitTableWithAttachmentProps };
}
src/views/Account/AccountManageList.vue
@@ -44,7 +44,7 @@
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { RoleClientType } from '@/constants';
import { Message, OrderInputType } from '@bole-core/core';
import { Message } from '@bole-core/core';
import AddOrEditAccountDialog from './components/AddOrEditAccountDialog.vue';
defineOptions({
@@ -96,7 +96,7 @@
  },
  {
    defaultExtraParams: {
      orderInput: [{ property: 'id', order: OrderInputType.Desc }],
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
      keyword: '',
    },
    columnsRenderProps: {
src/views/CPersonManage/CPersonManageList.vue
@@ -80,7 +80,6 @@
import { useAccess, useGlobalEventContext } from '@/hooks';
import { Gender } from '@/constants';
import CPersonDetailDialog from './components/CPersonDetailDialog.vue';
import { OrderInputType } from '@bole-core/core';
import { convertApi2FormUrlOnlyOne, format } from '@/utils';
import { ModelValueType } from 'element-plus';
@@ -168,7 +167,7 @@
      realVerifyStatus: '' as any as boolean,
      nearlyHireDateTime: [] as unknown as ModelValueType,
      nearlySignDateTime: [] as unknown as ModelValueType,
      orderInput: [{ property: 'userId', order: OrderInputType.Desc }],
      orderInput: [{ property: 'userId', order: EnumPagedListOrder.Desc }],
    },
    queryKey: ['flexEnterpriseWokerServices/getUserClientList'],
    columnsRenderProps: {
src/views/CPersonManage/components/CPersonDetailDialog.vue
@@ -58,7 +58,6 @@
  ProFormInputNumber,
  defineColumns,
} from '@bole-core/components';
import { OrderInputType } from '@bole-core/core';
import _ from 'lodash';
import { setOSSLink } from '@/utils';
import {
@@ -165,7 +164,7 @@
  },
  {
    defaultExtraParams: {
      orderInput: [{ property: 'applyTime', order: OrderInputType.Desc }],
      orderInput: [{ property: 'applyTime', order: EnumPagedListOrder.Desc }],
    },
    columnsRenderProps: {
      applyTime: { type: 'date' },
src/views/FinanceManage/FinanceManageList.vue
New file
@@ -0,0 +1,149 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem tip-content="发布状态">
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="[
                { value: true, label: '发布中' },
                { value: false, label: '已停止' },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem tip-content="推荐状态">
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="[
                { value: true, label: '已推荐' },
                { value: false, label: '未推荐' },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem tip-content="发布时间">
            <FieldDatePicker
              v-model="extraParamState.beginDate"
              type="daterange"
              range-separator="~"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              @change="getList()"
            ></FieldDatePicker>
          </QueryFilterItem>
          <QueryFilterItem>
            <SearchInput
              v-model="extraParamState.keyword"
              style="width: 260px"
              placeholder="任务名称"
              @on-click-search="getList"
            >
            </SearchInput>
          </QueryFilterItem>
        </template>
      </ProTableQueryFilterBar>
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
    </AppContainer>
    <FinanceDetailDialog v-bind="dialogProps" />
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  ProTableQueryFilterBar,
  OperationBtnType,
  ProTableV2,
  SearchInput,
  LoadingLayout,
  AppContainer,
  QueryFilterItem,
  useTable,
  FieldDatePicker,
  FieldRadio,
  useFormDialog,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { ModelValueType } from 'element-plus';
import * as enterpriseServices from '@/services/api/enterprise';
import FinanceDetailDialog from './components/FinanceDetailDialog.vue';
defineOptions({
  name: 'FinanceManageList',
});
const operationBtnMap: Record<string, OperationBtnType> = {
  detailBtn: { emits: { onClick: (role) => openDialog(role) } },
};
const { column, operationBtns } = useAccess({
  operationBtnMap,
});
const router = useRouter();
const BaseState = {
  loading: true,
};
const state = reactive({ ...BaseState });
onMounted(async () => {
  await getList();
  state.loading = false;
});
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetEnterprisesQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        // searchKeys: extraParamState.keyword,
      };
      let res = await enterpriseServices.getEnterprises(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {}
  },
  {
    defaultExtraParams: {
      keyword: '',
      pageType: '' as any as number,
      status: '' as any as boolean,
      beginDate: [] as unknown as ModelValueType,
      endDate: [] as unknown as ModelValueType,
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
  }
);
const { dialogProps, handleEdit, editForm } = useFormDialog({
  defaultFormParams: {
    id: '',
  },
});
function openDialog(row) {
  handleEdit({
    id: row.id,
  });
}
</script>
src/views/FinanceManage/components/FinanceDetailDialog.vue
New file
@@ -0,0 +1,101 @@
<template>
  <ProDialog title="明细" v-model="visible" destroy-on-close draggable>
    <PortraitTable v-bind="portraitTableProps" label-width="140px" :col-number="2"></PortraitTable>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="emit('onCancel')" type="primary">确定</el-button>
      </span>
    </template>
  </ProDialog>
</template>
<script setup lang="ts">
import { ProDialog, toThousand } from '@bole-core/components';
import { usePortraitTable } from '@/hooks';
defineOptions({
  name: 'FinanceDetailDialog',
});
type Form = {
  name?: string;
};
const visible = defineModel({ type: Boolean });
const form = defineModel<Form>('form');
const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void;
  (e: 'onCancel'): void;
}>();
const { portraitTableProps } = usePortraitTable({
  data: form,
  columns: [
    {
      label: '付款人账户',
      key: 'name',
      type: 'text',
    },
    {
      label: '收款人账户',
      key: 'name',
      type: 'text',
    },
    {
      label: '付款人名称',
      key: 'name',
      type: 'text',
    },
    {
      label: '收款人名称',
      key: 'name',
      type: 'text',
    },
    {
      label: '付款人开户行',
      key: 'name',
      type: 'text',
    },
    {
      label: '收款人开户行',
      key: 'name',
      type: 'text',
    },
    {
      label: '币种',
      key: 'name',
      type: 'text',
    },
    {
      label: '交易金额',
      key: 'name',
      type: 'money',
    },
    {
      label: '用途',
      key: 'name',
      type: 'text',
    },
    {
      label: '摘要',
      key: 'name',
      type: 'text',
    },
    {
      label: '交易时间',
      key: 'name',
      type: 'text',
    },
    {
      label: '交易状态',
      key: 'name',
      type: 'text',
    },
  ],
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
</style>
src/views/OperationManage/OperationManageList.vue
@@ -7,7 +7,7 @@
            <FieldSelect
              v-model="extraParamState.pageType"
              placeholder="广告页面"
              :value-enum="FlexWorkerEleSignEnumText"
              :value-enum="[]"
              clearable
              @change="getAdvertiseOnShowList()"
            />
@@ -15,7 +15,10 @@
          <QueryFilterItem tip-content="状态">
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="FlexWorkerEleSignEnumText"
              :value-enum="[
                { value: true, label: '展示中' },
                { value: false, label: '已下架' },
              ]"
              buttonStyle
              showAllBtn
              @change="getAdvertiseOnShowList()"
@@ -89,7 +92,7 @@
import { FlexWorkerEleSignEnumText } from '@/constants';
import { ModelValueType } from 'element-plus';
import { format, setOSSLink, convertApi2FormUrl, convertFormUrl2Api } from '@/utils';
import { OrderInputType, Message } from '@bole-core/core';
import { Message } from '@bole-core/core';
defineOptions({
  name: 'OperationManageList',
@@ -158,10 +161,9 @@
      status: '' as any as boolean,
      beginDate: [] as unknown as ModelValueType,
      endDate: [] as unknown as ModelValueType,
      orderInput: [{ property: 'sort', order: OrderInputType.Asc }],
      orderInput: [{ property: 'sort', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
    columnPropsMap: ['advertiseBeginDate', 'advertiseEndDate'],
  }
);
src/views/ProtocolManage/EditTemplate.vue
New file
@@ -0,0 +1,196 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem>
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="[
                { value: 1, label: '待制版' },
                { value: 2, label: '已完成' },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem tip-content="客户上传时间">
            <FieldDatePicker
              v-model="extraParamState.beginDate"
              type="daterange"
              range-separator="~"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              @change="getList()"
            ></FieldDatePicker>
          </QueryFilterItem>
          <QueryFilterItem tip-content="制版时间">
            <FieldDatePicker
              v-model="extraParamState.beginDate"
              type="daterange"
              range-separator="~"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              @change="getList()"
            ></FieldDatePicker>
          </QueryFilterItem>
          <QueryFilterItem>
            <SearchInput
              v-model="extraParamState.keyword"
              style="width: 260px"
              placeholder="模板名称/ID/业务编码"
              @on-click-search="getList"
            >
            </SearchInput>
          </QueryFilterItem>
        </template>
        <template #btn>
          <el-button @click="openDialog()" icon="Plus" type="primary">新增模板</el-button>
        </template>
      </ProTableQueryFilterBar>
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
    </AppContainer>
    <AddOrEditTemplateDialog v-bind="dialogProps" />
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  ProTableQueryFilterBar,
  OperationBtnType,
  ProTableV2,
  SearchInput,
  LoadingLayout,
  AppContainer,
  QueryFilterItem,
  useTable,
  FieldDatePicker,
  FieldRadio,
  useFormDialog,
  UploadUserFile,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { ModelValueType } from 'element-plus';
import * as enterpriseServices from '@/services/api/enterprise';
import AddOrEditTemplateDialog from './components/AddOrEditTemplateDialog.vue';
import { Message } from '@bole-core/core';
defineOptions({
  name: 'EditTemplate',
});
const operationBtnMap: Record<string, OperationBtnType> = {
  editBtn: { emits: { onClick: (role) => openDialog(role) } },
  editTemplateBtn: {
    emits: { onClick: (role) => openDialog(role) },
    extraProps: {
      hide: (row) => false,
    },
  },
  downloadBtn: {
    emits: { onClick: (role) => handleDownload(role) },
  },
  delBtn: {
    emits: { onClick: (role) => handleDelete(role) },
    extraProps: {
      hide: (row) => false,
    },
  },
  logBtn: {
    emits: { onClick: (role) => openLogDialog(role) },
  },
};
const { column, operationBtns } = useAccess({
  operationBtnMap,
});
const router = useRouter();
const BaseState = {
  loading: true,
};
const state = reactive({ ...BaseState });
onMounted(async () => {
  await getList();
  state.loading = false;
});
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetEnterprisesQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        // searchKeys: extraParamState.keyword,
      };
      let res = await enterpriseServices.getEnterprises(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {}
  },
  {
    defaultExtraParams: {
      keyword: '',
      status: '' as any as boolean,
      beginDate: [] as unknown as ModelValueType,
      endDate: [] as unknown as ModelValueType,
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
  }
);
const { dialogProps, handleEdit, handleAdd, editForm } = useFormDialog({
  onConfirm: handleAddOrEdit,
  defaultFormParams: {
    id: '',
    templateId: '',
    name: '',
    bussinessCode: '',
    templateFileUrl: [] as UploadUserFile[],
    title: '新增模板',
  },
});
function openDialog(row?) {
  if (row) {
    handleEdit({
      id: '',
      name: '',
      bussinessCode: '',
      templateId: '',
      templateFileUrl: [] as UploadUserFile[],
    });
  } else {
    handleAdd();
  }
}
async function handleAddOrEdit() {}
function handleDownload(row) {}
async function handleDelete(row) {
  try {
    await Message.deleteMessage();
  } catch (error) {}
}
function openLogDialog(row) {}
</script>
src/views/ProtocolManage/ProtocolManageList.vue
New file
@@ -0,0 +1,112 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem>
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="[{ value: 1, label: '待制版' }]"
              buttonStyle
              showAllBtn
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem>
            <SearchInput
              v-model="extraParamState.keyword"
              style="width: 260px"
              placeholder="企业/甲方企业"
              @on-click-search="getList"
            >
            </SearchInput>
          </QueryFilterItem>
        </template>
      </ProTableQueryFilterBar>
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
    </AppContainer>
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  ProTableQueryFilterBar,
  OperationBtnType,
  ProTableV2,
  SearchInput,
  LoadingLayout,
  AppContainer,
  QueryFilterItem,
  useTable,
  FieldRadio,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import * as enterpriseServices from '@/services/api/enterprise';
defineOptions({
  name: 'ProtocolManageList',
});
const operationBtnMap: Record<string, OperationBtnType> = {
  editTemplateBtn: { emits: { onClick: (role) => goEdit(role) } },
};
const { column, operationBtns } = useAccess({
  operationBtnMap,
});
const router = useRouter();
const BaseState = {
  loading: true,
};
const state = reactive({ ...BaseState });
onMounted(async () => {
  await getList();
  state.loading = false;
});
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetEnterprisesQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        // searchKeys: extraParamState.keyword,
      };
      let res = await enterpriseServices.getEnterprises(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {}
  },
  {
    defaultExtraParams: {
      keyword: '',
      status: '',
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
  }
);
function goEdit(row) {
  router.push({
    name: 'EditTemplate',
    params: {
      id: row.id,
    },
  });
}
</script>
src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue
New file
@@ -0,0 +1,124 @@
<template>
  <ProDialog
    :title="form.title"
    v-model="visible"
    destroy-on-close
    draggable
    @close="onDialogClose"
  >
    <ProForm :model="form" ref="dialogForm" label-width="120px">
      <ProFormItemV2
        label="模板ID:"
        prop="templateId"
        :check-rules="[{ message: '请输入模板ID' }]"
      >
        <ProFormText
          placeholder="请输入模板ID"
          v-model.trim="form.templateId"
          :formatter="filterCN"
        ></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2
        label="通道:"
        prop="templateId"
        :check-rules="[{ message: '请选择电子签通道' }]"
      >
        <ProFormSelect
          placeholder="请选择电子签通道"
          v-model="form.templateId"
          :value-enum="[{ label: 1, value: '支付宝' }]"
        ></ProFormSelect>
      </ProFormItemV2>
      <ProFormItemV2
        label="业务编码:"
        prop="bussinessCode"
        :check-rules="[{ message: '请输入业务编码' }]"
      >
        <ProFormText
          placeholder="请输入业务编码"
          v-model.trim="form.bussinessCode"
          :maxlength="5"
          :formatter="filterNumbersFromString"
        ></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2 label="模板名称:" prop="name" :check-rules="[{ message: '请输入模板名称' }]">
        <ProFormText
          placeholder="请输入模板名称"
          v-model.trim="form.name"
          :maxlength="15"
        ></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2
        label="上传模板:"
        prop="templateFileUrl"
        :check-rules="[{ message: '请上传模板', type: 'upload' }]"
      >
        <ProFormUpload
          v-model:file-url="form.templateFileUrl"
          :limit="1"
          :limitFileSize="10"
          accept="pdf"
        ></ProFormUpload>
      </ProFormItemV2>
    </ProForm>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="handleConfirm">确 定</el-button>
      </span>
    </template>
  </ProDialog>
</template>
<script setup lang="ts">
import {
  ProDialog,
  UploadUserFile,
  ProForm,
  ProFormItemV2,
  ProFormText,
  ProFormUpload,
  ProFormSelect,
} from '@bole-core/components';
import { filterCN, filterNumbersFromString } from '@/utils';
import { FormInstance } from 'element-plus';
defineOptions({
  name: 'AddOrEditTemplateDialog',
});
const visible = defineModel({ type: Boolean });
type Form = {
  title?: string;
  id: string;
  templateId: string;
  name: string;
  bussinessCode: string;
  templateFileUrl: UploadUserFile[];
};
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>
src/views/TaskManage/TaskManageList.vue
@@ -3,19 +3,13 @@
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem>
            <FieldSelect
              v-model="extraParamState.pageType"
              placeholder="广告页面"
              :value-enum="FlexWorkerEleSignEnumText"
              clearable
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem tip-content="发布状态">
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="FlexWorkerEleSignEnumText"
              :value-enum="[
                { value: true, label: '发布中' },
                { value: false, label: '已停止' },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
@@ -24,7 +18,10 @@
          <QueryFilterItem tip-content="推荐状态">
            <FieldRadio
              v-model="extraParamState.status"
              :value-enum="FlexWorkerEleSignEnumText"
              :value-enum="[
                { value: true, label: '已推荐' },
                { value: false, label: '未推荐' },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
@@ -69,13 +66,11 @@
  QueryFilterItem,
  useTable,
  FieldDatePicker,
  FieldSelect,
  FieldRadio,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { FlexWorkerEleSignEnumText } from '@/constants';
import { ModelValueType } from 'element-plus';
import { OrderInputType } from '@bole-core/core';
import * as enterpriseServices from '@/services/api/enterprise';
defineOptions({
  name: 'OperationManageList',
@@ -83,13 +78,13 @@
const operationBtnMap: Record<string, OperationBtnType> = {
  detailBtn: { emits: { onClick: (role) => goDetail(role) } },
  takeOnBtn: {
  recommendBtn: {
    emits: { onClick: (role) => setAdvertiseOnShowStatus(role) },
    extraProps: {
      hide: (row) => row.status,
    },
  },
  takeDownBtn: {
  cancelRecommendBtn: {
    emits: { onClick: (role) => setAdvertiseOnShowStatus(role) },
    props: { type: 'danger' },
    extraProps: {
@@ -123,15 +118,15 @@
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetUserClientForBackInput = {
      let params: API.GetEnterprisesQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        searchKeys: extraParamState.keyword,
        // searchKeys: extraParamState.keyword,
      };
      let res = await flexEnterpriseWokerServices.getUserClientList(params, {
      let res = await enterpriseServices.getEnterprises(params, {
        showLoading: !state.loading,
      });
      return res;
@@ -144,10 +139,9 @@
      status: '' as any as boolean,
      beginDate: [] as unknown as ModelValueType,
      endDate: [] as unknown as ModelValueType,
      orderInput: [{ property: 'sort', order: OrderInputType.Asc }],
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
    columnPropsMap: ['advertiseBeginDate', 'advertiseEndDate'],
  }
);
@@ -157,6 +151,6 @@
}
function goDetail(row) {
  router.push({ name: 'TaskDetail', params: { id: row?.id ?? '' } });
  router.push({ name: 'TaskManageDetail', params: { id: row?.id ?? '' } });
}
</script>
src/views/TaskManage/components/SignDetailView.vue
@@ -1,13 +1,103 @@
<template>
  <div>SignDetailView</div>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableV2 v-bind="proTableProps" :columns="column" :operationBtns="operationBtns">
      </ProTableV2>
    </AppContainer>
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  OperationBtnType,
  ProTableV2,
  LoadingLayout,
  AppContainer,
  useTable,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { ModelValueType } from 'element-plus';
import * as enterpriseServices from '@/services/api/enterprise';
defineOptions({
  name: 'SignDetailView',
});
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
</style>
const operationBtnMap: Record<string, OperationBtnType> = {
  detailBtn: { emits: { onClick: (role) => goDetail(role) } },
  recommendBtn: {
    emits: { onClick: (role) => setAdvertiseOnShowStatus(role) },
    extraProps: {
      hide: (row) => row.status,
    },
  },
  cancelRecommendBtn: {
    emits: { onClick: (role) => setAdvertiseOnShowStatus(role) },
    props: { type: 'danger' },
    extraProps: {
      hide: (row) => !row.status,
    },
  },
};
const { checkSubModuleItemShow, column, operationBtns } = useAccess({
  operationBtnMap,
});
const router = useRouter();
const BaseState = {
  loading: true,
};
const state = reactive({ ...BaseState });
onMounted(async () => {
  await getList();
  state.loading = false;
});
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetEnterprisesQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        // searchKeys: extraParamState.keyword,
      };
      let res = await enterpriseServices.getEnterprises(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {}
  },
  {
    defaultExtraParams: {
      keyword: '',
      pageType: '' as any as number,
      status: '' as any as boolean,
      beginDate: [] as unknown as ModelValueType,
      endDate: [] as unknown as ModelValueType,
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
    },
    columnsRenderProps: {},
  }
);
async function setAdvertiseOnShowStatus(row) {
  try {
  } catch (error) {}
}
function goDetail(row) {
  router.push({ name: 'TaskManageDetail', params: { id: row?.id ?? '' } });
}
</script>
src/views/TaskManage/components/TaskDetailView.vue
@@ -6,16 +6,107 @@
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="任务名称:" prop="name">
                <ProFormText v-model.trim="detail.name" />
                <ProFormText v-model.trim="detail.enterpriseName" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormItemV2 label="服务费:" prop="salaryType">
              <RadioWithExtra
                v-model="detail.enterpriseName"
                :value-enum="[
                  { value: 1, text: '按月' },
                  { value: 2, text: '按日' },
                ]"
                enumLabelKey="text"
                enum-value-key="value"
                :showExtra="true"
              >
                <template #extra>
                  <ProFormInputNumber
                    :controls="false"
                    v-model="detail.enterpriseName"
                    :unit="detail.enterpriseName === '' ? '元/月' : '元/日'"
                  ></ProFormInputNumber>
                </template>
              </RadioWithExtra>
            </ProFormItemV2>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="结算方式:" prop="salaryType">
                <ProFormRadio
                  v-model="detail.enterpriseName"
                  :value-enum="[
                    { label: '月结', value: 1 },
                    { label: '日结', value: 2 },
                  ]"
                />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="任务名称:" prop="name"> </ProFormItemV2>
              <ProFormItemV2 label="福利:" prop="salaryType">
                <ProFormRadio v-model="detail.enterpriseName" :value-enum="dictionaryDataList" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="年龄范围:" prop="ageRange">
                <ProFormInputNumber v-model="detail.enterpriseName"></ProFormInputNumber>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="性别需求:" prop="salaryType">
                <ProFormRadio
                  v-model="detail.enterpriseName"
                  :value-enum="[
                    { label: '男', value: 1 },
                    { label: '女', value: 2 },
                  ]"
                />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="资格证书:" prop="salaryType">
                <ProFormRadio v-model="detail.enterpriseName" :value-enum="dictionaryDataList" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="任务地点:" prop="areaList">
                <!-- <ProFromAddressSelectV2
                  v-model:areaList="detail.areaList"
                  areaListPlaceholder="请选择"
                  :layer="AreaType.Area"
                /> -->
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="任务时间:" prop="creationTime" mode="read">
                <ProFormDatePicker
                  v-model="detail.enterpriseName"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
        </ProForm>
        <template #footer>
          <el-button @click="handleBack">关闭</el-button>
        </template>
      </PageFormLayout>
    </AppContainer>
  </LoadingLayout>
@@ -32,8 +123,12 @@
  ProFormItemV2,
  ProFormText,
  ProFormInputNumber,
  ProFormRadio,
  ProFormDatePicker,
} from '@bole-core/components';
import { useQuery } from '@tanstack/vue-query';
import { AreaType } from '@/constants';
import * as enterpriseServices from '@/services/api/enterprise';
defineOptions({
  name: 'TaskDetailView',
@@ -41,15 +136,30 @@
const route = useRoute();
const id = route.params?.id as string;
const { closeViewPush } = useRouteView();
const { dictionaryDataList } = useDictionaryDataSelect({
  categoryCode: computed(() => CategoryCode.Welfare),
});
const { data: detail, isLoading } = useQuery({
  queryKey: ['customerServices/getParkCustomerManageBaseDetail', id],
  queryKey: ['enterpriseServices/getEnterprise', id],
  queryFn: async () => {
    return await customerServices.getParkCustomerManageBaseDetail({ id: id });
    return await enterpriseServices.getEnterprise(
      { id: id },
      {
        showLoading: false,
      }
    );
  },
  placeholderData: () => ({} as API.GetUserClientForBackOutput),
  enabled: !!id,
  placeholderData: () => ({} as API.GetEnterpriseQueryResult),
  enabled: computed(() => !!id),
});
function handleBack() {
  closeViewPush(route, {
    name: 'TaskManageList',
  });
}
</script>
<style lang="scss" scoped>