跳至主要內容

【BI】②项目构建

holic-x...大约 11 分钟项目bi-platform

【BI】②项目构建

前端项目构建

1.项目初始化

构建前端项目,搭建基于react的ant design pro项目脚手架,注意项目版本依赖问题(如果nodejs版本不兼容则适当调整即可)

# 使用 npm 加载脚手架
npm i @ant-design/pro-cli -g
# 创建前端项目
pro create bi-platform-frontend

# 选择umi版本(可以尝试umi4踩新坑,umi3提示选择简单还是全量脚手架),原使用umi3 simple

# 进入指定项目安装项目依赖
cd bi-platform-frontend
tyarn 或者 npm install

# 脚手架初始完成,进入开发状态
npm run start

# 项目启动完成访问http://localhost:8000/,第一次初始化加载会比较慢

​ 查看package.json文件,对照相应的启动命令看其配置,如果执行npm run dev命令本质上执行的是start:dev,可以看其指令配置中MOCK=none,由于此时还没有接入后台数据接口,因此需要借助MOCK模拟数据接口实现访问。重启项目npm run start访问,然后登录访问主页(start以模拟数据方式运行,dev命令禁用了MOCK调用自己定义的后端)

​ 项目构建完成,引入git仓库做版本管理

2.项目瘦身

框架本身生成的东西有很多,但实际上一些小型项目中不需要引用这么复杂的内容,为了优化代码结构,此处通过清理项目一些可能不会用到的东西给项目瘦身

(1)国际化移除:/src/locales

​ 国际化:集成了多种语言:中文、英文... ,考虑项目主要在国内访问,去除国际化配置;如果要使用国际化,还要去配置不同语言的引用

​ 在package.json文件中找到i18n-remove,这里提供了移除国际化的脚本( "i18n-remove": "pro i18n-remove --locale=zh-CN --write",),执行指令(如果指令执行失败,参考官方解决方案open in new window

pro i18n-remove --locale=zh-CN --write

# 指令执行出错,参考官方解决方案,此处参考引入依赖后再次尝试
yarn add eslint-config-prettier
yarn add eslint-plugin-unicorn

或者执行:yarn add eslint-config-prettier --dev yarn add eslint-plugin-unicorn --dev 

修改:
node_modules/@umijs/lint/dist/config/eslint/index.js
// es2022: true

​ 奇奇怪怪的问题:在vscode中执行指令报错,但是通过cmd窗口执行指令正常(指令执行完毕移除了一些关联配置)

image-20240416215904248

​ 指令执行是为了移除国际化相关配置文件,需要手动移除locales文件夹,完成清理后重启项目检查是否正常运行

​ 重启项目如果报错则进一步排查(例如移除国际化出现SyntaxError: Export 'SelectLang' is not defined,参考官方解决方案open in new window:将src/components/index.js 中的 SelectLang 变量删除)

image-20240416220911174

常见问题处理:左侧菜单栏不显示

​ 需要修改路由配置,给config/route.ts中配置的路由都加上name属性(随后重启项目尝试访问)

后端项目构建

1.项目初始化

项目构建配置

​ 后端项目构建引用此前的通用后台模板作为参考,基于模板脚手架进行开发。配置maven、jdk,全局搜索springboot-init调整为自己的项目名称配置(bi-platform-backend)

数据库连接配置

​ resources/application.yml:

​ 数据库用户名、密码配置、数据库名dada_db_bi_platform

项目启动接口测试

​ 访问:http://localhost:8101/api/doc.html#/home

2.数据表设计

用户表和图表信息表

-- 用户表
create table if not exists user
(
    id           bigint auto_increment comment 'id' primary key,
    userAccount  varchar(256)                           not null comment '账号',
    userPassword varchar(512)                           not null comment '密码',
    userName     varchar(256)                           null comment '用户昵称',
    userAvatar   varchar(1024)                          null comment '用户头像',
    userRole     varchar(256) default 'user'            not null comment '用户角色:user/admin',
    createTime   datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime   datetime     default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete     tinyint      default 0                 not null comment '是否删除',
    index idx_userAccount (userAccount)
    ) comment '用户' collate = utf8mb4_unicode_ci;

-- 图表信息表
create table if not exists chart
(
    id           bigint auto_increment comment 'id' primary key,
    goal				 text  null comment '分析目标',
    `name`               varchar(128) null comment '图表名称',
    chartData    text  null comment '图表数据',
    chartType	   varchar(128) null comment '图表类型',
    genChart		 text	 null comment '生成的图表数据',
    genResult		 text	 null comment '生成的分析结论',
    status       varchar(128) not null default 'wait' comment 'wait,running,succeed,failed',
    execMessage  text   null comment '执行信息',
    userId       bigint null comment '创建用户 id',
    createTime   datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime   datetime     default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete     tinyint      default 0                 not null comment '是否删除'
) comment '图表信息表' collate = utf8mb4_unicode_ci;

​ 根据设计好的数据表,删除默认的数据表结构,重新生成系统所需的表信息

3.基础模块开发

(1)代码生成器构建业务代码

​ 在Database模块中选中表,随后右键选择MyBatisX-Generator

image-20240416225522270

​ 代码生成成功在src/main/java/generator文件夹下可跟踪生成的代码,将代码对号入座即可

generatorcom.noob.springbootinit
domainmodel/entity
mappermapper
service、service/implservice、service/impl
resources/mapper调整对应实体映射

实体类调整

主键ID:@TableId(type = IdType.AUTO)调整为@TableId(type = IdType.ASSIGN_ID)(将原有自动递增序列调整为雪花算法生成唯一id,长整型)

逻辑删除:isDelete字段加上逻辑删除注解@TableLogic(逻辑删除字段)

飘红报错调整

​ 对于一些项目中暂时没有引入的内容可以先清理掉,例如第三方登录:UserService中的第三方登录接口(userLoginByMpOpen)、UserController中的userLoginByWxOpen、附带删除controller/WxMpController、wxmp文件夹(微信公众号接入相关)

重启项目测试

​ 用户注册=》用户登录,测试接口

(2)图表信息模块构建

controller层、dto层等内容

基于原有PostController进行改造,然后依次引入相关DTO定义等内容

【1】复制PostController为ChartController(将Post统一调整为Chart,注意大小写相关也要分别替换),注意全局替换一些关键字处理,不要搞错了

【2】注释调整:帖子=》图表

【3】根据飘红依次引入相关的实体定义

image-20240416232029731

​ 参考上述内容,在model/dto下创建chart包,将原有post下相关的xxxRequest复制过来修改为对应的ChartXXXRequest,然后再依次根据实际业务场景调整请求参数(先构建基础框架,再调整业务字段细节)

​ 类似地,在model/vo下创建ChartVO(从PostVO中构建),将字段定义替换为Chart中的内容

ChartController的addChart改造,设置要添加的Chart实体值(可用快捷键ALT+ENTER生成setter)然后结合ChartAddRequest看哪些是前端传递过来的,哪些是需要手动赋值的内容,填充即可。

​ 此外需要清理掉一些无关紧要的接口定义

【4】Service相关改造(参考PostService实现)

​ 先把项目飘红报错处理,搭建基础业务模块框架,然后再定位具体的业务实现

前后端联调

OpenAPI

​ 使用Ant Design Pro自带的openAPI工具,根据后端swagger接口文档,自动生成对应请求的service代码

​ 前端项目配置:config/config.ts配置openAPI参数:schemaPath

openAPI: [
    {
      requestLibPath: "import { request } from '@umijs/max'",
      // 或者使用在线的版本
      schemaPath: "http://localhost:8101/api/v2/api-docs",
      projectName:"noob-bi",
      // schemaPath: join(__dirname, 'oneapi.json'),
      mock: false,
    }
  ],

​ 打开package.json,执行openapi指令,生成swagger文件(在services目录多出一个noob-bi目录,里面自动生成调用后端指定接口的方法代码)(终端输入yarn run openapi

image-20240417203048502

前后端联调测试:

​ 修改app.tsx文件,配置baseURL:http://localhost:8101/

image-20240417203935550

​ 在pages/User/Login/index.tsx文件中添加接口请求(测试前后端联调)

useEffect(()=>{
    listChartByPageUsingPost({}).then(res=>{
      console.error('res',res)
    })
  })

image-20240417204054119

​ dev模式启动项目,访问前端:http://localhost:8000,F12检查接口是否正常响应即可

image-20240417204342735

项目模板优化

前端模板优化

​ 了解项目结构和内容,把一些不需要用到的东西清理掉

image-20240417205740212

项目结构说明(❌表示可删除)
.husky检查提交的代码,是否规范(代码检验的小工具)
configumi配置(包括路由、构建等配置)
config.tsAnt Design Pro核心配置(整个项目所用框架配置)
defaultSetting.tsAnt Design Pro默认配置
opeapi.json示例数据(❌)
proxy.ts代理(便于本地开发)
router.ts定义网页路由(输入网址跳转页面)
mock本地模拟数据(❌)
public/iconsicons目录存放页面图标(❌)可以引入自定义图标
src/.umi框架自动生成的隐藏文件(可不管)
src/components业务通用组件
src/locales国际化资源(❌)搭配去除国际化指令删除
src/pages业务页面入口和常用模板
src/service后台接口服务
access.ts控制页面访问权限
app.tsxAnt Design Pro框架的主要文件
global.less全局样式
global.tsx全局JS
manifest.json开发app或者h5网页指定多种不同配置(此处可❌)
例如:生成项目名称、项目图标尺寸等(打包的时候用到)
requestErrorConfig.js控制前端页面发送请求的配置
service-worker.jsh5网页离线时优化页面的体验
tests测试工具(❌)
types
.editorconfig
.eslintignore
.eslintrc.js
.prettierignore
.prettierrc.js
保证前端项目代码规范
jest.config.ts单元测试框架
jsconfig.json控制语法
README.md项目默认文档

图标替换:iconfontopen in new window

public目录:(svg下载)logo.svg替换、(png下载)favicon.ico替换

image-20240417211725596

标题替换

​ 【ctrl+shift+F】将原有Ant Design Pro相关的内容替换为项目相关

模块开发

登录模块构建

无用代码清理

​ 删除pages/User/Login下的_snapshots_/login.test.tsx.snap

​ pages/User/Login/index.tsx文件中的<Lang />飘红,没有用到直接删除(Lang配置相关)

image-20240417213507587

​ 删除自动登录、其他登录方式、手机号登录登相关代码

image-20240417214123121

image-20240417214103834

​ 忘记密码?调整为注册(实现注册接口)

image-20240417214604885

​ 调整完成页面参考如下所示

image-20240417214703754

登录功能实现

​ 关注<LoginForm>组件实现,将用户输入的内容(key)替换为后端对应的内容即可(查看登录接口请求参数即可)

​ name =》userAccount、password=》userPassword

​ 可修改placeholder属性(输入提示)

image-20240417215046560

​ 删除错误填写验证相关

image-20240417215400979

后端接口对接

定位onFinish=》当用户点击登录后执行handleSubmit方法,将LoginParams调整为后端的

image-20240417215935916

handleSubmit&fetchUserInfo修改:

image-20240417220220507image-20240417220240652

/**
   * 登陆成功后,获取用户登录信息
   */
  const fetchUserInfo = async () => {
    const userInfo = await getLoginUserUsingGet();
    if (userInfo) {
      flushSync(() => {
        setInitialState((s) => ({
          ...s,
          currentUser: userInfo,
        }));
      });
    }
  };

  /*
  useEffect(()=>{
    listChartByPageUsingPost({}).then(res=>{
      console.error('res',res)
    })
  })
  */

  const handleSubmit = async (values: API.UserLoginRequest) => {
    try {
      // 登录
      const res = await userLoginUsingPost(values);
      if (res.code === 0) {
        const defaultLoginSuccessMessage = '登录成功!';
        message.success(defaultLoginSuccessMessage);
        await fetchUserInfo();
        const urlParams = new URL(window.location.href).searchParams;
        history.push(urlParams.get('redirect') || '/');
        return;
      } else {
        message.error(res.message);
      }
    } catch (error) {
      const defaultLoginFailureMessage = '登录失败,请重试!';
      console.log(error);
      message.error(defaultLoginFailureMessage);
    }
  };

​ 如果userName、userAvatar没有显示可以在后台数据库中补充(后续再完善代码细节),完成上述步骤启动登录验证接口是否调通

清理未引用的内容

VSCode快捷键(shift+alt+O)

image-20240417220912002

全局状态保存

​ app.tsx文件,找到getInitialState函数修改。然后按【shift+alt+O】清理无用引用

image-20240417221303168

export async function getInitialState(): Promise<{
  currentUser?: API.LoginUserVO;
}> {
  const fetchUserInfo = async () => {
    try {
      const res = await getLoginUserUsingGet();
      return res.data;
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };
  // 如果不是登录页面,执行
  const { location } = history;
  if (location.pathname !== loginPath) {
    const currentUser = await fetchUserInfo();
    return {
      currentUser,
    };
  }

  return {};
}

头像加载

​ 登录后访问发现头像转圈圈没有加载进去,数据库中用户对应userAvatar要配置为对应头像链接

​ 修改app.tsx的头像配置

image-20240417221753950

​ 修改用户名配置:src/compontents/RightContent/AvatarDropdown.tsx(头像下拉框),将name修改为userName

image-20240417222040644

​ 此处继续访问发现登录跳转页面后还是无法加载,排查loading组件(打印登录用户信息发现没有数据)发现还是没有登录(说明用户登录状态没有保存成功)

image-20240417222940912

需要在app.tsx中配置withCredentials: true

export const request = {
  baseURL:"http://localhost:8101",
  withCredentials: true,
  ...errorConfig,
};

image-20240417223247236

errConfig配置(requestErrorConfig.ts配置)

​ 可以将requestErrorConfig.ts重命名为requestConfig.ts(这个文件中定义了请求处理、请求拦截器、响应拦截器)。(重命名需注意app.tsx的引用也要相应修改)

​ 请求拦截器中给所有的请求都加上了token字段,可以将这部分注释掉,这样通过F12查看接口看起来简洁一点

image-20240417223909992

image-20240417223940650

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3