Quellcode durchsuchen

feat: (regiser) 增加注册

gemercheung vor 2 Jahren
Ursprung
Commit
2aa2d21f74

+ 50 - 0
mock/notification/list.ts

@@ -0,0 +1,50 @@
+import { MockMethod } from 'vite-plugin-mock';
+import { mock, Random } from 'mockjs';
+import { resultPageSuccess } from '../_util';
+Random.extend({
+  phone: function () {
+    const phonePrefixs = ['132', '135', '189']; // 自己写前缀哈
+    return this.pick(phonePrefixs) + mock(/\d{8}/); //Number()
+  },
+});
+// console.log(Random.phone());
+// 生成 1 - 10 个 随机手机号码
+
+const demoList = (() => {
+  const result: any[] = [];
+  for (let index = 0; index < 200; index++) {
+    const { phone } = mock({
+      phone: '@phone',
+    });
+
+    result.push({
+      id: `${index}`,
+      name: '@cname',
+      nickName: '@cname',
+      avatarUrl: `@image('400x400', '@color', '微信头像')`,
+      'gender|1': [0, 1, 2],
+      city: '@city',
+      phone: phone,
+      province: '@province',
+      country: '@region',
+      language: '',
+      address: '@county(true)',
+      creatTime: '@datetime',
+      birthday: '@datetime',
+      lastLogin: '@datetime',
+    });
+  }
+  return result;
+})();
+
+export default [
+  {
+    url: '/zfb/notification/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 20 } = query;
+      return resultPageSuccess(page, pageSize, demoList);
+    },
+  },
+] as MockMethod[];

+ 20 - 0
src/api/notification/list.ts

@@ -0,0 +1,20 @@
+import { defHttp } from '/@/utils/http/axios';
+import { PageParams, MemberListGetResultModel } from './model';
+
+enum Api {
+  pageList = '/zfb-api/zfb/notification/list',
+}
+
+/**
+ * @description: Get sample list value
+ */
+
+export const ListApi = (params: PageParams) =>
+  defHttp.post<MemberListGetResultModel>({
+    url: Api.pageList,
+    params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });

+ 19 - 0
src/api/notification/model.ts

@@ -0,0 +1,19 @@
+import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel';
+/**
+ * @description: Request list interface parameters
+ */
+export type PageParams = BasicPageParams;
+
+export interface MemberListItem {
+  id: number;
+  name: string;
+  image: string;
+  link: string;
+  createTime: string;
+  isShow: boolean;
+}
+
+/**
+ * @description: Request list return value
+ */
+export type MemberListGetResultModel = BasicFetchResult<MemberListItem>;

+ 83 - 72
src/api/sys/model/userModel.ts

@@ -1,72 +1,83 @@
-import type { UserInfo } from '/#/store';
-/**
- * @description: Login interface parameters
- */
-export interface LoginParams {
-  userName: string;
-  userPassword: string;
-  captcha: string;
-}
-
-export interface RoleInfo {
-  userID?: string;
-  roleName: string;
-  value: string;
-  brandList: string[] | any;
-  canShow: string;
-  createTime: number;
-  createUserId: number;
-  deptExpirationDate: number;
-  deptId: number;
-  deptManagerPhoneNum: string;
-  deptName: string;
-  email: string;
-  fdkkPassword: string;
-  fdkkUser: string;
-  isPlatformStreamer: false;
-  mobile: string;
-  parentDeptId: number;
-  parentDeptName: number;
-  password: string;
-  roleId: number;
-  roleIdList: any[];
-  roleList: number;
-  status: number;
-  userId: number;
-  username: string;
-}
-
-/**
- * @description: Login interface return value
- */
-export interface LoginResultModel {
-  id?: string | number;
-  token: string;
-  role?: RoleInfo;
-  user: RoleInfo;
-}
-export type GetUserInfoModel = UserInfo;
-
-export interface updateUserInfoPasswordParam {
-  id: string | number;
-  password?: string;
-  newPassword?: string;
-}
-/**
- * @description: Get user information return value
- */
-// export interface GetUserInfoModel {
-//   roles: RoleInfo[];
-//   // 用户id
-//   id: string | number;
-
-//   // userId: string | number;
-//   // 用户名
-//   userName: string;
-//   // 真实名字
-//   realName: string;
-//   // 头像
-//   avatar: string;
-//   // 介绍
-//   desc?: string;
-// }
+import type { UserInfo } from '/#/store';
+/**
+ * @description: Login interface parameters
+ */
+export interface LoginParams {
+  userName: string;
+  userPassword: string;
+  captcha: string;
+}
+
+export interface SendcodeParams {
+  phone: string;
+  areaNum?: string;
+}
+
+export interface RegisterParams {
+  userName: string;
+  userPassword: string;
+  area: string;
+  code: string;
+}
+export interface RoleInfo {
+  userID?: string;
+  roleName: string;
+  value: string;
+  brandList: string[] | any;
+  canShow: string;
+  createTime: number;
+  createUserId: number;
+  deptExpirationDate: number;
+  deptId: number;
+  deptManagerPhoneNum: string;
+  deptName: string;
+  email: string;
+  fdkkPassword: string;
+  fdkkUser: string;
+  isPlatformStreamer: false;
+  mobile: string;
+  parentDeptId: number;
+  parentDeptName: number;
+  password: string;
+  roleId: number;
+  roleIdList: any[];
+  roleList: number;
+  status: number;
+  userId: number;
+  username: string;
+}
+
+/**
+ * @description: Login interface return value
+ */
+export interface LoginResultModel {
+  id?: string | number;
+  token: string;
+  role?: RoleInfo;
+  user: RoleInfo;
+}
+export type GetUserInfoModel = UserInfo;
+
+export interface updateUserInfoPasswordParam {
+  id: string | number;
+  password?: string;
+  newPassword?: string;
+}
+/**
+ * @description: Get user information return value
+ */
+// export interface GetUserInfoModel {
+//   roles: RoleInfo[];
+//   // 用户id
+//   id: string | number;
+
+//   // userId: string | number;
+//   // 用户名
+//   userName: string;
+//   // 真实名字
+//   realName: string;
+//   // 头像
+//   avatar: string;
+//   // 介绍
+//   desc?: string;
+// }

+ 28 - 1
src/api/sys/user.ts

@@ -1,6 +1,7 @@
 import { defHttp } from '/@/utils/http/axios';
 import {
   LoginParams,
+  SendcodeParams,
   LoginResultModel,
   GetUserInfoModel,
   updateUserInfoPasswordParam,
@@ -8,12 +9,14 @@ import {
 import { encodeStr } from '/@/utils/encodeUtil';
 import { ErrorMessageMode } from '/#/axios';
 import { ContentTypeEnum } from '/@/enums/httpEnum';
-
+import type { Result } from '/#/axios';
 // import { encode } from 'js-base64';
 
 enum Api {
   // Login = '/zfb-api/zfb/sys/login',
   Login = '/zfb-api/zfb/loginBackground',
+  Sendcode = '/zfb-api/zfb/phone/getSMForApp',
+  Register = '/zfb-api/zfb/platform/user/register',
   Logout = '/logout',
   updatePassword = '/zfb-api/zfb/user/updatePassword',
   GetUserInfo = '/zfb-api/zfb/shop/sys/user/infoAnon',
@@ -48,6 +51,30 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal')
   );
 }
 
+export async function sendCodeApi(params: SendcodeParams) {
+  const paramData: SendcodeParams = {
+    areaNum: '86',
+    phone: params.phone,
+  };
+  const res = await defHttp.post<Result>(
+    {
+      url: Api.Sendcode,
+      // params,
+      params: paramData,
+      headers: { 'Content-Type': ContentTypeEnum.JSON },
+    },
+    {
+      useResult: true,
+    },
+  );
+  console.log('res', res);
+  if (res.code === 200) {
+    return Promise.resolve(true);
+  } else {
+    return Promise.resolve(false);
+  }
+}
+
 /**
  * @description: getUserInfo
  */

+ 3 - 3
src/layouts/default/header/components/notify/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div :class="prefixCls">
     <Popover title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`">
-      <Badge size="small" :count="count" :numberStyle="numberStyle">
+      <Badge size="small" dot :count="100" :numberStyle="numberStyle">
         <BellOutlined />
       </Badge>
       <!-- <template #content>
@@ -24,7 +24,7 @@
 <script lang="ts">
   import { computed, defineComponent, ref } from 'vue';
   // Tabs, Badge
-  import { Popover } from 'ant-design-vue';
+  import { Popover, Badge } from 'ant-design-vue';
   import { BellOutlined } from '@ant-design/icons-vue';
   import { tabListData, ListItem } from './data';
   // import NoticeList from './NoticeList.vue';
@@ -32,7 +32,7 @@
   import { useMessage } from '/@/hooks/web/useMessage';
   // Tabs, TabPane: Tabs.TabPane, Badge, NoticeList
   export default defineComponent({
-    components: { Popover, BellOutlined },
+    components: { Popover, BellOutlined, Badge },
     setup() {
       const { prefixCls } = useDesign('header-notify');
       const { createMessage } = useMessage();

+ 280 - 275
src/utils/http/axios/index.ts

@@ -1,275 +1,280 @@
-// axios配置  可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动
-// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
-
-import type { AxiosResponse } from 'axios';
-import { clone } from 'lodash-es';
-import type { RequestOptions, Result } from '/#/axios';
-import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform';
-import { VAxios } from './Axios';
-import { checkStatus } from './checkStatus';
-import { useGlobSetting } from '/@/hooks/setting';
-import { useMessage } from '/@/hooks/web/useMessage';
-import { RequestEnum, ResultEnum, ContentTypeEnum } from '/@/enums/httpEnum';
-import { isString } from '/@/utils/is';
-import { getToken } from '/@/utils/auth';
-import { setObjToUrlParams, deepMerge } from '/@/utils';
-import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
-import { useI18n } from '/@/hooks/web/useI18n';
-import { joinTimestamp, formatRequestDate } from './helper';
-import { useUserStoreWithOut } from '/@/store/modules/user';
-
-const globSetting = useGlobSetting();
-const urlPrefix = globSetting.urlPrefix;
-const { createMessage, createErrorModal } = useMessage();
-
-/**
- * @description: 数据处理,方便区分多种处理方式
- */
-const transform: AxiosTransform = {
-  /**
-   * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
-   */
-  transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
-    const { t } = useI18n();
-    const { isTransformResponse, isReturnNativeResponse } = options;
-    // 是否返回原生响应头 比如:需要获取响应头时使用该属性
-    if (isReturnNativeResponse) {
-      return res;
-    }
-    // 不进行任何处理,直接返回
-    // 用于页面代码可能需要直接获取code,data,message这些信息时开启
-    if (!isTransformResponse) {
-      return res.data;
-    }
-    // 错误的时候返回
-
-    const { data } = res;
-    if (!data) {
-      // return '[HTTP] Request has no return value';
-      throw new Error(t('sys.api.apiRequestFailed'));
-    }
-    //  这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
-
-    const { code, error, message } = data;
-    // TODO
-    // 这里逻辑可以根据项目进行修改
-    const hasSuccess =
-      data &&
-      Reflect.has(data, 'code') &&
-      (code === ResultEnum.SUCCESS || code === ResultEnum.NORMAL);
-    if (hasSuccess) {
-      const converterResult = data.message;
-      const converterMessage = error;
-      Reflect.set(data, 'result', converterResult);
-      Reflect.set(data, 'message', converterMessage);
-      // data.result = converterResult;
-      // data.message = converterMessage;
-      delete data.error;
-      return data.result || data;
-    }
-
-    // 在此处根据自己项目的实际情况对不同的code执行不同的操作
-    // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
-    let timeoutMsg = '';
-    switch (code) {
-      case ResultEnum.TIMEOUT:
-        timeoutMsg = t('sys.api.timeoutMessage');
-        const userStore = useUserStoreWithOut();
-        userStore.setToken(undefined);
-        userStore.logout(true);
-        break;
-      case ResultEnum.JAVA_ERROR:
-        if (error) {
-          timeoutMsg = error;
-        }
-        break;
-      default:
-        if (message) {
-          timeoutMsg = message;
-        }
-        //TODO 由于后端HACKCODE error当信息string
-        if (error) {
-          timeoutMsg = error;
-        }
-        break;
-    }
-
-    // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
-    // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
-    if (options.errorMessageMode === 'modal') {
-      createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });
-    } else if (options.errorMessageMode === 'message') {
-      createMessage.error(timeoutMsg);
-    }
-    console.log('timeoutMsg', timeoutMsg);
-    throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));
-  },
-
-  // 请求之前处理config
-  beforeRequestHook: (config, options) => {
-    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
-
-    if (joinPrefix) {
-      config.url = `${urlPrefix}${config.url}`;
-    }
-
-    if (apiUrl && isString(apiUrl)) {
-      config.url = `${apiUrl}${config.url}`;
-    }
-    const params = config.params || {};
-    const data = config.data || false;
-    formatDate && data && !isString(data) && formatRequestDate(data);
-    if (config.method?.toUpperCase() === RequestEnum.GET) {
-      if (!isString(params)) {
-        // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
-        config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
-      } else {
-        // 兼容restful风格
-        config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
-        config.params = undefined;
-      }
-    } else {
-      if (!isString(params)) {
-        formatDate && formatRequestDate(params);
-        if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
-          config.data = data;
-          config.params = params;
-        } else {
-          // 非GET请求如果没有提供data,则将params视为data
-          config.data = params;
-          config.params = undefined;
-        }
-        if (joinParamsToUrl) {
-          config.url = setObjToUrlParams(
-            config.url as string,
-            Object.assign({}, config.params, config.data),
-          );
-        }
-      } else {
-        // 兼容restful风格
-        config.url = config.url + params;
-        config.params = undefined;
-      }
-    }
-    return config;
-  },
-
-  /**
-   * @description: 请求拦截器处理
-   */
-  requestInterceptors: (config, options) => {
-    // 请求之前处理config
-    const token = getToken();
-    if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
-      // jwt token
-      // (config as Recordable).headers.Authorization = options.authenticationScheme
-      //   ? `${options.authenticationScheme} ${token}`
-      //   : token;
-      (config as Recordable).headers.token = options.authenticationScheme
-        ? `${options.authenticationScheme} ${token}`
-        : token;
-    }
-    return config;
-  },
-
-  /**
-   * @description: 响应拦截器处理
-   */
-  responseInterceptors: (res: AxiosResponse<any>) => {
-    return res;
-  },
-
-  /**
-   * @description: 响应错误处理
-   */
-  responseInterceptorsCatch: (error: any) => {
-    const { t } = useI18n();
-    const errorLogStore = useErrorLogStoreWithOut();
-    errorLogStore.addAjaxErrorInfo(error);
-    const { response, code, message, config } = error || {};
-    const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
-    const msg: string = response?.data?.error?.message ?? '';
-    const err: string = error?.toString?.() ?? '';
-    let errMessage = '';
-
-    try {
-      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
-        errMessage = t('sys.api.apiTimeoutMessage');
-      }
-      if (err?.includes('Network Error')) {
-        errMessage = t('sys.api.networkExceptionMsg');
-      }
-
-      if (errMessage) {
-        if (errorMessageMode === 'modal') {
-          createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });
-        } else if (errorMessageMode === 'message') {
-          createMessage.error(errMessage);
-        }
-        return Promise.reject(error);
-      }
-    } catch (error) {
-      throw new Error(error as unknown as string);
-    }
-
-    checkStatus(error?.response?.status, msg, errorMessageMode);
-    return Promise.reject(error);
-  },
-};
-
-function createAxios(opt?: Partial<CreateAxiosOptions>) {
-  return new VAxios(
-    deepMerge(
-      {
-        // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
-        // authentication schemes,e.g: Bearer
-        // authenticationScheme: 'Bearer',
-        authenticationScheme: '',
-        timeout: 10 * 1000,
-        // 基础接口地址
-        // baseURL: globSetting.apiUrl,
-
-        headers: { 'Content-Type': ContentTypeEnum.JSON },
-        // 如果是form-data格式
-        // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
-        // 数据处理方式
-        transform: clone(transform),
-        // 配置项,下面的选项都可以在独立的接口请求中覆盖
-        requestOptions: {
-          // 默认将prefix 添加到url
-          joinPrefix: true,
-          // 是否返回原生响应头 比如:需要获取响应头时使用该属性
-          isReturnNativeResponse: false,
-          // 需要对返回数据进行处理
-          isTransformResponse: true,
-          // post请求的时候添加参数到url
-          joinParamsToUrl: false,
-          // 格式化提交参数时间
-          formatDate: true,
-          // 消息提示类型
-          errorMessageMode: 'message',
-          // 接口地址
-          apiUrl: globSetting.apiUrl,
-          // 接口拼接地址
-          urlPrefix: urlPrefix,
-          //  是否加入时间戳
-          joinTime: true,
-          // 忽略重复请求
-          ignoreCancelToken: true,
-          // 是否携带token
-          withToken: true,
-        },
-      },
-      opt || {},
-    ),
-  );
-}
-export const defHttp = createAxios();
-
-// other api url
-// export const otherHttp = createAxios({
-//   requestOptions: {
-//     apiUrl: 'xxx',
-//     urlPrefix: 'xxx',
-//   },
-// });
+// axios配置  可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动
+// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
+
+import type { AxiosResponse } from 'axios';
+import { clone } from 'lodash-es';
+import type { RequestOptions, Result } from '/#/axios';
+import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform';
+import { VAxios } from './Axios';
+import { checkStatus } from './checkStatus';
+import { useGlobSetting } from '/@/hooks/setting';
+import { useMessage } from '/@/hooks/web/useMessage';
+import { RequestEnum, ResultEnum, ContentTypeEnum } from '/@/enums/httpEnum';
+import { isString } from '/@/utils/is';
+import { getToken } from '/@/utils/auth';
+import { setObjToUrlParams, deepMerge } from '/@/utils';
+import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { joinTimestamp, formatRequestDate } from './helper';
+import { useUserStoreWithOut } from '/@/store/modules/user';
+
+const globSetting = useGlobSetting();
+const urlPrefix = globSetting.urlPrefix;
+const { createMessage, createErrorModal } = useMessage();
+
+/**
+ * @description: 数据处理,方便区分多种处理方式
+ */
+const transform: AxiosTransform = {
+  /**
+   * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
+   */
+  transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
+    const { t } = useI18n();
+    const { isTransformResponse, isReturnNativeResponse } = options;
+    // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+    if (isReturnNativeResponse) {
+      return res;
+    }
+    // 不进行任何处理,直接返回
+    // 用于页面代码可能需要直接获取code,data,message这些信息时开启
+    if (!isTransformResponse) {
+      return res.data;
+    }
+    // 错误的时候返回
+
+    const { data } = res;
+    if (!data) {
+      // return '[HTTP] Request has no return value';
+      throw new Error(t('sys.api.apiRequestFailed'));
+    }
+    //  这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
+
+    const { code, error, message } = data;
+    // TODO
+    // 这里逻辑可以根据项目进行修改
+    const hasSuccess =
+      data &&
+      Reflect.has(data, 'code') &&
+      (code === ResultEnum.SUCCESS || code === ResultEnum.NORMAL);
+    if (hasSuccess) {
+      const converterResult = data.message;
+      const converterMessage = error;
+      Reflect.set(data, 'result', converterResult);
+      Reflect.set(data, 'message', converterMessage);
+      // data.result = converterResult;
+      // data.message = converterMessage;
+      delete data.error;
+      //增加自定义result return
+      if (options.useResult) {
+        return data;
+      } else {
+        return data.result;
+      }
+    }
+
+    // 在此处根据自己项目的实际情况对不同的code执行不同的操作
+    // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
+    let timeoutMsg = '';
+    switch (code) {
+      case ResultEnum.TIMEOUT:
+        timeoutMsg = t('sys.api.timeoutMessage');
+        const userStore = useUserStoreWithOut();
+        userStore.setToken(undefined);
+        userStore.logout(true);
+        break;
+      case ResultEnum.JAVA_ERROR:
+        if (error) {
+          timeoutMsg = error;
+        }
+        break;
+      default:
+        if (message) {
+          timeoutMsg = message;
+        }
+        //TODO 由于后端HACKCODE error当信息string
+        if (error) {
+          timeoutMsg = error;
+        }
+        break;
+    }
+
+    // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
+    // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
+    if (options.errorMessageMode === 'modal') {
+      createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });
+    } else if (options.errorMessageMode === 'message') {
+      createMessage.error(timeoutMsg);
+    }
+    console.log('timeoutMsg', timeoutMsg);
+    throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));
+  },
+
+  // 请求之前处理config
+  beforeRequestHook: (config, options) => {
+    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
+
+    if (joinPrefix) {
+      config.url = `${urlPrefix}${config.url}`;
+    }
+
+    if (apiUrl && isString(apiUrl)) {
+      config.url = `${apiUrl}${config.url}`;
+    }
+    const params = config.params || {};
+    const data = config.data || false;
+    formatDate && data && !isString(data) && formatRequestDate(data);
+    if (config.method?.toUpperCase() === RequestEnum.GET) {
+      if (!isString(params)) {
+        // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
+        config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
+      } else {
+        // 兼容restful风格
+        config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
+        config.params = undefined;
+      }
+    } else {
+      if (!isString(params)) {
+        formatDate && formatRequestDate(params);
+        if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
+          config.data = data;
+          config.params = params;
+        } else {
+          // 非GET请求如果没有提供data,则将params视为data
+          config.data = params;
+          config.params = undefined;
+        }
+        if (joinParamsToUrl) {
+          config.url = setObjToUrlParams(
+            config.url as string,
+            Object.assign({}, config.params, config.data),
+          );
+        }
+      } else {
+        // 兼容restful风格
+        config.url = config.url + params;
+        config.params = undefined;
+      }
+    }
+    return config;
+  },
+
+  /**
+   * @description: 请求拦截器处理
+   */
+  requestInterceptors: (config, options) => {
+    // 请求之前处理config
+    const token = getToken();
+    if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
+      // jwt token
+      // (config as Recordable).headers.Authorization = options.authenticationScheme
+      //   ? `${options.authenticationScheme} ${token}`
+      //   : token;
+      (config as Recordable).headers.token = options.authenticationScheme
+        ? `${options.authenticationScheme} ${token}`
+        : token;
+    }
+    return config;
+  },
+
+  /**
+   * @description: 响应拦截器处理
+   */
+  responseInterceptors: (res: AxiosResponse<any>) => {
+    return res;
+  },
+
+  /**
+   * @description: 响应错误处理
+   */
+  responseInterceptorsCatch: (error: any) => {
+    const { t } = useI18n();
+    const errorLogStore = useErrorLogStoreWithOut();
+    errorLogStore.addAjaxErrorInfo(error);
+    const { response, code, message, config } = error || {};
+    const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
+    const msg: string = response?.data?.error?.message ?? '';
+    const err: string = error?.toString?.() ?? '';
+    let errMessage = '';
+
+    try {
+      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
+        errMessage = t('sys.api.apiTimeoutMessage');
+      }
+      if (err?.includes('Network Error')) {
+        errMessage = t('sys.api.networkExceptionMsg');
+      }
+
+      if (errMessage) {
+        if (errorMessageMode === 'modal') {
+          createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });
+        } else if (errorMessageMode === 'message') {
+          createMessage.error(errMessage);
+        }
+        return Promise.reject(error);
+      }
+    } catch (error) {
+      throw new Error(error as unknown as string);
+    }
+
+    checkStatus(error?.response?.status, msg, errorMessageMode);
+    return Promise.reject(error);
+  },
+};
+
+function createAxios(opt?: Partial<CreateAxiosOptions>) {
+  return new VAxios(
+    deepMerge(
+      {
+        // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
+        // authentication schemes,e.g: Bearer
+        // authenticationScheme: 'Bearer',
+        authenticationScheme: '',
+        timeout: 10 * 1000,
+        // 基础接口地址
+        // baseURL: globSetting.apiUrl,
+
+        headers: { 'Content-Type': ContentTypeEnum.JSON },
+        // 如果是form-data格式
+        // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
+        // 数据处理方式
+        transform: clone(transform),
+        // 配置项,下面的选项都可以在独立的接口请求中覆盖
+        requestOptions: {
+          // 默认将prefix 添加到url
+          joinPrefix: true,
+          // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+          isReturnNativeResponse: false,
+          // 需要对返回数据进行处理
+          isTransformResponse: true,
+          // post请求的时候添加参数到url
+          joinParamsToUrl: false,
+          // 格式化提交参数时间
+          formatDate: true,
+          // 消息提示类型
+          errorMessageMode: 'message',
+          // 接口地址
+          apiUrl: globSetting.apiUrl,
+          // 接口拼接地址
+          urlPrefix: urlPrefix,
+          //  是否加入时间戳
+          joinTime: true,
+          // 忽略重复请求
+          ignoreCancelToken: true,
+          // 是否携带token
+          withToken: true,
+        },
+      },
+      opt || {},
+    ),
+  );
+}
+export const defHttp = createAxios();
+
+// other api url
+// export const otherHttp = createAxios({
+//   requestOptions: {
+//     apiUrl: 'xxx',
+//     urlPrefix: 'xxx',
+//   },
+// });

+ 155 - 0
src/views/notification/list.vue

@@ -0,0 +1,155 @@
+<template>
+  <div class="p-4">
+    <BasicTable @register="registerTable">
+      <template #toolbar> </template>
+      <template #avatar="{ record }">
+        <Avatar :size="80" :src="record.avatar" />
+      </template>
+
+      <template #gender="{ record }">
+        {{ renderGenderLabel(record.gender) }}
+      </template>
+
+      <template #birthday="{ record }">
+        <Time v-if="record.birthday" :value="record.birthday" mode="datetime" />
+      </template>
+
+      <template #lastLoginTime="{ record }">
+        <Time :value="record.lastLoginTime" mode="datetime" />
+      </template>
+
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '详情',
+              onClick: () => {
+                go(`/order/list/detail/${record.orderNo}`);
+              },
+            },
+            {
+              label: '打印',
+              color: 'error',
+              onClick: () => {
+                createMessage.info(`暂未接入`);
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable, BasicColumn, FormProps, TableAction } from '/@/components/Table';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { uploadApi } from '/@/api/sys/upload';
+
+  import { ListApi } from '/@/api/notification/list';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useGo } from '/@/hooks/web/usePage';
+  import { Avatar } from 'ant-design-vue';
+  import { Time } from '/@/components/Time';
+
+  export default defineComponent({
+    components: { BasicTable, TableAction, Avatar, Time },
+    setup() {
+      const { createMessage } = useMessage();
+      const go = useGo();
+      const { t } = useI18n();
+      const columns: BasicColumn[] = [
+        {
+          title: 'ID',
+          dataIndex: 'id',
+          fixed: 'left',
+          width: 60,
+        },
+        {
+          title: '名称',
+          dataIndex: 'title',
+          // sorter: true,
+          width: 160,
+        },
+        {
+          title: '内容',
+          dataIndex: 'content',
+          // sorter: true,
+          width: 160,
+        },
+        {
+          title: '持续时间',
+          dataIndex: 'lastLoginTime',
+          slots: { customRender: 'lastLoginTime' },
+          // sorter: true,
+          width: 120,
+        },
+        {
+          title: '发布时间',
+          dataIndex: 'lastLoginTime',
+          slots: { customRender: 'lastLoginTime' },
+          // sorter: true,
+          width: 120,
+        },
+      ];
+
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        schemas: [
+          {
+            field: 'username',
+            label: '名称',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 5,
+              xxl: 5,
+            },
+          },
+        ],
+      };
+
+      const [registerTable] = useTable({
+        title: '消息列表',
+        api: ListApi,
+        columns: columns,
+        useSearchForm: true,
+        formConfig: searchForm,
+        showTableSetting: true,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        rowKey: 'id',
+        pagination: { pageSize: 20 },
+        bordered: true,
+        fetchSetting: {
+          pageField: 'page',
+          sizeField: 'limit',
+          listField: 'list',
+          totalField: 'totalCount',
+        },
+      });
+
+      function renderGenderLabel(gender: number): string {
+        switch (gender) {
+          case 0:
+            return '女';
+          case 1:
+            return '男';
+          default:
+            return '未知';
+        }
+      }
+
+      return {
+        registerTable,
+        createMessage,
+        t,
+        go,
+        renderGenderLabel,
+        uploadApi: uploadApi as any,
+      };
+    },
+  });
+</script>

+ 6 - 6
src/views/staff/list.vue

@@ -89,8 +89,8 @@
         lookNum: 0,
         shotNum: 0,
       });
-      const [registerDetail, { openModal: openDetaileModal }] = useModal();
-      const [registerDelList, { openModal: openDelListeModal }] = useModal();
+      const [registerDetail, { openModal: openDetailModal }] = useModal();
+      const [registerDelList, { openModal: openDelListModal }] = useModal();
       const { createConfirm, createMessage } = useMessage();
       const userStore = useUserStore();
       const { getCheckRole } = userStore;
@@ -247,10 +247,10 @@
         // ) {
         //   return createMessage.error('新增失败,可添加员工数量为0个');
         // }
-        openDetaileModal(true, {});
+        openDetailModal(true, {});
       }
       function handleEdit(record: Recordable) {
-        openDetaileModal(true, record);
+        openDetailModal(true, record);
       }
       function getNumByStaffData() {
         getNumByStaff({}).then((res) => {
@@ -261,7 +261,7 @@
       async function handleDelete(record) {
         let check = await preDelApi(record.id); //
         if (Array.isArray(check)) {
-          return openDelListeModal(true, {
+          return openDelListModal(true, {
             ...record,
             option: check,
           });
@@ -285,7 +285,7 @@
         registerTable,
         registerDetail,
         registerDelList,
-        openDelListeModal,
+        openDelListModal,
         createMessage,
         handDelconfirm,
         t,

+ 23 - 13
src/views/sys/login/RegisterForm.vue

@@ -1,12 +1,12 @@
 <template>
   <template v-if="getShow">
     <LoginFormTitle class="enter-x" />
-    <Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef">
+    <Form class="p-4 enter-x" :model="RegisterformData" :rules="getFormRules" ref="formRef">
       <FormItem name="account" class="enter-x">
         <Input
           class="fix-auto-fill"
           size="large"
-          v-model:value="formData.account"
+          v-model:value="RegisterformData.userName"
           placeholder="请输入手机号"
         />
       </FormItem>
@@ -18,18 +18,26 @@
           class="fix-auto-fill"
         />
       </FormItem> -->
-      <FormItem name="sms" class="enter-x">
+      <FormItem name="code" class="enter-x">
         <CountdownInput
           size="large"
           class="fix-auto-fill"
-          v-model:value="formData.sms"
+          :count="60"
+          :sendCodeApi="
+            () => {
+              return sendCodeApi({
+                phone: RegisterformData.userName,
+              });
+            }
+          "
+          v-model:value="RegisterformData.code"
           placeholder="请输入手机验证码"
         />
       </FormItem>
       <FormItem name="password" class="enter-x">
         <StrengthMeter
           size="large"
-          v-model:value="formData.password"
+          v-model:value="RegisterformData.userPassword"
           placeholder="请输入账号密码"
         />
       </FormItem>
@@ -73,6 +81,7 @@
   import { CountdownInput } from '/@/components/CountDown';
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useLoginState, useFormRules, useFormValid, LoginStateEnum } from './useLogin';
+  import { sendCodeApi } from '/@/api/sys/user';
 
   const FormItem = Form.Item;
   // const InputPassword = Input.Password;
@@ -82,16 +91,17 @@
   const formRef = ref();
   const loading = ref(false);
 
-  const formData = reactive({
-    account: '',
-    password: '',
-    confirmPassword: '',
-    mobile: '',
-    sms: '',
-    policy: false,
+  const RegisterformData = reactive({
+    userName: '',
+    userPassword: '',
+    // confirmPassword: '',
+    // mobile: '',
+    area: '86',
+    code: '',
+    // policy: false,
   });
 
-  const { getFormRules } = useFormRules(formData);
+  const { getFormRules } = useFormRules(RegisterformData);
   const { validForm } = useFormValid(formRef);
 
   const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER);

+ 2 - 0
types/axios.d.ts

@@ -23,6 +23,8 @@ export interface RequestOptions {
   ignoreCancelToken?: boolean;
   // Whether to send token in header
   withToken?: boolean;
+
+  useResult?: boolean;
 }
 
 // export interface Result<T = any> {

+ 1 - 0
types/config.d.ts

@@ -16,6 +16,7 @@ export interface MenuSetting {
   bgColor: string;
   fixed: boolean;
   collapsed: boolean;
+  siderHidden: boolean;
   canDrag: boolean;
   show: boolean;
   hidden: boolean;