wupengfei
7 天以前 42d60f50072ebde98549157420bd18639712af43
feat: 1.2.0.1
6个文件已添加
13个文件已修改
958 ■■■■■ 已修改文件
.eslintrc-auto-import.json 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
auto-imports.d.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/task.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/user.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useUser.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/typings.d.ts 129 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/services/api/user.ts 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/CheckReceiveTaskDetail.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/components/AddOrEditEmploymentView.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/components/CheckManageDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/components/ManualCheckManageDialog.vue 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/constants/columns.ts 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/UserManage/UserManageList.vue 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/UserManage/components/AddOrEditUserDialog.vue 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/UserManage/constants/columns.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/UserManage/constants/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.eslintrc-auto-import.json
@@ -98,6 +98,7 @@
    "EnumUserGenderTextForPerson": true,
    "EnumUserRealMethod": true,
    "EnumUserStatus": true,
    "EnumUserStatusText": true,
    "EnumUserType": true,
    "EnumUserTypeText": true,
    "EnumUserWalletTransactionType": true,
@@ -269,6 +270,7 @@
    "useTaskSelect": true,
    "useTemplateRef": true,
    "useUser": true,
    "useUserInfoRoles": true,
    "useVModel": true,
    "useVModels": true,
    "watch": true,
auto-imports.d.ts
@@ -105,6 +105,7 @@
  const EnumUserInfoStatus: typeof import('./src/constants/apiEnum')['EnumUserInfoStatus']
  const EnumUserRealMethod: typeof import('./src/constants/apiEnum')['EnumUserRealMethod']
  const EnumUserStatus: typeof import('./src/constants/apiEnum')['EnumUserStatus']
  const EnumUserStatusText: typeof import('./src/constants/user')['EnumUserStatusText']
  const EnumUserType: typeof import('./src/constants/apiEnum')['EnumUserType']
  const EnumUserTypeText: typeof import('./src/constants/apiEnumText')['EnumUserTypeText']
  const EnumUserWalletTransactionType: typeof import('./src/constants/apiEnum')['EnumUserWalletTransactionType']
@@ -223,6 +224,7 @@
  const unref: typeof import('vue')['unref']
  const useAccess: typeof import('./src/hooks/useAccess')['useAccess']
  const useAllAreaList: typeof import('./src/hooks/dic')['useAllAreaList']
  const useAllRoleList: typeof import('./src/hooks/useUser')['useAllRoleList']
  const useArea: typeof import('./src/hooks/dic')['useArea']
  const useAreaByCascader: typeof import('./src/hooks/dic')['useAreaByCascader']
  const useAttrs: typeof import('vue')['useAttrs']
@@ -260,6 +262,7 @@
  const useTaskSelect: typeof import('./src/hooks/settlement')['useTaskSelect']
  const useTemplateRef: typeof import('vue')['useTemplateRef']
  const useUser: typeof import('./src/hooks/useUser')['useUser']
  const useUserInfoRoles: typeof import('./src/hooks/useUser')['useUserInfoRoles']
  const useVModel: typeof import('./src/hooks/help')['useVModel']
  const useVModels: typeof import('./src/hooks/help')['useVModels']
  const watch: typeof import('vue')['watch']
@@ -403,6 +406,7 @@
    readonly EnumUserGenderTextForPerson: UnwrapRef<typeof import('./src/constants/task')['EnumUserGenderTextForPerson']>
    readonly EnumUserRealMethod: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserRealMethod']>
    readonly EnumUserStatus: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserStatus']>
    readonly EnumUserStatusText: UnwrapRef<typeof import('./src/constants/user')['EnumUserStatusText']>
    readonly EnumUserType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserType']>
    readonly EnumUserTypeText: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumUserTypeText']>
    readonly EnumUserWalletTransactionType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumUserWalletTransactionType']>
@@ -552,6 +556,7 @@
    readonly useTaskSelect: UnwrapRef<typeof import('./src/hooks/settlement')['useTaskSelect']>
    readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
    readonly useUser: UnwrapRef<typeof import('./src/hooks/useUser')['useUser']>
    readonly useUserInfoRoles: UnwrapRef<typeof import('./src/hooks/useUser')['useUserInfoRoles']>
    readonly useVModel: UnwrapRef<typeof import('./src/hooks/help')['useVModel']>
    readonly useVModels: UnwrapRef<typeof import('./src/hooks/help')['useVModels']>
    readonly watch: UnwrapRef<typeof import('vue')['watch']>
src/constants/index.ts
@@ -16,3 +16,4 @@
export * from './enterpriseWallet';
export * from './finance';
export * from './common';
export * from './user';
src/constants/task.ts
@@ -84,6 +84,7 @@
  [EnumBillingMethod.Day]: '按日',
  [EnumBillingMethod.Hour]: '按时',
  [EnumBillingMethod.Piece]: '计件',
  // [EnumBillingMethod.face]: '面议',
};
export const EnumBillingMethodUnitText = {
src/constants/user.ts
New file
@@ -0,0 +1,4 @@
export const EnumUserStatusText = {
  [EnumUserStatus.Normal]: '启用',
  [EnumUserStatus.Disabled]: '禁用',
};
src/hooks/useUser.ts
@@ -1,6 +1,7 @@
import { useUserStore } from '@/store/modules/user';
import { UserUtils } from '@bole-core/core';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import * as userServices from '@/services/api/user';
export function useUser() {
  const userStore = useUserStore();
@@ -13,3 +14,33 @@
    userDetail: userDetail,
  };
}
type UseUserInfoRolesOptions = {
  userInfoId: MaybeRef<string>;
  userType: EnumUserType;
  clientType: EnumClientType;
};
export function useUserInfoRoles({ userInfoId, userType, clientType }: UseUserInfoRolesOptions) {
  const { data: userInfoRoles } = useQuery({
    queryKey: ['userServices/getUserInfoRoles'],
    queryFn: async () => {
      let res = await userServices.getUserInfoRoles(
        {
          userInfoId: unref(userInfoId),
          userType: userType,
          clientType: clientType,
        },
        { showLoading: false }
      );
      return res;
    },
    select(data) {
      return data;
    },
  });
  return {
    userInfoRoles,
  };
}
src/router/index.ts
@@ -394,6 +394,35 @@
      // },
    ],
  },
  {
    path: '/UserManage',
    redirect: 'noRedirect',
    component: Layout,
    hidden: false,
    alwaysShow: true,
    meta: {
      rank: 10100,
      title: '用户管理',
      rootMenu: true,
      icon: 'home',
    },
    children: [
      {
        path: '/UserManageList',
        name: 'UserManageList',
        hidden: false,
        alwaysShow: true,
        component: () => import('@/views/UserManage/UserManageList.vue'),
        meta: {
          rank: 10101,
          title: '用户管理',
          // rootMenu: true,
          icon: 'home',
        },
      },
    ],
  },
  {
    path: '/Login',
    name: 'Login',
src/services/api/typings.d.ts
@@ -286,8 +286,15 @@
  interface APIgetUserInfoRolesParams {
    /** 用户Id */
    userInfoId?: string;
    /** 用户类型 */
    userType?: EnumUserType;
    /** 客户端类型 */
    clientType?: EnumClientType;
  }
  interface APIgetUserParams {
    /** 用户Id */
    id?: string;
  }
  interface APIgetUserResumeCredentialParams {
@@ -1884,6 +1891,24 @@
    timestamp?: number;
  }
  interface FriendlyResultGetOperationUserInfosQueryResult {
    /** 跟踪Id */
    traceId?: string;
    /** 状态码 */
    code?: number;
    /** 错误码 */
    errorCode?: string;
    data?: GetOperationUserInfosQueryResult;
    /** 执行成功 */
    success?: boolean;
    /** 错误信息 */
    msg?: any;
    /** 附加数据 */
    extras?: any;
    /** 时间戳 */
    timestamp?: number;
  }
  interface FriendlyResultGetPersonalApplyTaskInfosQueryResult {
    /** 跟踪Id */
    traceId?: string;
@@ -2360,6 +2385,24 @@
    /** 错误码 */
    errorCode?: string;
    data?: GetTraceIdLogQueryResult;
    /** 执行成功 */
    success?: boolean;
    /** 错误信息 */
    msg?: any;
    /** 附加数据 */
    extras?: any;
    /** 时间戳 */
    timestamp?: number;
  }
  interface FriendlyResultGetUserQueryResult {
    /** 跟踪Id */
    traceId?: string;
    /** 状态码 */
    code?: number;
    /** 错误码 */
    errorCode?: string;
    data?: GetUserQueryResult;
    /** 执行成功 */
    success?: boolean;
    /** 错误信息 */
@@ -3009,24 +3052,6 @@
    /** 错误码 */
    errorCode?: string;
    data?: PagedListQueryResultGetEnterprisesQueryResultItem;
    /** 执行成功 */
    success?: boolean;
    /** 错误信息 */
    msg?: any;
    /** 附加数据 */
    extras?: any;
    /** 时间戳 */
    timestamp?: number;
  }
  interface FriendlyResultPagedListQueryResultGetOperationUserInfosQueryResultItem {
    /** 跟踪Id */
    traceId?: string;
    /** 状态码 */
    code?: number;
    /** 错误码 */
    errorCode?: string;
    data?: PagedListQueryResultGetOperationUserInfosQueryResultItem;
    /** 执行成功 */
    success?: boolean;
    /** 错误信息 */
@@ -4618,10 +4643,10 @@
    pageModel?: PagedListQueryPageModel;
  }
  interface GetOperationUserInfosQuery {
    /** 关键字 */
    keywords?: string;
    pageModel?: PagedListQueryPageModel;
  interface GetOperationUserInfosQueryResult {
    pageModel?: PagedListQueryResultPageModel;
    /** 数据 */
    data?: GetOperationUserInfosQueryResultItem[];
  }
  interface GetOperationUserInfosQueryResultItem {
@@ -5860,6 +5885,29 @@
    isChecked?: boolean;
  }
  interface GetUserQueryResult {
    /** 用户Id */
    id?: string;
    /** 姓名 */
    name?: string;
    /** 用户名 */
    userName?: string;
    /** 手机号 */
    phoneNumber?: string;
    /** 角色Id */
    roles?: GetUserQueryResultRole[];
    status?: EnumUserStatus;
    /** 备注 */
    remark?: string;
  }
  interface GetUserQueryResultRole {
    /** 角色Id */
    id?: string;
    /** 名称 */
    name?: string;
  }
  interface GetUserResumeCredentialQueryResult {
    /** 资格证书Id */
    id?: string;
@@ -6120,6 +6168,12 @@
    workExperience?: string;
  }
  interface GetUsersQuery {
    /** 关键字 */
    keywords?: string;
    pageModel?: PagedListQueryPageModel;
  }
  type GetWxmpSettingsQuery = Record<string, any>;
  interface GetWxmpSettingsQueryResult {
@@ -6352,12 +6406,6 @@
    data?: GetEnterprisesQueryResultItem[];
  }
  interface PagedListQueryResultGetOperationUserInfosQueryResultItem {
    pageModel?: PagedListQueryResultPageModel;
    /** 数据 */
    data?: GetOperationUserInfosQueryResultItem[];
  }
  interface PagedListQueryResultGetRolesQueryResultItem {
    pageModel?: PagedListQueryResultPageModel;
    /** 数据 */
@@ -6476,6 +6524,13 @@
  interface ResendResourceCommand {
    /** 资源日志Id */
    id?: string;
  }
  interface ResetUserPasswordsCommand {
    /** Id */
    ids?: string[];
    /** 密码 */
    password?: string;
  }
  interface RevokeTaskSettlementOrderCommand {
@@ -6866,6 +6921,24 @@
    id?: string;
  }
  interface SaveUserCommand {
    /** 姓名 */
    name?: string;
    /** 用户名 */
    userName?: string;
    /** 手机号 */
    phoneNumber?: string;
    /** 密码 */
    password?: string;
    /** 角色Id */
    roleIds?: string[];
    status?: EnumUserStatus;
    /** 备注 */
    remark?: string;
    /** Id */
    id?: string;
  }
  interface SaveUserResumeCredentialCommand {
    /** 证书类型编号 */
    typeCode: string;
src/services/api/user.ts
@@ -17,24 +17,6 @@
  });
}
/** 查询运营端用户分页列表数据 POST /api/user/user/getOperationUserInfos */
export async function getOperationUserInfos(
  body: API.GetOperationUserInfosQuery,
  options?: API.RequestConfig
) {
  return request<API.PagedListQueryResultGetOperationUserInfosQueryResultItem>(
    '/api/user/user/getOperationUserInfos',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json-patch+json',
      },
      data: body,
      ...(options || {}),
    }
  );
}
/** 查询个人用户银行卡信息 GET /api/user/user/getPersonalUserBankCard */
export async function getPersonalUserBankCard(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
@@ -137,6 +119,21 @@
  );
}
/** 查询用户详情 GET /api/user/user/getUser */
export async function getUser(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
  params: API.APIgetUserParams,
  options?: API.RequestConfig
) {
  return request<API.GetUserQueryResult>('/api/user/user/getUser', {
    method: 'GET',
    params: {
      ...params,
    },
    ...(options || {}),
  });
}
/** 查询用户角色列表 GET /api/user/user/getUserInfoRoles */
export async function getUserInfoRoles(
  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
@@ -152,6 +149,33 @@
  });
}
/** 查询用户分页列表数据 POST /api/user/user/getUsers */
export async function getUsers(body: API.GetUsersQuery, options?: API.RequestConfig) {
  return request<API.GetOperationUserInfosQueryResult>('/api/user/user/getUsers', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 重置用户密码 POST /api/user/user/resetUserPasswords */
export async function resetUserPasswords(
  body: API.ResetUserPasswordsCommand,
  options?: API.RequestConfig
) {
  return request<number>('/api/user/user/resetUserPasswords', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 保存用户银行卡信息 POST /api/user/user/savePersonalUserBankCard */
export async function savePersonalUserBankCard(
  body: API.SavePersonalUserBankCardCommand,
@@ -167,6 +191,18 @@
  });
}
/** 保存用户 POST /api/user/user/saveUser */
export async function saveUser(body: API.SaveUserCommand, options?: API.RequestConfig) {
  return request<string>('/api/user/user/saveUser', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json-patch+json',
    },
    data: body,
    ...(options || {}),
  });
}
/** 发送绑定银行卡短信 POST /api/user/user/sendSavePersonalUserBankCardVerifyCode */
export async function sendSavePersonalUserBankCardVerifyCode(
  body: API.SendSavePersonalUserBankCardVerifyCodeCommand,
src/views/EmploymentManage/CheckReceiveTaskDetail.vue
@@ -48,6 +48,7 @@
      </ProTableV2>
    </AppContainer>
    <CheckManageDialog v-bind="dialogProps" />
    <ManualCheckManageDialog v-bind="dialogManualProps" />
  </LoadingLayout>
</template>
@@ -72,6 +73,7 @@
import { EnumBillingMethodUnitText } from '@/constants';
import dayjs from 'dayjs';
import CheckManageDialog from './components/CheckManageDialog.vue';
import ManualCheckManageDialog from './components/ManualCheckManageDialog.vue';
defineOptions({
  name: 'CheckReceiveTaskDetail',
@@ -183,4 +185,11 @@
    isDetail: false,
  },
});
const { dialogProps: dialogManualProps, handleEdit: handleManualEdit } = useFormDialog({
  defaultFormParams: {
    id: '',
    isDetail: false,
  },
});
</script>
src/views/EmploymentManage/components/AddOrEditEmploymentView.vue
@@ -53,6 +53,37 @@
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <template v-if="form.billingMethod === EnumBillingMethod.Hour">
            <ProFormCol>
              <ProFormColItem :span="12">
                <ProFormItemV2 label="核定工时:" prop="name">
                  <ProFormInputNumber
                    :controls="false"
                    v-model="form.serviceFee"
                    placeholder="请输入核定工时"
                    :min="0"
                    :max="999999999999"
                    unit="小时/天"
                  ></ProFormInputNumber>
                </ProFormItemV2>
              </ProFormColItem>
            </ProFormCol>
            <ProFormCol>
              <ProFormColItem :span="12">
                <ProFormItemV2 label="超时服务费:" prop="name">
                  <ProFormInputNumber
                    :controls="false"
                    v-model="form.serviceFee"
                    placeholder="请输入超时服务费"
                    :min="0"
                    :max="999999999999"
                    unit="元/小时"
                  ></ProFormInputNumber>
                </ProFormItemV2>
              </ProFormColItem>
            </ProFormCol>
          </template>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2
@@ -199,12 +230,19 @@
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2
                label="详细地址:"
                prop="addressDetail"
                :check-rules="[{ message: '请输入详细地址' }]"
              >
                <ProFormText v-model.trim="form.addressDetail" placeholder="请输入详细地址" />
              <ProFormItemV2 label="地点说明:" prop="addressDetail">
                <ProFormText v-model.trim="form.addressDetail" placeholder="请输入地点说明" />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2 label="任务描述:" prop="addressDetail">
                <ProFormTextArea
                  :rows="4"
                  v-model.trim="form.addressDetail"
                  placeholder="请输入任务描述"
                />
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
@@ -223,6 +261,35 @@
                  end-placeholder="结束日期"
                  :disabled-date="disabledDate"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2
                label="报名时间:"
                prop="time"
                :check-rules="[{ message: '请选择报名时间', type: 'array' }]"
              >
                <ProFormDatePicker
                  v-model="form.time"
                  type="daterange"
                  range-separator="至"
                  start-placeholder="开始日期"
                  end-placeholder="结束日期"
                  :disabled-date="disabledDate"
                ></ProFormDatePicker>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
          <ProFormCol>
            <ProFormColItem :span="12">
              <ProFormItemV2
                label="验收方式:"
                prop="genderLimit"
                :check-rules="[{ message: '请选择验收方式' }]"
              >
                <ProFormRadio v-model="form.genderLimit" :value-enum="[]"></ProFormRadio>
              </ProFormItemV2>
            </ProFormColItem>
          </ProFormCol>
@@ -250,6 +317,7 @@
  ProFormDatePicker,
  ProFormCheckbox,
  ProFormSelect,
  ProFormTextArea,
} from '@bole-core/components';
import { FormInstance, ModelValueType } from 'element-plus';
import { Message } from '@bole-core/core';
@@ -258,6 +326,7 @@
import * as taskServices from '@/services/api/task';
import {
  EnumUserGenderTextForEdit,
  EnumBillingMethod,
  EnumBillingMethodText,
  EnumBillingMethodUnitText,
  EnumSettlementCycleText,
src/views/EmploymentManage/components/CheckManageDialog.vue
@@ -27,7 +27,7 @@
import { useGlobalEventContext } from '@/hooks';
defineOptions({
  name: 'EnterpriseConsumptionDetailDialog',
  name: 'CheckManageDialog',
});
type Form = {
src/views/EmploymentManage/components/ManualCheckManageDialog.vue
New file
@@ -0,0 +1,208 @@
<template>
  <ProDialog :title="title" v-model="visible" destroy-on-close draggable>
    <ProDialogTableWrapper :height="400">
      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
      </ProTableV2>
    </ProDialogTableWrapper>
    <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,
  ProTableV2,
  ProDialogTableWrapper,
  defineColumns,
  defineOperationBtns,
  useTable,
} from '@bole-core/components';
import * as taskCheckReceiveServices from '@/services/api/taskCheckReceive';
import { setOSSLink } from '@/utils';
import { downloadWithZip, Message } from '@bole-core/core';
import { useGlobalEventContext } from '@/hooks';
defineOptions({
  name: 'ManualCheckManageDialog',
});
type Form = {
  id: string;
  isDetail: boolean;
};
const visible = defineModel({ type: Boolean });
const form = defineModel<Form>('form');
const title = computed(() => (form.value.isDetail ? '详情' : '验收'));
const emit = defineEmits<{
  (e: 'onCancel'): void;
}>();
const eventContext = useGlobalEventContext();
const columns = defineColumns([
  {
    id: '1',
    enCode: 'date',
    name: '任务日期',
  },
  {
    id: '2',
    enCode: 'createdTime',
    name: '签到时间',
  },
  {
    id: '3',
    enCode: 'files',
    name: '签出时间',
  },
  {
    id: '4',
    enCode: 'checkReceiveStatus',
    name: '验收状态',
  },
  {
    id: '5',
    enCode: 'checkReceiveTime',
    name: '操作人',
  },
]);
const operationBtns = defineOperationBtns([
  {
    data: {
      enCode: 'checkReceiveBtn',
      name: '验收通过',
    },
    emits: {
      onClick: (role) => checkReceiveTask(role, EnumTaskUserSubmitCheckReceiveStatus.Success),
    },
    extraProps: {
      hide: (row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem) =>
        !(
          row.checkReceiveStatus === EnumTaskUserSubmitCheckReceiveStatus.WaitSubmit ||
          row.checkReceiveStatus === EnumTaskUserSubmitCheckReceiveStatus.WaitCheckReceive
        ) || form.value.isDetail,
    },
  },
  {
    data: {
      enCode: 'checkReceiveBtn',
      name: '验收未通过',
    },
    emits: {
      onClick: (role) => checkReceiveTask(role, EnumTaskUserSubmitCheckReceiveStatus.Fail),
    },
    extraProps: {
      hide: (row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem) =>
        !(
          row.checkReceiveStatus === EnumTaskUserSubmitCheckReceiveStatus.WaitSubmit ||
          row.checkReceiveStatus === EnumTaskUserSubmitCheckReceiveStatus.WaitCheckReceive
        ) || form.value.isDetail,
    },
  },
  {
    data: {
      enCode: 'downloadBtn',
      name: '下载',
    },
    emits: {
      onClick: (role) => handleDownload(role),
    },
    extraProps: {
      hide: (row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem) => row.files?.length === 0,
    },
  },
]);
watch(
  visible,
  (val) => {
    if (val) {
      if (form.value.id) {
        getList();
      }
    }
  },
  {
    immediate: true,
  }
);
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetCheckReceiveTaskUserSubmitsQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        id: form.value.id,
      };
      let res = await taskCheckReceiveServices.getCheckReceiveTaskUserSubmits(params);
      return res;
    } catch (error) {
      console.log('error: ', error);
    }
  },
  {
    defaultExtraParams: {
      orderInput: [{ property: 'date', order: EnumPagedListOrder.Desc }],
    },
    queryKey: ['taskCheckReceiveServices/getCheckReceiveTaskUserSubmits'],
    columnsRenderProps: {
      createdTime: { type: 'date' },
      checkReceiveTime: { type: 'date' },
      date: { type: 'date', format: 'YYYY-MM-DD' },
      checkReceiveStatus: { type: 'enum', valueEnum: EnumTaskUserSubmitCheckReceiveStatusText },
      files: {
        type: 'url',
        //@ts-ignore
        formatter: (row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem) =>
          row.files?.length > 0 && (row.files ?? []).map((x) => setOSSLink(x)),
        showDownloadBtn: false,
      },
    },
  }
);
function handleDownload(row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem) {
  if (row.files?.length > 0) {
    downloadWithZip(
      row.files.map((x) => ({
        data: `${setOSSLink(x)}`,
      })),
      '验收照片'
    );
  }
}
async function checkReceiveTask(
  row: API.GetCheckReceiveTaskUserSubmitsQueryResultItem,
  checkReceiveStatus: EnumTaskUserSubmitCheckReceiveStatus
) {
  try {
    let params: API.CheckReceiveTaskCommand = {
      id: row.id,
      checkReceiveStatus: checkReceiveStatus,
    };
    let res = await taskCheckReceiveServices.checkReceiveTask(params);
    if (res) {
      Message.successMessage('操作成功');
      getList(paginationState.pageIndex);
      eventContext.emit('checkReceiveTask');
    }
  } catch (error) {}
}
</script>
src/views/EmploymentManage/constants/columns.ts
@@ -38,26 +38,41 @@
  },
  {
    id: '8',
    enCode: 'userCount',
    name: '报名开始',
  },
  {
    id: '9',
    enCode: 'userCount',
    name: '报名结束',
  },
  {
    id: '10',
    enCode: 'userCount',
    name: '报名状态',
  },
  {
    id: '11',
    enCode: 'status',
    name: '任务状态',
  },
  {
    id: '9',
    id: '12',
    enCode: 'createdTime',
    name: '发布日期',
  },
  {
    id: '10',
    id: '13',
    enCode: 'beginTime',
    name: '开始日期',
    name: '任务开始日期',
  },
  {
    id: '11',
    id: '14',
    enCode: 'endTime',
    name: '结束日期',
    name: '任务结束日期',
  },
  {
    id: '12',
    id: '15',
    enCode: 'releaseStatus',
    name: '发布状态',
  },
@@ -183,10 +198,15 @@
  {
    id: '8',
    enCode: 'checkReceiveStatus',
    name: '任务验收状态',
    name: '验收方式',
  },
  {
    id: '9',
    enCode: 'checkReceiveStatus',
    name: '任务验收状态',
  },
  {
    id: '10',
    enCode: 'lastCheckReceiveTime',
    name: '最近验收时间',
  },
src/views/ServiceChargeManage/components/EditAccountInfoDialog.vue
@@ -21,7 +21,7 @@
      <ProFormItemV2
        label="收款账户:"
        prop="receiveAccount"
        :check-rules="[{ message: '请输入收款账户', type: 'bankCard' }]"
        :check-rules="[{ message: '请输入收款账户' }]"
      >
        <ProFormText placeholder="请输入收款账户" v-model.trim="form.receiveAccount"></ProFormText>
      </ProFormItemV2>
src/views/UserManage/UserManageList.vue
New file
@@ -0,0 +1,170 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem>
            <SearchInput
              v-model="extraParamState.keywords"
              style="width: 260px"
              placeholder="姓名/用户名/手机号"
              @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="UserManageColumns"
        :operationBtns="operationBtns"
      >
      </ProTableV2>
    </AppContainer>
    <AddOrEditUserDialog v-bind="dialogProps" />
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  ProTableQueryFilterBar,
  ProTableV2,
  SearchInput,
  LoadingLayout,
  AppContainer,
  QueryFilterItem,
  useTable,
  useFormDialog,
  defineOperationBtns,
} from '@bole-core/components';
import * as userServices from '@/services/api/user';
import { UserManageColumns } from './constants';
import { EnumUserStatusText } from '@/constants';
import { ModelValueType } from 'element-plus';
import { Message } from '@bole-core/core';
import AddOrEditUserDialog from './components/AddOrEditUserDialog.vue';
defineOptions({
  name: 'UserManageList',
});
const operationBtns = defineOperationBtns([
  {
    data: {
      enCode: 'editBtn',
      name: '编辑',
    },
    emits: {
      onClick: (role) => openDialog(role),
    },
  },
]);
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.GetUsersQuery = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        keywords: extraParamState.keywords,
      };
      let res = await userServices.getUsers(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {}
  },
  {
    defaultExtraParams: {
      keywords: '',
      status: '',
      time: [] as unknown as ModelValueType,
      orderInput: [{ property: 'id', order: EnumPagedListOrder.Desc }],
    },
    columnsRenderProps: {
      roles: {
        formatter: (role: API.GetOperationUserInfosQueryResultItem) =>
          role.roles?.length > 0 ? role.roles.map((x) => x.name).join(',') : '',
      },
      status: { type: 'enum', valueEnum: EnumUserStatusText },
    },
  }
);
const { dialogProps, handleEdit, handleAdd, editForm, dialogState } = useFormDialog({
  onConfirm: handleAddOrEdit,
  defaultFormParams: {
    id: '',
    name: '',
    userName: '',
    phoneNumber: '',
    remark: '',
    roleIds: [] as string[],
    password: '',
  },
});
function openDialog(row?: API.GetOperationUserInfosQueryResultItem) {
  if (row) {
    handleEdit({
      id: row.id,
      name: row.name,
      userName: row.userName,
      phoneNumber: row.phoneNumber,
      remark: row.remark,
      roleIds: row.roles?.map((x) => x.id) ?? [],
      password: '',
    });
  } else {
    handleAdd();
  }
}
async function handleAddOrEdit() {
  const isEdit = editForm.id;
  try {
    let params: API.SaveUserCommand = {
      name: editForm.name,
      userName: editForm.userName,
      phoneNumber: editForm.phoneNumber,
      password: editForm.password,
      roleIds: editForm.roleIds,
      remark: editForm.remark,
    };
    if (editForm.id) {
      params.id = editForm.id;
    }
    let res = await userServices.saveUser(params);
    if (res) {
      Message.successMessage('操作成功');
      getList(isEdit ? paginationState.pageIndex : 1);
      dialogState.dialogVisible = false;
    }
  } catch (error) {}
}
</script>
src/views/UserManage/components/AddOrEditUserDialog.vue
New file
@@ -0,0 +1,143 @@
<template>
  <ProDialog
    :title="innerForm.title"
    v-model="innerVisible"
    @close="onDialogClose"
    destroy-on-close
    draggable
  >
    <ProForm :model="innerForm" ref="dialogForm" label-width="90px">
      <ProFormItemV2 label="姓名" prop="name" :check-rules="[{ message: '请输入姓名' }]">
        <ProFormText placeholder="请输入姓名" v-model.trim="innerForm.name"></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2
        label="手机号"
        prop="phoneNumber"
        :check-rules="[{ message: '请输入手机号', type: 'phone' }]"
      >
        <ProFormText placeholder="请输入手机号" v-model.trim="innerForm.phoneNumber"></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2 label="用户名" prop="userName" :check-rules="[{ message: '请输入用户名' }]">
        <ProFormText placeholder="请输入用户名" v-model.trim="innerForm.userName"></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2
        v-if="!isEdit"
        label="密码"
        prop="password"
        :check-rules="[{ message: '请输入密码' }]"
      >
        <ProFormText placeholder="请输入账号" v-model.trim="innerForm.password"></ProFormText>
      </ProFormItemV2>
      <ProFormItemV2 label="角色" prop="roleIds" :check-rules="[{ message: '请选择角色' }]">
        <ProFormCheckbox
          v-model="innerForm.roleIds"
          :value-enum="userInfoRoles"
          enumLabelKey="name"
          enum-value-key="id"
        ></ProFormCheckbox>
      </ProFormItemV2>
      <ProFormItemV2 label="备注:" prop="remark">
        <ProFormTextArea
          v-model="innerForm.remark"
          placeholder="请输入备注"
          show-word-limit
          :maxlength="2000"
        ></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 { FormRules, FormInstance } from 'element-plus';
import {
  ProDialog,
  ProForm,
  ProFormItemV2,
  ProFormText,
  ProFormTextArea,
  ProFormCheckbox,
  ProFormSelect,
} from '@bole-core/components';
import { BoleRegExp } from '@bole-core/core';
import { useUserInfoRoles } from '@/hooks';
defineOptions({
  name: 'AddOrEditUserDialog',
});
type Props = {
  modelValue: boolean;
  form: {
    name: string;
    title?: string;
    id: string;
    userName: string;
    phoneNumber: string;
    remark: string;
    roleIds: string[];
    password: string;
  };
};
const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
});
const { userInfoRoles } = useUserInfoRoles({
  userInfoId: toRef(props.form, 'id'),
  userType: EnumUserType.Enterprise,
  clientType: EnumClientType.PcWeb,
});
const isEdit = computed(() => !!props.form.id);
const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void;
  (e: 'update:form', value: Props['form']): void;
  (e: 'onConfirm'): void;
  (e: 'onCancel'): void;
}>();
const dialogForm = ref<FormInstance>();
const innerVisible = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emit('update:modelValue', val);
  },
});
const innerForm = computed({
  get() {
    return props.form;
  },
  set(val) {
    emit('update:form', val);
  },
});
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/UserManage/constants/columns.ts
New file
@@ -0,0 +1,34 @@
import { defineColumns } from '@bole-core/components';
export const UserManageColumns = defineColumns([
  {
    id: '1',
    enCode: 'name',
    name: '姓名',
  },
  {
    id: '2',
    enCode: 'userName',
    name: '用户名',
  },
  {
    id: '3',
    enCode: 'phoneNumber',
    name: '手机号',
  },
  {
    id: '4',
    enCode: 'roles',
    name: '角色',
  },
  {
    id: '5',
    enCode: 'status',
    name: '状态',
  },
  {
    id: '6',
    enCode: 'remark',
    name: '备注',
  },
]);
src/views/UserManage/constants/index.ts
New file
@@ -0,0 +1 @@
export * from './columns';