6. 对SKILL进行一次全新尝试,改为框架+细节方式的实践及验证:admin-web联调与bug修复

6. 对SKILL进行一次全新尝试,改为框架+细节方式的实践及验证:admin-web联调与bug修复

上篇把 gateway 授权转发的问题搞定后,这篇接着进入 admin-web 前端第一次联调。

按 SKILL 框架+细节生成,AI 应该不会再犯之前那些低级错误------结果还是一路坑:RSA 加密被删了要找回来、UI 骨架错得离谱要重摆、svg-icon 组件找不到、汉堡菜单死活显示不对......每个坑都得揪出来骂回去才能改对。

这篇就是从 RSA 找回开始,到 hamburger 图标最后一次跑偏,全程记录 admin-web 第一轮联调的 bug 修复过程。

一、第一次联调,admin-web

1.1 admin-web第一次运行

第一次运行前后端

1.2 联调问题

先说两大问题:

1、登录密码还是明码,这是不对的前面就改过一次。不知道为什么仍然还是这样

2、界面完全对不上UI。这个是大问题,也要重新修改。

复制代码
admin-web 先说两大问题:
1、登录密码还是明码,这是不对的前面就改过一次。不知道为什么仍然还是这样
2、界面完全对不上UI。这个是大问题,也要重新修改。
objectivec 复制代码
补充:
1、ui-prototype\admin-web 是admin-web的ui设计图
2、注释写着「本工程后端无 RSA 解密,前端不做 RSA 加密」
那就是后端错误,也是要改的。SKILL中应该有这一块的说明。

这是补充前一任务的,接着完成前面任务

1.3 明文密码AI推脱

bash 复制代码
原来是以前web中有这一段
登录密码:前端 userStore.login 用 JSEncrypt + constants.PUB_KEY(RSA 公钥)加密后再传 loginApi。密码绝不明文传输。后端用 RSA 私钥解密后 BCrypt 校验。公私钥由后端启动时生成一对,前端 PUB_KEY 取自同一对公钥(写入 src/constants/index.js),两端保持一致。
我看下web-admin为什么会删除这一段。查一下web-admin中有没有上面这一段
这个要增加上,并在service-api中也要添加上
objectivec 复制代码
把前端加密加回来 + 给后端补 RSA 私钥解密,并把这条写进 service-api SKILL。我先读取相关文件当前状态并生成RSA密钥对。

这是对的,但不要加入RsaKeyManager.java,检测一下以前有代码里面肯定是有的,还可能是使用hutool的,不要引用第三方。

按这个思路重新接着操作
java 复制代码
 String pwd = RsaUtils.decode(form.getPassword());
 
 package com.ahjiguang.nesc.sys.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.ahjiguang.nesc.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

@Component
public class RsaUtils {

    private static String PRIVATEKEY;
    private static String PUBLICKEY;

    @Value("${ivy.security.private-key}")
    public void setPRIVATEKEY(String privateKey) {
        PRIVATEKEY = privateKey;
    }

    @Value("${ivy.security.public-key}")
    public void setPUBLICKEY(String publickey) {
        PUBLICKEY = publickey;
    }

    public static String encode(String data) {
        return encode(PUBLICKEY, data);
    }

    //加密
    public static String encode(String publicKey, String data) {
        if (StringUtils.isEmpty(data)) {
            return null;
        }

        RSA rsa = new RSA(null, Base64.decode(publicKey));
        byte[] encrypt = rsa.encrypt(StrUtil.bytes(data, CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
        return Base64.encode(encrypt);
    }

    public static String decode(String value) {
        return decode(PRIVATEKEY, value);
    }

    //解密
    public static String decode(String privatekey, String value) {
        if (StringUtils.isEmpty(value)) {
            return null;
        }

        RSA rsa = new RSA(Base64.decode(privatekey), null);
        byte[] decrypt = rsa.decrypt(Base64.decode(value), KeyType.PrivateKey);
        return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
    }
 

    }

按倒是三阶段复刻吧

等下,可不可以使用 Element Plus来实现呢

dart 复制代码
等下,可不可以使用 Element Plus来实现呢

1.4 登录还是带clientType

复制代码
 越说越生气 ,不是说了登录不用 clientType吗?
现在登录不进去了
ruby 复制代码
我还在测试,
你改代码到底以什么为标准的?完全就是你想的吗?那我要那些skill干嘛,那些开发文档干嘛。
你能不能想一想,你是一个上班牛马,有这么多规矩,你要遵守,才可以开发????
less 复制代码
登录界面没什么问题,
Phase B(任务 #245):布局组件(面包屑/Logo/滚动条/下拉)+ 仪表盘暗玻璃。
Phase C(任务 #246):14 个业务页表格/表单/按钮玻璃风,逐页对照原型。
是分开做还是一起做
css 复制代码
分开做吧,开始b

1.5 说改了,结果呢?

复制代码
请问你这是改了啥?大界面不改,有什么用?又不能截图。
菜单上满屏,
工作台严重靠右,
工作台等放在最下面了。
复制代码
可以,先搞骨架才对,不然一看就不对,
css 复制代码
右上的 工作台,数据大屏没有靠右
你好,xx  这个
骨架 OK 后,我把 Phase B 剩余的仪表盘结构重 这个做了再说吧
css 复制代码
又理解错我的意思了,
Phase B 做了

页面报错

vbscript 复制代码
Failed to load resource: the server responded with a status of 415 (Unsupported Media Type)
api/sys/role/page/1/undefined:1  Failed to load resource: the server responded with a status of 415 (Unsupported Media Type)
api/sys/dept/page/1/undefined:1  Failed to load resource: the server responded with a status of 415 (Unsupported Media Type)
api/sys/user/page/5/undefined:1  Failed to load resource: the server responded with a status of 415 (Unsupported Media Type)
api/sys/operlog/page/1/undefined:1  Failed to load resource: the server responded with a status of 404 (Not Found)
api/sys/operlog/page/6/undefined:1  Failed to load resource: the server responded with a status of 404 (Not Found)

这些要回去改后端,也要改的。
左侧菜单,应该是两级或三级,不是现在这样,如日志管理->登录日志
                                              |->操作日志,
                                              这些以ui为准

所以说,这次是叫联调,前后端都要一起改的。

1.6 Dto问题

css 复制代码
补充:
Menu pojo 没有 children 字段 这时就需要 MenuDto extends Menu

接着前面开发
复制代码
补充:
MenuDto 前面缺少的字段补充上,如children,其他需要的字段
接着前面开发
css 复制代码
再补充:
如果有其他的pojo字段不够时,就添加dto,同menu一样,需要的字段添加进dto中
打断多次,要记得当前任务,接着开发

先就改这些,有问题后面再说。

二、显示bug修改

2.1 日志bug

还有一个bug

javascript 复制代码
还有bug
oper-log 消费异常,跳过本条: Redisson is shutdown
这个应该每条都要保证记录,可以每十条一次,不能直接跳过。

admin-web也有一bug
左侧菜单:有两个工作台,这是哪里的问题,顺便看下。

// 清空操作日志 POST /sys/operLog/clean
  clean() {
  
  日志怎么可以清空?日志所有操作只能读,不可改,删

本来我准备说,删除方法要抛出异常,结果ai自己做到了,这一点还是值得表扬的。

三、遗留问题:树要不要加children

bash 复制代码
角色/部门/用户页调用的 deptApi.tree() 后端暂无 /dept/tree,本轮未补。
仪表盘「最近用户」依赖 User 分页返回 deptName/roleName 等联字段,若为空显示「---」,后续可按同原则为 User 建 DTO。
下一步可做 Phase C(全局玻璃风 el-table/el-dialog/el-button + 14 业务页逐页对照),或先补 /dept/tree。你定方向。
先补tree吧,下一步再C
复制代码
错了,如果叫tree的就是树,不要前端改。
接着前面的做
复制代码
Phase C

四、admin-web bug修复

4.1 admin-web 还是有bug

通过F12可以查看到admin-web还是有一些bug

ini 复制代码
[Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/dict" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn onAfterEnter=fn<afterEnter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys"  ... > 
  at <SidebarItem key="/sys4" item= Object base-path="/sys" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/config" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn onAfterEnter=fn<afterEnter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys"  ... > 
  at <SidebarItem key="/sys4" item= Object base-path="/sys" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/post" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn<enter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys"  ... > 
  at <SidebarItem key="/sys4" item= Object base-path="/sys" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/notice" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn<enter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys"  ... > 
  at <SidebarItem key="/sys4" item= Object base-path="/sys" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/log5" item= Object base-path="/sys/log" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/log/login" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn<enter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys/log"  ... > 
  at <SidebarItem key="/sys/log5" item= Object base-path="/sys/log" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Failed to resolve component: svg-icon
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <SidebarItem key="/sys/log/oper" is-nest=true item= Object  ... > 
  at <BaseTransition onBeforeEnter=fn<onBeforeEnter> onEnter=fn<enter>  ... > 
  at <Transition name="el-collapse-transition" onBeforeEnter=fn<beforeEnter> onEnter=fn<enter>  ... > 
  at <ElCollapseTransition > 
  at <ElSubMenu key=1 ref="subMenu" index="/sys/log"  ... > 
  at <SidebarItem key="/sys/log5" item= Object base-path="/sys/log" > 
  at <ElMenu default-active="/dashboard" collapse=false background-color="#1e293b"  ... > 
  at <ElScrollbar wrap-class="scrollbar-wrapper" > 
  at <Index key=1 class="sidebar-container" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Unhandled error during execution of setup function 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > key="/sys/log/login" > 
  at <KeepAlive include= Array(0) > 
  at <BaseTransition mode="out-in" appear=false persisted=false  ... > 
  at <Transition name="fade-transform" mode="out-in" > 
  at <RouterView> 
  at <AppMain> 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy(Object) > > 
  at <RouterView> 
  at <App>
warn$1 @ chunk-XHCA3OSI.js?v=07235b87:2277
chunk-XHCA3OSI.js?v=07235b87:2494 Uncaught ReferenceError: ref is not defined
    at setup (index.vue:6:20)

4.2 手动指明bug

ini 复制代码
1、header中的 左菜单收缩展开的那个图标和面包屑重叠
2、chunk-XHCA3OSI.js?v=07235b87:2277 [Vue warn]: Component inside <Transition> renders non-element root node that cannot be animated. 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > key="/sys/user" > 
  at <KeepAlive include= 
Array(0)
 > 
  at <BaseTransition mode="out-in" appear=false persisted=false  ... > 
  at <Transition name="fade-transform" mode="out-in" > 
  at <RouterView> 
  at <AppMain> 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< 
Proxy(Object)
 > > 
  at <RouterView> 
  at <App>
:8093/api/sys/proxy/roles:1 
 Failed to load resource: the server responded with a status of 404 (Not Found)
:8093/api/sys/proxy/posts:1 
 Failed to load resource: the server responded with a status of 404 (Not Found)

3、Total 4  Go to
页码这个改成中文

4.3 多事一举的代理

多事一举的代理,还将其他微服务的方法代理一下放Controller,脑子有时真是好东西。

bash 复制代码
1、向左收缩,显示的是图标,不是文字,这个要注意一下。现在这个按钮不显示了,
2、新建后端 ProxyController(/proxy/{key} → roles/posts 列表,对齐前端 proxyApi 契约),仅取未删除项。
我的点好奇,前端role为什么要proxy,直接访问sys就好了。全文检查一下是否还有这样的白痴问题。
 后端 ProxyController 绝对是你理解错误,还写进SKILL了。
 只有feign才要代理,加防腐层,也不可能wms代理sys的编写成Controller,feign只给本地服务使用,不对外
objectivec 复制代码
SKILL 调试模式
bash 复制代码
proxy-api.js 调 /sys/proxy/${key},dictStore.getProxyDict 也走它。
这个proxy指的是前端proxy,而不是后端也使用proxy,后端就是正常的访问。 这是补充的,如果改过了就不用理了。
工作台也要增加一个图标,

4.4 通用错误修改其他

前面发现的如果是通用的错误,也顺便修改一下 user-web 和 screen

sql 复制代码
前面发现的如果是通用的错误,也顺便修改一下 user-web 和 screen

4.5 就一收缩图标搞不定

复制代码
1、admin-web 单击向左收缩,再单击展开,那个图标显示还是有问题的
2、收缩后,系统管理,没有显示图标,而是显示文字,这个要改。
arduino 复制代码
操,你行不行
<svg data-v-4140561e="" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line data-v-4140561e="" x1="3" y1="6" x2="21" y2="6"></line><line data-v-4140561e="" x1="3" y1="12" x2="21" y2="12"></line><line data-v-4140561e="" x1="3" y1="18" x2="21" y2="18"></line></svg>

我说这个图标显示有问题,看不见。

五、小结

第一轮联调下来,总结几点:

  1. RSA 加密前端+后端一套都不能少。前端 JSEncrypt 加密、后端 hutool RSA 解密,公私钥由配置文件注入,这套流程早就有了,AI 说删就删得找回来。
  2. UI 骨架必须先做对。菜单折叠、布局对齐、面包屑重叠这些骨架问题不改对,后面业务功能做了也白做。
  3. SVG 图标显示就是个玄学问题。颜色、stroke-width、stroke 这些属性差一点都看不见,得反复试。
  4. ProxyController 是典型理解偏差。前端需要 proxy 不代表后端要新增 Controller,不然要微服务干嘛,每个都代理一下,那不是每一个微服务都是全的了?这就没有意义了,feign 只给本地服务用,不需要对外暴露。

下一篇继续:UI设计问题出在哪,网关为什么没按 SKILL 生成,jar包打包运行又出了哪些幺蛾子。

相关推荐
别动我齐刘海17 分钟前
从0到1独立搭建机器人软件系统
c++·人工智能·神经网络·opencv·目标检测·机器学习·机器人
Lambert28117 分钟前
同一个 Agent,用 Spring AI 2.0 和 AgentScope Java 各实现一遍:差的不止代码量
openai·ai编程
夏夜霜18 分钟前
糖球系列③:ESP 圆屏不跑模型,它只是后台的语音客户端
人工智能
小宋102119 分钟前
MCP 是什么:从零编写一个可供 AI 调用的工具服务
人工智能·github
桃西西呀22 分钟前
AI 为什么一本正经地胡说八道?3 个底层原因 + 2 个防坑法
人工智能·llm·ai编程
天空11023 分钟前
Claude Code 怎么换用 Claude Fable 5.1:配置步骤、端点验证方法,以及缓存降价 75% 到底省了多少(2026 年 9 月)
人工智能·ai编程
用户7686874404925 分钟前
我为什么不用 OpenAI 的 function calling,自己用正则解析工具调用
人工智能
正在走向自律25 分钟前
从 Python 基础到大模型落地:读《深入浅出 Python 人工智能》,吃透 AI 工程化 CRUD 实战
开发语言·人工智能·python·机器学习·知识脉络
长沙京卓26 分钟前
MagenticLite 设备需求:能不能本地跑,先分清 App 端和模型端
人工智能·ai