news 2026/9/16 7:03:51

基于SSM+Vue的药房药品管理系统实战:从表设计到部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于SSM+Vue的药房药品管理系统实战:从表设计到部署

简介:这份药房药品管理系统源码,基于Java后端语言,整合SSM框架与Vue前端技术,面向Web开发初学者、Java工程师及毕业设计学生,可帮助解决药品信息管理、库存盘点、进货销售等业务场景的快速实现问题。压缩包为zip格式,整体大小约22.7MB,主要包含Spring、SpringMVC、MyBatis的Java后端源码,Vue前端页面与交互逻辑,以及MySQL数据库建表脚本和Maven配置,使用IDEA或Eclipse导入即可查看运行。系统采用前后端分离设计,后端由SSM和SpringBoot协作提供接口服务,前端Vue负责数据展示与操作交互,覆盖药品分类、供应商、库存预警等常见模块,完整展示了企业级药品管理系统的代码组织方式。其中SQL脚本预置了药品表、订单表等核心数据表,Maven配置帮助管理依赖,Vue组件拆分清晰,便于二次开发。目前该资源已有83人浏览学习,对正在做课程设计或毕业设计的同学,是一份值得参照的完整源码方案。

1. 药房药品管理系统选型:SSM 负责数据,Vue 负责交互

药房的日常业务看着就三件事:进药、卖药、盘库存。但把批号、效期、供应商、处方来源这些字段引进来之后,表结构会一下子变厚,页面交互也从单表增删改查变成多条件搜索、批次选择、临期高亮。SSM + Vue 在药房药品管理系统里是出现频率很高的组合,SSM 三件套把接口、事务、SQL 分得清清楚楚,Vue 把表格和表单交互做成单页体验。

要读懂一套这种实现源码,或者拿它改造成一个能上线的药房系统,重点不在框架 API,而在数据表怎么拆、库存怎么扣、效期怎么预警、权限怎么收敛,这四个点正好对应后面四章的落点。这篇按源码落地路径来讲,适合 java 后端初学者,也适合要接手这种老项目做二次开发的人。

2. SSM 后端的工程分层与药品数据表设计

2.1 先看懂 SSM 工程的 maven 依赖与包结构

拿到一份 SSM 药房系统源码,第一件事不是启动,而是先看工程长什么样。常见做法是单一 maven war 工程,按 controller、service、mapper、entity 四个包分前后依赖。Spring 容器配置分成 applicationContext.xml 和 spring-mvc.xml:前者扫 service、mapper、datasource,后者只扫 controller。这样拆是因为 SpringMVC 有父子容器机制,子容器里配置的 Controller 不能直接依赖父容器没有的 Bean,乱扫会出现一堆“找不到 bean”的启动报错。

<properties> <spring.version>5.2.22.RELEASE</spring.version> <mybatis.version>3.5.10</mybatis.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.11</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> </dependencies>

依赖版本有一点要注意:Spring 5 的 spring-webmvc 和 spring-context 版本必须一致,否则运行期报 NoSuchMethodError;MyBatis 3.5.x 必须配 mybatis-spring 2.x,这个组合与 Spring 5 才兼容。Druid 数据源不是必须的,但药房系统并发不大,Druid 自带监控页排障很方便,我一般会保留。

提示:如果源码还在用 Spring 4.x,先跑通再升级,不要一上来就改大版本,否则一堆过时的 Spring XML 配置会先爆出兼容错误。

2.2 拆成药品、批次、流水三张表,效期才有地方放

同一种药会按批进货,各批次的进价、售价、有效期不同。若把库存直接放在药品表,批次信息就无处存放,效期预警也无从谈起。所以基本表结构至少拆成三张:drug 表保存通用名、规格、厂家、库存上下限;drug_batch 表保存批号、生产日期、失效日期、当前数量;stock_record 表按时间顺序记录每一笔出入库。

CREATE TABLE drug ( id BIGINT PRIMARY KEY AUTO_INCREMENT, drug_code VARCHAR(32) NOT NULL COMMENT '药品编码', drug_name VARCHAR(64) NOT NULL COMMENT '通用名', spec VARCHAR(64) COMMENT '规格', unit VARCHAR(10) COMMENT '单位', form VARCHAR(20) COMMENT '剂型', manufacturer VARCHAR(128) COMMENT '生产厂家', min_stock INT DEFAULT 0 COMMENT '库存下限,低于此值预警', max_stock INT DEFAULT 0 COMMENT '库存上限,高于此值积压', status TINYINT DEFAULT 1 COMMENT '1启用 0停用', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_drug_code (drug_code) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE drug_batch ( id BIGINT PRIMARY KEY AUTO_INCREMENT, drug_id BIGINT NOT NULL, batch_no VARCHAR(32) NOT NULL COMMENT '生产批号', product_date DATE COMMENT '生产日期', expire_date DATE NOT NULL COMMENT '失效日期', quantity INT NOT NULL DEFAULT 0 COMMENT '当前批次剩余数量', purchase_price DECIMAL(10,2) COMMENT '采购单价', sale_price DECIMAL(10,2) COMMENT '零售单价', UNIQUE KEY uk_drug_batch (drug_id, batch_no), KEY idx_expire (expire_date) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

字段命名全部用下划线,MyBatis 开启 mapUnderscoreToCamelCase 后自动映射 drugCode 这类驼峰属性,不用每个实体都写 resultMap。uk_drug_batch 唯一键保证同一药品同一批号只有一条记录;idx_expire 索引是给效期预警查询用的,后面第 4 章会专门讲。

药品主数据、批次库存、流水记录三张表的职责边界如下:

表名用途关键字段
drug药品基础档案drug_code, drug_name, min_stock, max_stock
drug_batch批次级库存与效期batch_no, expire_date, quantity
stock_record出入库流水与审计change_qty, type, operator

2.3 批次扣减:把判断写进 UPDATE,避免超卖

出库是药房系统并发最高的操作。常见错误是先查再改,两个请求同时读到 quantity=10,各自扣 5,最后一次更新把结果覆盖错。解决方式是把判断条件写进 update 语句,靠数据库行锁保证原子性。

<update id="deductBatchStock"> UPDATE drug_batch SET quantity = quantity - #{qty} WHERE id = #{batchId} AND quantity >= #{qty} AND expire_date > #{today} </update>

WHERE 里两个条件缺一不可:quantity >= #{qty} 保证扣减后不会变成负数;expire_date > #{today} 保证过期批次不会被发出去。update 返回影响行数,返回 0 就说明数量不够或批次已过期,service 层直接抛业务异常,不必再查一次。如果你读过 MyBatis 的 update 执行路径就能明白,影响行数来自 JDBC 的 executeUpdate 返回值,判断成本极低。

提示:药店场景单量不大,条件更新足够用。如果要改成连锁药房多门店同时发药,就要在 drug_batch 表加 version 字段做乐观锁,或者直接引入分布式锁。

2.4 Service 层事务边界与配置

库存变更涉及两个写操作:扣减批次数量、插入流水。如果只扣了库存、流水插入失败,账面就乱了。SSM 里事务一般落在 service 实现类上。

@Service public class StockService { @Transactional(rollbackFor = Exception.class) public StockRecord outStock(StockOutDTO dto) { int rows = drugBatchMapper.deductBatchStock( dto.getBatchId(), dto.getQty(), new Date()); if (rows == 0) { throw new BizException("库存不足或药品已过期"); } StockRecord record = new StockRecord(); record.setDrugId(dto.getDrugId()); record.setBatchId(dto.getBatchId()); record.setChangeQty(-dto.getQty()); record.setType(2); // 2 表示出库,正负号见 4.1 的约定 record.setOperator(SecurityUtils.getCurrentUserName()); stockRecordMapper.insert(record); return record; } }

rollbackFor 必须显式写成 Exception.class。Spring 默认只对 RuntimeException 回滚,如果抛的是自定义 checked 异常,事务会正常提交,流水和库存对不上,月底盘点才暴雷。事务传播级别用默认 REQUIRED 就够,这种单库场景不需要 NESTED 和 REQUIRES_NEW,写多了反而容易把事务拆断。

3. Vue 前端的接口对接与页面状态管理

3.1 开发环境先解决跨域:vite 代理与参数说明

Vue 开发服务器默认跑在 3000 或 8080,后端 SSM 打进 Tomcat 后跑在 9090,两者不同源。药房系统登录态靠 token 传递,为了避免每个请求都走浏览器 CORS 预检,开发时用前端代理把 /api 前缀的请求转发到后端最省事。

// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], server: { port: 3000, proxy: { '/api': { target: 'http://localhost:9090', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } } })

target 是后端 SSM 的根地址,一般就是 Tomcat 的访问根路径;changeOrigin 设为 true 会改写请求的 Host 头;rewrite 把 /api 前缀剥掉,后端 Controller 里就不需要额外加一层 context-path。如果拿到的是 vue-cli 工程,对应配置写在 vue.config.js 的 devServer.proxy 里,字段含义一致。

参数作用本例子取值
target后端接口地址http://localhost:9090
changeOrigin改写请求 Host 头true
rewrite去除路径前缀/^/api//

另一个坑是后端如果已经配了 CorsFilter,前端又开代理,两个机制叠加会产生重复的 Access-Control-Allow-Origin 响应头。排查时直接看浏览器 Network 面板,响应头里出现两个同名头就注释掉后端的过滤器。

3.2 axios 统一封装:token 注入、响应码处理、401 跳转

大部分页面都要登录态,最省事的方式是登录成功把 token 存 localStorage,axios 请求拦截器统一塞进 Header,响应拦截器统一处理 401 和业务错误。

import axios from 'axios' const service = axios.create({ baseURL: '/api', timeout: 10000 }) // 请求拦截器:注入 token service.interceptors.request.use(config => { const token = localStorage.getItem('pharmacy_token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) // 响应拦截器:处理业务码与登录态失效 service.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { return Promise.reject(new Error(res.message || '请求失败')) } return res }, error => { if (error.response && error.response.status === 401) { window.location.href = '/login' } return Promise.reject(error) } ) export default service

这里约定后端未登录时返回 HTTP 401,前端靠 status === 401 跳登录页。如果后端习惯返回 200 加业务码 401,两边的逻辑就要统一改成业务码判断,否则会出现“提示成功但页面没数据”的假象。超时时间建议设 10 秒,药房系统的导出报表接口偶尔会超过这个值,可以在具体调用里用service.get(url, { timeout: 30000 })单独覆盖。

3.3 路由拆成登录、主框架、业务页面,参数尽量走 query

后台管理端的路由结构固定:登录页独立,主框架 Layout 负责侧边栏和内容区,业务页面挂成 children。懒加载写法让首屏只下载必要的 chunk。

const routes = [ { path: '/login', component: () => import('@/views/Login.vue') }, { path: '/', component: () => import('@/layout/Layout.vue'), redirect: '/dashboard', children: [ { path: 'dashboard', name: 'Dashboard', component: () => import('@/views/Dashboard.vue'), meta: { title: '工作台' } }, { path: 'drug/list', name: 'DrugList', component: () => import('@/views/drug/List.vue'), meta: { title: '药品管理' } }, { path: 'stock/in', name: 'StockIn', component: () => import('@/views/stock/In.vue'), meta: { title: '入库' } }, { path: 'stock/warn', name: 'StockWarn', component: () => import('@/views/stock/Warn.vue'), meta: { title: '效期预警' } } ] } ]

meta.title 用来做侧边菜单的循环渲染,加新页面时只需在 children 里加一项。vue-router 4(Vue 3 默认)跳转时传参有 query 和 params 两种:query 会拼在 URL 后面,刷新不会丢;params 存在内存里,刷新页面就空了。药房系统里从列表页跳到药品详情页传药品 id,用 query 最稳,别用 params,否则用户一刷新就跳回列表。

3.4 列表页分页搜索的传参技巧

药品列表是药房系统的核心页面,搜索条件一般有药品名称、编码、厂家、是否只看低库存。封装查询函数时,最忌讳把整个表单对象原样传给后端。

import service from '@/utils/request' export function getDrugList(params) { return service({ url: '/drug/list', method: 'get', params }) }
async function loadList() { const params = { pageNum: page.pageNum, pageSize: page.pageSize, drugName: searchForm.drugName || undefined, drugCode: searchForm.drugCode || undefined, manufacturer: searchForm.manufacturer || undefined, lowStockOnly: searchForm.lowStockOnly || false } const res = await getDrugList(params) list.value = res.data.records total.value = res.data.total }

空字符串转成 undefined 的原因:axios 序列化参数时,值为 undefined 的字段会直接跳过,不进入 URL。后端 MyBatis 的动态 SQL 只需要判断字段是否为 null,不用关心空字符串,条件更干净。每次点击搜索都要把 pageNum 重置为 1,否则可能出现停留在第 5 页搜索到空列表的体验问题。排查列表页数据时,优先用 Vue DevTools 看组件的 list 和 total 是否赋值,再看 Network 面板的请求参数,两步能定位 90% 的问题。

4. 药房核心业务:库存流水、效期预警与操作权限

4.1 出入库必须双写:扣批次、记流水

药房系统的价值不在“能增删改查”,而在每一盒药都能追溯。入库、出库、退货、盘点调整这四类动作都要落在 stock_record 表,type 字段约定如下:

type含义change_qty 方向
1入库正数
2出库负数
3退货正数
4盘点调整正数或负数

前端提交时,后端要校验 type 的取值,不能直接存前端传的任意数字。业务单号可以单独建一个字段,比如 RK20250101001、CK20250101003,流水列表按 record_time 倒序分页展示。遇到报损、报废这类场景,复用 type=4 盘点调整,在 remark 里写明原因就行,不需要为每个动作单独建表。

出库时由仓库人员指定批次,更接近药房实际操作习惯。如果要做成自动分配批次,一般是“近效期先出”,也就是按失效日期升序取批次循环扣减:

SELECT id, quantity, expire_date FROM drug_batch WHERE drug_id = #{drugId} AND quantity > 0 AND expire_date > CURDATE() ORDER BY expire_date ASC LIMIT 10;

service 层拿到结果后循环调用 deductBatchStock,一个批次不够就扣下一个批次,直到满足出库数量。这里要格外注意:循环中任意一次扣减失败,整个事务都要回滚,不能出现前一批扣了、后一批失败导致账目错乱。

4.2 效期预警:按剩余天数动态算,别只靠定时任务

很多源码用 quartz 每天凌晨扫一遍库,把临期药品写预警表。这个方案能用,但当天的入库药品要第二天的任务跑完才出现,且阈值调整麻烦。更可靠的方式是查询时动态计算剩余天数。

SELECT d.drug_code, d.drug_name, d.spec, b.batch_no, b.quantity, b.expire_date, DATEDIFF(b.expire_date, CURDATE()) AS remain_days FROM drug_batch b INNER JOIN drug d ON d.id = b.drug_id WHERE b.quantity > 0 AND b.expire_date <= DATE_ADD(CURDATE(), INTERVAL #{warnDays} DAY) ORDER BY b.expire_date ASC;

warnDays 从系统参数表读取,药房一般配置两级:90 天以内标黄,30 天以内标红。前端拿到 remain_days 后做样式判断,不影响后端逻辑。这段 SQL 走的正是 drug_batch 表上的 idx_expire 索引,数据量上来之后依然能保持稳定。

预警页面实时查询的另一个好处是,参数调整立即生效。把阈值塞进定时任务里的做法,改一次配置要重启或手动触发,运维成本高。定时任务可以保留一个,用来每天把临期批次导出报表,页面预警走实时查询,两者职责分开。

4.3 权限控制:HandlerInterceptor 加会话,不急着引 Shiro

药房系统用户模型通常就管理员、库管员、收银员三种,没有复杂的组织架构和细粒度权限。Spring Security 和 Shiro 在这个体量下都偏重。务实做法是用 SpringMVC 的 HandlerInterceptor 做 URL 级控制。

public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { User user = (User) request.getSession().getAttribute("loginUser"); if (user == null) { response.setStatus(401); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":401,\"message\":\"未登录或已过期\"}"); return false; } if (request.getRequestURI().startsWith("/admin/") && !"ADMIN".equals(user.getRole())) { response.setStatus(403); response.getWriter().write("{\"code\":403,\"message\":\"无权限访问\"}"); return false; } return true; } }

拦截器注册时记得放行登录接口和静态资源:

<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/login"/> <mvc:exclude-mapping path="/css/**"/> <mvc:exclude-mapping path="/js/**"/> <mvc:exclude-mapping path="/druid/**"/> </mvc:interceptor> </mvc:interceptors>

提示:很多人把登录页也拦截了,导致系统一访问就 401,调试半天才发现是路径放行配置写错。所有静态资源和登录接口必须放在 exclude-mapping 里。

药房这类系统,操作留痕比复杂权限模型更重要。即使不做细粒度权限,也要在每次增删改时写操作人,在 service 里从会话中取,不要用前端传的值。这既是审计要求,也是出纠纷时追责的依据。

5. 打包部署的验证顺序与后端排错技巧

5.1 本地到服务器:war 包和 dist 目录两条发布路径

SSM 后端打 war 包部署到 Tomcat,前端 Vue 打包成静态文件。上线前按顺序验证:先执行构建命令,确认打包能过,再把 war 包丢进 Tomcat。

mvn clean package -DskipTests cp target/pharmacy-web.war /opt/tomcat/webapps/ROOT.war /opt/tomcat/bin/startup.sh tail -f /opt/tomcat/logs/catalina.out

启动后第一件事不是开页面,而是看 catalina.out 里有没有成功的部署日志和数据库连接池初始化日志。Druid 连接失败往往不影响 Tomcat 启动,而是第一个请求进来才报错,这种延迟暴露的问题最迷惑人。数据库连接串里的时区参数要写成 serverTimezone=Asia/Shanghai,连接 8.x MySQL 时不带时区会直接报错。

Vue 前端构建产物放到 Nginx 静态目录,接口请求反向代理到后端:

server { listen 80; server_name pharmacy.example.com; root /data/pharmacy/dist; index index.html; location /api/ { proxy_pass http://127.0.0.1:9090/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

proxy_pass 末尾的斜杠非常关键,它会把 /api/login 重写成后端 /login,与开发环境 vite 的 rewrite 保持一致,后端 Controller 不用改任何路径。如果 Vue 路由用的是 history 模式,直接访问 http://pharmacy.example.com/stock/warn 会 Nginx 404,这不是打包后布局异常,而是 Nginx 没有对应的静态文件兜底,需要加一行try_files $uri $uri/ /index.html;。发布前还要确认服务器上java -versionmvn -vnode -v都可用,老 vue-cli 工程对 Node 版本要求与新 vite 工程不一样,版本太新反而可能装不上依赖。

5.2 接口 404、MyBatis 绑定异常、跨域三类报错定位顺序

后端接口 404,先看 Tomcat 访问日志,确认请求到了容器没有。如果是已经到了容器但 404,检查 SpringMVC 的 @RequestMapping 全路径和前端实际路径是否一致,最常见的是 /api 前缀在前端代理里没剥干净。开发阶段可以把 spring-mvc.xml 的日志级别调到 DEBUG,看 HandlerMapping 匹配到了哪个方法:

<logger name="org.springframework.web.servlet.mvc.method.annotation" level="DEBUG"/>

MyBatis 报 “Invalid bound statement (not found)”,检 查三处:Mapper 接口的包路径是否和 mybatis 扫描包一致;XML 文件是否放在 resources/mapper 下且被 maven 当作资源打入 classpath;Mapper 接口方法名与 XML 里的 id 是否完全一致。这三个问题轮着查一遍,绑定异常基本解决。

跨域报错不要只在前端查。打开 F12 的 Network 面板,响应头里没有 Access-Control-Allow-Origin 才是真正的后端问题;如果出现了但请求还是失败,通常是 OPTIONS 预检没有正确处理。确认前端开了代理、后端关了 CorsFilter,两边不叠加是最省心的配置。

5.3 上线前把慢 SQL 和 Druid 监控打开

药房系统部署完毕后,最容易被忽略的是数据库索引和 SQL 执行计划。drug_batch 表上的 idx_expire 和 uk_drug_batch 就是为预警和批次查询准备的,上线前跑一遍 explain 确认 SQL 真实走了索引。如果 drug_batch.quantity 在 where 条件里参与判断时走了全表扫描,优先优化索引,不要急着加 Redis 缓存,药房业务对数据一致性要求远高于对性能的要求。

把 MySQL 慢查询日志打开,阈值设 500ms,观察一周里出现频率最高的 SQL:

SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 0.5;

同时打开 Druid 监控页,默认地址是 /druid/index.html,可以看到连接池活跃数、慢查询和每个接口的执行统计。药房这类小并发系统,瓶颈很少在 Tomcat,而在 SQL 上。排查时把 Druid 的 SQL 列表拉出来对照 explain 结果,最容易翻车的写法是 where 条件里对日期字段做函数运算,比如MONTH(expire_date) = 5会让索引失效,改成expire_date BETWEEN '2025-05-01' AND '2025-05-31'才能命中 idx_expire,这条经验在效期统计场景里百试百灵。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 7:02:52

蓝桥杯《三国游戏》贪心+排序解法:从暴力到最优的完整思路

拿今年蓝桥杯省赛的《三国游戏》来说&#xff0c;它表面上是一道模拟三国对抗的题目&#xff0c;实际上考的是贪心加排序&#xff0c;属于竞赛里非常典型的“转化后求最优”问题。很多同学第一次看到它&#xff0c;第一反应是去枚举所有事件组合&#xff0c;结果发现n一上来就是…

作者头像 李华
网站建设 2026/9/16 7:01:42

RoboMaster硬件调试实战讲义:从故障切入的系统级思维训练

1. 这份讲义到底在解决什么问题&#xff1f;——不是教你怎么焊电路&#xff0c;而是帮你建立硬件工程师的“肌肉记忆”“Robomaster硬件基础讲义V0.2.1”这个标题里藏着三个关键信号&#xff1a;Robomaster是场景&#xff0c;硬件是领域&#xff0c;V0.2.1是版本号——它不是最…

作者头像 李华
网站建设 2026/9/16 6:59:48

用C语言构建最小x86计算机:南大ICS PA1硬件模拟器实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 6:59:13

AR-NAR混合Transformer:低延迟高质量序列生成新范式

1. 项目概述&#xff1a;从“YuE”到AR–NAR MoT——一个被低估的序列建模新范式如果你最近在Hugging Face上刷模型库&#xff0c;或者关注过ACL、ICLR近年关于文本生成、语音合成或时间序列预测的论文&#xff0c;大概率已经见过“YuE”这个名字。它不是某个网红AI工具的代号&…

作者头像 李华
网站建设 2026/9/16 6:58:21

Nodejs 部署阿里云监听 IP 失败?用 TaoToken 给 Codex 配通道再查 0.0.0.0

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 6:58:08

Windows虚拟内存与OOM排查:分页文件配置实战指南

1. 为什么“大内存时代”仍然绕不开虚拟内存先说一个我经常遇到的场景&#xff1a;机器明明配了 16GB 甚至 32GB 内存&#xff0c;任务管理器里看物理内存也只用了 60% 左右&#xff0c;结果跑一个稍微大一点的程序&#xff0c;系统直接弹“内存不足”&#xff0c;或者某个进程…

作者头像 李华