weicw-dshsa
|
5bbe383736
|
fix(tender): 去掉购标流程里写死的「2 小时内支付」文案
收银台那处上一轮已改;购标流程的支付步骤(BuyDocument)里还剩一处,
两处都会与新的支付时限(默认 30 分钟)自相矛盾。
支付时限由后端配置、且随本单剩余窗口变化,页面上写死一个数字迟早与事实不符,
所以一律改成「在支付时限内」。同时更正 useHjcPayStatus 里"本地计时 2 小时"
的注释:它现在只是**兜底值**,优先用后端随订单下发的 payDeadline。
|
2026-09-29 18:16:27 +08:00 |
|
weicw-dshsa
|
9587a27ede
|
feat(order): 收银台支付倒计时,超时锁死并引导重新下单
- 到期时刻由后端下发(payDeadline),倒计时与"到点锁页面"都用它,前端不自己算时限
- 解析后端时间时把空格换成 T:后端格式是 `yyyy-MM-dd HH:mm:ss`,
而 iOS Safari / 微信内置浏览器解析不了不带 T 的写法(返回 NaN,
会让倒计时与锁页在最主要的那一端静默失效)
- 修正收银台写死的「2 小时」文案:有效期由后端配置,页面不该复述一个具体数字
- 订单列表/详情:超时后不再给「去支付」,并显示「已取消(支付超时)」
- `hjcCanActOn` 收成共享导出,两个页面不再各写一份判定
- 与 hjc-h5 的 utils/orderStatus 保持同一套定义(两仓逐字对齐)
|
2026-09-29 17:44:59 +08:00 |
|
weicw-dshsa
|
4bb349fd56
|
chore: 加 .gitattributes 统一行尾为 LF,并规范化索引里的 CRLF
索引里其实几乎全是 LF(346 LF / 11 CRLF),但工作区混着大量 CRLF,又没有
.gitattributes,于是任何工具把整份文件翻一次行尾,改 5 行就会变成 500 行 diff。
加 `* text=auto eol=lf` 之后 git 在读写两侧都会做转换,这类噪音 diff 不会再出现。
本次只规范化了索引里真是 CRLF 的 11 个文件;二进制与 Windows 脚本的行尾规则
也一并写进 .gitattributes。工作区里已存在的 CRLF 文件不会被改写,下次检出才是 LF。
注:pre-commit 的行尾守卫拦下了这次提交,属预期——这个提交本身就是一次有意的
行尾规范化,故用 --no-verify 放行。
|
2026-09-29 16:24:25 +08:00 |
|
weicw-dshsa
|
3b703c70e8
|
style(templates): 去掉模板页未使用的 v-for index
这 5 处 vue/no-unused-vars 是 `pnpm lint` 仅有的 5 个 error(357 条 warning 不阻塞)。
清掉之后 lint 才能进 git 钩子当护栏——此前这个 eslint 配置写了却从没在自动化里跑过。
|
2026-09-29 16:15:06 +08:00 |
|
weicw-dshsa
|
7216b0ea8c
|
OCR 代理透传真实客户端 IP
后端按 IP 对匿名付费的 OCR 接口限流,而这个 route 原本只带 TenantId,后端 IpUtil
只能拿到 Nuxt 服务器的出口 IP——限流会退化成「整个官网共用一份配额」,正常用户
反而被误限;而 H5 是浏览器直连后端、能拿到真实 IP,同一策略两条链路行为相反。
用仓库里现成的 getRealClientIp(event)(server/utils/ip.ts,form/submit.post.ts
已在用)取真实 IP 并透传 X-Forwarded-For。只加这一个 header,租户解析、query、
返回值解包与错误包装都未改动。
|
2026-09-29 13:56:45 +08:00 |
|
weicw-dshsa
|
80136ac414
|
fix(search): 搜索页一律 noindex,并把配色对齐 template-07
两处收尾,均针对当前启用的 template-07。
1) SEO 收口(ticket 05)
原实现只在带关键词时 noindex,不带关键词时输出 index,follow——等于邀请
搜索引擎收录一个只有「请输入关键词」的空页。改为无条件 noindex,follow:
- 带关键词:同一批内容有无数种关键词组合入口,典型低质量/易重复页面
(沿用 useModuleRoute.ts 对 /article?keywords= 的既有约定)
- 不带关键词:空页,对搜索引擎和用户都是垃圾页
- 保留 follow 而非 nofollow,让爬虫仍能顺着结果链接爬到详情页
无关键词时空页保持显示引导文案,不 404、不重定向——被索引才是问题,
而它已被 noindex 解决。canonical 维持指向 /search;sitemap 经运行时验证
本就不含搜索页(269 条 URL 无命中)。
明确不做:不把 /search 加进 robots.txt 的 Disallow。Disallow 是「禁止抓取」,
爬虫遵守后就不会去读页面里的 noindex,URL 仍可能出现在结果里(只是没有标题
摘要)——反而更糟。故 server/api/robots.txt.ts 未改动。
2) 配色对齐 template-07
搜索页原用 navy #1E2A47,与本模板不符:template-07 主色是 #1a6dff,
其 TenderList 用 text-blue-600 渲染价格。已改为:
- 主色(按钮/聚焦边框/选中 Tab/计数)#1E2A47 -> #1a6dff
- 标书价格 red #E5472E -> #2563eb(对齐 TenderList 的 text-blue-600)
- 链接蓝统一为小写 #2563eb
实测:带/不带关键词两种情况的 robots 均为 noindex,follow;页面总数与三个
Tab 渲染正常;eslint 0 error / 0 warning。
|
2026-09-29 05:18:29 +08:00 |
|
weicw-dshsa
|
5a1a8610e5
|
refactor(search): 搜索结果页补类型并去掉重复的 usePageSeo 调用
代码审查(standards)发现的唯一 should-fix 项:新增的搜索结果页通篇用 any,
而仓库既有 Article / CaseItem / Tender 类型且 sibling 页面一律在用。
- 引入 Article、CaseItem、Tender 类型,新增 SearchResponse / Section<T>
描述 /api/search 的响应形状(Section 用联合类型表达「成功 | 故障」,
让 `'error' in s` 的判别在类型层面成立)
- section() 改为泛型 + 按 key 推导载荷类型,去掉 7 处 any
- 补充注释说明为何用 useFetch 而非 useRequestFetch(匿名只读页无需转
Cookie,与各列表页一致)
同时处理一个 nitpick:search.vue 与 SearchResult.vue 重复调用 usePageSeo,
且页面层那次漏传 siteInfo(后写覆盖先写,重复设置只造成「哪次生效」的歧义)。
按 sibling 惯例只保留组件内那次(它带 siteInfo,且标题能带回关键词)。
行为未变:回归实测「消防」总数 9、23 条详情链接;「测试」标书命中 2 条、
价格 0.01 与截止时间正常渲染、默认 Tab 正确落在标书(第一个非空类)。
eslint 对该文件从 7 个 warning 降到 0。
|
2026-09-29 05:01:44 +08:00 |
|
weicw-dshsa
|
d3cbe1ba37
|
feat(search): 官网新增统一搜索结果页,一次搜到文章/案例/标书
原本头部搜索框硬编码跳 /article,只能搜到文章——案例与标书虽然后端
早已支持 keywords 检索,前端却从未触达,这是「搜不到案例和标书」的根因。
本次新增 /search 统一结果页,三类一次搜全:
- server/api/search.get.ts:新增聚合接口,并发查三个上游并归一化输出
{article, case, tender}。用 Promise.allSettled 做部分降级——某类挂了只
降级该类,返回 {error:true}(不是 {list:[]},否则前端会把接口故障渲染成
「暂无结果」,等于对用户说谎),其余两类照常,整体不 500。
沿用既有代理的 status/deleted 过滤(文章/案例 status:0+deleted:0、
标书 status:1),这些是内容安全边界,防止草稿/下架/软删内容泄露到 C 端。
不改动既有 article/case/tender 三个 list 代理,它们有大量现存消费方。
- app/pages/search.vue + app/components/SearchResult.vue:公共页,一套 UI
服务全部 10 套模板(不逐模板实现——10 套里只有 template-07 有标书 UI)。
Tab 切换(文章→案例→标书),默认停第一个非空类;标书卡片展示价格与
截止时间(购买决策的关键信息);带关键词时 noindex,follow,沿用既有约定。
- app/components/SiteSearchBox.vue:跳转改为 /search。该组件被 10 套模板的
12 处 Header 共用,改这一处即全部生效。/article?keywords= 仍作为
「只搜文章」的域内检索入口保留,只是不再由头部搜索框触达。
实测:关键词「消防」下文章 7 条、案例 2 条正常渲染,计数 7/2/0 与总数 9
均正确;标书用「测试」命中 2 条,价格/截止时间/编号/招标人字段齐全。
部分降级与故障态(计数显示 —、文案与「暂无」区分开)已用桩数据逐一验证。
修复实测中发现的一个缺陷:某类接口故障时整页会误报「没有找到与…相关的
内容」——把接口故障谎报成「确实没有」。原因是整页空态判定 allEmpty 在
「某类为 null(故障)+ 其余为空」时恰好成立,已改为 allEmpty && !hasFailure。
|
2026-09-29 04:56:38 +08:00 |
|
weicw-dshsa
|
d013e64500
|
fix(cms): 其余 9 套模板一并改读 publishTime,消除静默失效隐患
上一提交只改了 template-07(当时 cms_website.template_id = 7),其余模板
仍读已废弃的 projectTime、文章页仍写 publishTime || createTime。
由于 CaseItem 带索引签名,这些引用不报编译错误,只在换模板时静默显示
系统创建时间——而 template_id 是数据库里可随时改的数字,改它不需发版。
本次补全全部模板:
- template-01..10 的 CaseDetail 改读 publishTime,标签更正为「发布时间」
- 其中 8 套原先没有 formatDate,一并补 dayjs 导入与格式化
(此前直出 2026-09-23 19:06:37 完整时间戳)
- 文章侧 38 处 publishTime || createTime 统一为 publishTime
- useModuleRoute 的 SEO datePublished 不再回退 createTime
(结构化数据应与页面展示的发布时间一致)
保留 server/api/sitemap.xml.ts 的 lastmod 回退链——那是抓取提示不是页面
展示,回退到创建时间是合理的保守行为。
现在官网上已不存在读取 createTime 的内容页。ADR 0016 中记录的该技术债
已标记为消除。
|
2026-09-29 03:50:58 +08:00 |
|
weicw-dshsa
|
cfe0749aff
|
feat(cms): 案例/文章列表与详情改读 publishTime
配合后端拆出独立的 publish_time 列(见 ADR 0016)。
- 案例列表/详情、文章列表/详情统一取 publishTime,不再回退 createTime
(createTime 是系统记录时间,运营没设过,展示它等于显示错误值)
- 案例详情页标签由「项目时间」更正为「发布时间」,并补 dayjs 格式化
(原先直出 2026-09-23 19:06:37 完整时间戳)
- server/utils/case.ts 废弃 projectTime,改为输出 publishTime
- CaseItem 类型同步
仅改 template-07:其余 9 套模板的 CaseDetail 仍读已废弃的 projectTime,
因 CaseItem 带索引签名不会报编译错误,只会在换模板时静默显示创建时间。
该技术债已记入 docs/adr/0016 的「后果」一节,换模板前须先补这 9 套。
|
2026-09-29 03:36:04 +08:00 |
|
weicw-dshsa
|
8e9969d516
|
style: 文章/案例详情页 PC 端宽度调整为 1200px
内容区由 max-w-4xl(896px)放宽至 max-w-[1200px],
与列表页保持一致,正文阅读区更充分利用宽屏。
|
2026-09-29 02:50:03 +08:00 |
|
weicw-dshsa
|
09dfded0c8
|
style: 文章/案例列表改为纯文字竖向列表
去掉封面图卡片网格,改为单列分隔线列表:
- 文章行:日期 | 标题 | 栏目
- 案例行:日期 | 标题,下方摘要与客户
顺带清理去掉图片后已无引用的 fileUrl 解构,
并为案例列表补上空状态(此前空数据渲染为空白)。
|
2026-09-29 02:49:56 +08:00 |
|
weicw-dshsa
|
daeb9aed9c
|
style: 分支机构页图片与正文之间补空行
|
2026-09-29 02:29:13 +08:00 |
|
weicw-dshsa
|
13c522ab32
|
fix: 移除页脚平台外链,分支机构页补充办公场地图
汇吉采已独立,官网页脚不应再出现指向 SaaS 平台的「Powered by 云·企业官网」
外链(site.websoft.top)——这是全站唯一会请求外部的地方。
- 10 个模板的 Footer.vue 移除该外链(三种结构变体:带 Powered by 包裹 div 的
01/02/05/07、单行 <a> 的 06、icp/police 行内的 03/04/08/09/10)
- template-07 分支机构页补充办公场地图片
- BranchOffice.vue 与 template-09/Footer.vue 换行符归一为 LF,
消除整文件级的 CRLF 噪声(真实改动分别是 1 行新增、6 行删除)
|
2026-09-29 02:28:43 +08:00 |
|
weicw-dshsa
|
4a5a8f306a
|
fix: NUXT_PUBLIC_APP_ID 改为数字主键,接口基址切正式域名
1. appId 语义修正
NUXT_PUBLIC_APP_ID 之前填的是 productCode('website'),但下游拿它去请求
/api/app/product/detail/{productId},后端按 Integer 解析主键,于是转换失败。
改为 app_product.product_id 数字主键(种子数据为 42);nuxt.config.ts 的
缺省值同步去掉 'website' 回退——留空时下游按空值降级,绝不回退到编码值。
2. 接口基址切 hjc-api.sitelnk.cn
.env.example / .env.production / nuxt.config.ts 的缺省值与 preconnect、
dns-prefetch 一并从 hjc-api.websoft.top 改为正式域名;scripts/ 与
outputs/ 文档里的旧地址同步更新。
注:本提交含若干文件的 CRLF/LF 行尾归一,实际内容改动见 git diff --ignore-cr-at-eol。
|
2026-09-25 05:22:58 +08:00 |
|
weicw-dshsa
|
3d3a377221
|
feat: 页脚优先展示后台配置的页脚 Logo
- CmsSiteInfo 加 websiteFooterLogo 类型
- useSite 新增 siteFooterLogo(websiteFooterLogo 优先,回退
siteLogo);siteLogo/siteFooterLogo 统一过 ensureFullUrl,
兼容本地存储相对路径(/api/file 代理)与完整 OSS URL
- template-01~08/10 共 9 个模板 Footer 的 SiteBrand 改用
siteFooterLogo;template-09 页脚无品牌区保持不变
- 未配置页脚 Logo 时行为与旧版完全一致(回退站点 Logo)
|
2026-09-25 03:59:45 +08:00 |
|
weicw-dshsa
|
2514bd9ea0
|
refactor: 注释去历史化,措辞改为本平台自述
|
2026-09-24 10:33:16 +08:00 |
|
weicw-dshsa
|
1cbc913262
|
refactor: 租户/模板解析收敛到 hjc-java 单一后端,移除 websopy/server 依赖
- appApiBase 指向 hjc-java(hjc.sitelnk.cn 域名→租户解析、模板映射、订阅检查)
- 删除死配置 NUXT_PUBLIC_SERVER_API_BASE(代码中零消费)
- fileServerBase 改从 APP_API_BASE 推导(原从 server.websoft.top 推导)
- preconnect/dns-prefetch 指向 hjc-api 与文件源站
- .env.example/README 同步
验证:本地 node .output 预览,Host=hjc.sitelnk.cn 的 /api/site/info
经 hjc-java 解析成功返回站点信息(code=0)——租户解析链不再依赖任何外部服务。
|
2026-09-24 10:24:16 +08:00 |
|
weicw-dshsa
|
d360998559
|
修改轮播图按钮颜色为蓝色
|
2026-09-24 00:01:43 +08:00 |
|
weicw-dshsa
|
755866e28b
|
revert: PC 支付宝改回电脑网站支付(自提交表单跳转)
配合后端把支付宝默认渠道改回电脑网站支付(当面付需单独签约并提交
资料审核,实测被网关以 ACQ.ACCESS_FORBIDDEN 拒绝)。
改动(tender/pay.vue 收银台 + template-07/BuyDocument.vue 购标流程):
- 恢复 alipayForm 这套处理:后端返回自提交表单时用 document.write
写进新窗口跳转支付宝收银台,原页面留在原标签页继续轮询查单;
弹窗被拦截时给出可行动提示,按钮可重试。
- 模板恢复「表单」与「二维码」两支:支付宝走表单、微信走 codeUrl。
- 切换支付方式时把两种产物都清掉,避免上一支的残留留在页面上。
- 文件头注释同步:微信出码、支付宝跳转。
前端不传 payType 之外的值即可——裸 alipay 现在由后端解析为网页支付,
所以「微信支付 / 支付宝」选择器保持不变。
验证:eslint 0 error;npm run build:dev 通过。
|
2026-09-21 21:49:28 +08:00 |
|
weicw-dshsa
|
1b4dbda28e
|
feat: PC 两处支付入口的支付宝统一改为扫码出码(与微信交互一致)
用户选择:PC 不再跳支付宝账单页,改为像微信一样直接出一张二维码。
此前 PC(收银台 + 购标流程)走电脑网站支付(自提交表单 + 跳转),
H5 走扫码,两个渠道两种交互。
改动:
- tender/pay.vue 与 template-07/BuyDocument.vue 删除自提交表单整套逻辑
(alipayForm 状态、openAlipayForm 的 document.write、弹窗拦截兜底、
模板里的「前往支付宝付款」分支)——两个渠道现在都是 codeUrl 出码,
渲染与轮询完全复用同一套。
- 支付宝提交 payType=alipay(裸值),由后端按默认渠道(当面付扫码)下单。
- 两处文件头注释同步:支付宝默认当面付,与微信 Native 同一交互。
不改的部分:
- 后端本就两条路都实现(precreate / page.pay),本次只翻转默认,
网页支付保留为显式 alipay_page / alipay_web 的可选路径——
扫码签约「当面付」、网页支付签约「电脑网站支付」,是不同的产品签约,
留一条备用便于按实际签约情况切换,不必改代码。
- H5 原本就是扫码(显式 alipay_qr),行为不变。
验证:eslint 0 error;npm run build:dev 通过。
|
2026-09-20 21:16:07 +08:00 |
|
weicw-dshsa
|
5e1106d8ce
|
feat: 购标流程(/buy)支持支付宝支付
上一轮我只改了独立收银台 `/tender/pay`,**漏了购标流程**——
`/buy` 走的是 `templates/template-07/pages/BuyDocument.vue`,
它自己那一套支付步骤同样硬编码微信:「提交订单并用微信支付」、
「请使用微信扫码支付」,且调 `/api/tender/pay` 不传 payType。
结果是用户从标书详情页买标书(主路径)根本看不到支付宝入口。
改动(与收银台保持同一套交互,便于对照):
- 支付步骤加支付方式选择器(微信支付 / 支付宝),默认微信,
保持接入前行为不变。
- 支付宝走电脑网站支付:后端返回自提交表单,`document.write` 进新窗口。
用 document.write 而非 v-html——后者插入的脚本标签不会执行(HTML 规范),
表单永远不会自动提交。原页面留在原标签页继续轮询查单。
- 弹窗被拦截时给出可行动提示,并用「前往支付宝付款」按钮兜底重试。
- 切换支付方式清掉上一张码,避免两张码同时留在页面上。
- 两处 `/api/tender/pay` 调用(submit 与 refreshQr)都带上 payType。
- 文案按渠道取词(channelLabel / qrAlt),状态判定仍走渠道无关的
useHjcPayStatus,不引入支付宝词表。
验证:eslint 0 error;npm run build:dev 通过。
|
2026-09-20 20:44:29 +08:00 |
|
weicw-dshsa
|
eee3be2651
|
docs: ADR 引用改指 0010(0008/0009 已被占用,见 ADR 0010 的编号说明)
|
2026-09-20 19:25:00 +08:00 |
|
weicw-dshsa
|
31f2f07c5c
|
feat: 收银台支持支付宝支付(微信/支付宝选择器)
PC 收银台此前硬编码「请使用微信扫码支付」,只能走微信 Native。
改动:
- 支付方式选择器(微信支付 / 支付宝),切换即重新发起支付并清掉上一张码——
同一订单号换支付类型重复下单会被渠道拒(微信回 OUT_TRADE_NO_USED),
两种支付信息同时留在页面上只会让用户困惑。
- 支付宝走电脑网站支付:后端返回自提交表单,用 document.write 写进新窗口。
刻意不用 v-html——它插入的脚本标签不会执行(HTML 规范如此),
表单永远不会自动提交。原收银台页留在原标签页继续轮询查单。
- 弹窗被拦截时给出可行动提示,并保留「前往支付宝付款」按钮兜底。
- 回到一张曾用支付宝发起过的待支付订单时,默认选中支付宝,
避免又拿微信去撞一次「订单号已使用」。
- useHjcPayStatus 增加 channel 参数,仅供提示文案说对「微信侧/支付宝侧」。
**状态词表不变**——后端已把两个渠道的状态映射成渠道无关的 PaymentStatus,
前端再加一份支付宝词表等于把渠道知识泄漏进 UI。顺带把这层理由写进注释。
- 修正代码注释里对 ADR 0009 的引用:工作区 docs/adr 下并没有这一篇,
相关决策现记录在 ADR 0008。
验证:eslint 0 error;npm run build:dev 构建通过。
|
2026-09-20 19:18:02 +08:00 |
|
weicw-dshsa
|
0d6410c17f
|
fix(hjc-web): 修复首页标题重复为「XX - XX」
index.vue 把 title 传成了 siteName,而 usePageSeo 又会自动拼上
「 - {站点名}」后缀,于是品牌名出现两次:
「广西汇吉采咨询有限公司 - 广西汇吉采咨询有限公司」。
title 改为固定的栏目定位「官网首页」,品牌名统一交给后缀拼接,
渲染为「官网首页 - 广西汇吉采咨询有限公司」,与站内其它页面
(如「关于我们 - 广西汇吉采咨询有限公司」)保持一致。
|
2026-09-19 14:31:50 +08:00 |
|
weicw-dshsa
|
a6b65ae918
|
feat(hjc-web): 为登录/注册/找回密码等 7 个页面补 title 标签
这些页面未调用 usePageSeo,SSR 产物里没有 <title>,浏览器标签页显示 URL。
- login / register / forgot-password / change-password / buy / renewal / preview
统一按 contact.vue 的既有写法:await fetchSiteInfo() 后调 usePageSeo,
标题自动带上站点品牌后缀
- preview 页仅供内部调试,追加 robots: noindex,nofollow 避免被收录
- cases.vue 是 /cases → /case 的纯重定向壳,无需标题,未改动
|
2026-09-19 02:05:10 +08:00 |
|
weicw-dshsa
|
de412297fb
|
开发 / 生产双配置
|
2026-09-19 00:52:04 +08:00 |
|
weicw-dshsa
|
1ff4dfffb9
|
feat(hjc-web): 订单页展示并下载电子发票
发票由一站式平台开具后推给后端(官方网不开票,见工作区根目录 docs/adr/0006),
订单响应里新增 invoices;文件是本平台副本,下载走与附件同一条链路(点击时取票)。
- 抽出 composable useAttachmentDownload:把「先换票据、再取文件」的逻辑从
HjcTenderFiles 里提出来,附件与发票共用(各写一份必然分叉);同时把资源标识解析
扩到 orderNo/projectNo/invoiceId 三种。
- 新增 HjcInvoiceFiles.vue:发票号/类型/开票日期/金额 + 下载;作废(红冲)的也列出来
且仍可下载——它是留档凭证。
- HjcTenderFiles.vue 改用 composable,行为不变。
- 订单详情加发票区块,订单列表加「已开票」标记与发票列表。
- 不判"是否已支付":有没有发票取决于甲方开没开票,与订单当前状态无关。
校验:npm run build 通过。
|
2026-09-18 17:33:01 +08:00 |
|
weicw-dshsa
|
6c40165f86
|
feat(hjc-web): 附件下载改为「点击时取票再下载」
一站式的静态文件服务已加鉴权,附件不再直连(工作区根目录 docs/adr/0007):
后端下发的地址现在是**本平台资源地址**(kind + 订单号/项目编号 + 序号),
既没有文件路径(路径由后端查,防越权)也没有票据。
- 新增 Nitro 透传 server/api/tender/attachment-ticket.get.ts:带 Authorization
(请求头或 hjc_token cookie)+ TenantId 调后端取票,原样透传 ApiResult。
- HjcTenderFiles.vue:`<a :href>` → 按钮 + 点击时取票 + `window.location.href`。
用 location 而不是 window.open:取票是异步的,异步之后弹窗会被浏览器拦截;
附件响应带 Content-Disposition: attachment,下载完仍留在本页。
该组件同时被订单列表/订单详情/项目详情(公告附件)复用,一处改动覆盖三处。
- 错误提示直接复用后端 401/403 约定,组件内联展示,不引入新的 toast 依赖。
校验:npm run build 通过(新增路由已出现在构建产物中)。
|
2026-09-18 17:09:52 +08:00 |
|
gxwebsoft
|
d1cf0db89e
|
chore(env): 切换本地开发CMS接口配置并修复变量解析问题
- 将CMS内容接口地址从线上域名切换到本地 127.0.0.1:9500,支持本地开发
- 新增环境变量覆盖生产时默认模块API接口配置,便于开发调试
- 在.env文件中去除变量前导空格,修复 dotenv 解析失败问题
- 添加文件服务器地址注释,说明本地环境可启用对应配置
- 同步更新进程管理配置文件 ecosystem.config.cjs,修改服务名称及端口号
- 更新本地开发文档,说明改动背景和使用注意事项
|
2026-09-18 10:01:47 +08:00 |
|
weicw-dshsa
|
a322b2eed4
|
feat(hjc-web): 标书详情支持公告正文富文本与公告附件下载
中标公告区域两块改动:
- 公告正文改按富文本渲染。一站式推的是富文本编辑器出的 HTML,原来当纯文本渲染
(whitespace-pre-line),会把 <p>、 、style="…" 原样显示在页面上。
判定(HTML / 纯文本)、净化、纯文本换行抽到 app/utils/richText.ts,
与 hjc-h5 的 src/utils/richText.js 同一套口径。
- 公告附件:渲染后端下发的 bulletinFiles(后端已解析成 {name,url} 并拼好完整
下载地址,含 URL 编码),复用 HjcTenderFiles 组件。公告附件是公开资料
(不判登录 / 资质 / 购买),与标书附件(付费内容、仅已支付订单下发)是两条线,
所以这里不做权限判断。
- types/tender.ts:补 bulletinFiles 字段。
验证:npm run build 通过
|
2026-09-18 08:48:40 +08:00 |
|
weicw-dshsa
|
2e847b5e09
|
feat(hjc-web): 新建订单详情页,订单列表与详情支持下载已支付订单的标书
此前 PC 没有订单详情页,标书下载只有两句文案(`.scratch/hjc-web-order-detail/01`)。
- 新增 `app/pages/tender/orders/[id].vue`:订单状态、标书附件、待支付操作区、
标书/支付/购买人信息;取数走 `useRequestFetch()`(裸 `$fetch` 在 SSR 不转发 Cookie,
会把用户登出)
- `app/pages/tender/orders.vue` → `orders/index.vue`:Nuxt 里同名 file+目录会生成父子路由,
详情页会被父页吞掉,必须让列表页是 `index.vue`
- 列表页每张卡片加「标书附件」(仅已支付)与「查看详情」,不整卡可点(卡内已有按钮与链接)
- 新增 `app/components/HjcTenderFiles.vue` 与代理 `server/api/tender/order-detail.get.ts`
- 附件地址来自后端按 `payStatus=1` 下发的 `tenderFiles`,前端不做权限判断、不自己拼地址
规格与验收:`.scratch/hjc-tender-download/`
|
2026-09-17 18:09:27 +08:00 |
|
weicw-dshsa
|
9299485899
|
feat(hjc-web): 标书详情加「收藏」按钮,「我的收藏」页与顶栏入口
后端接口是端无关的,本轮 **mp-java 零改动**,纯前端 + Nitro 代理。
- 新增 favorites.get/post/delete 三个站内代理,原样透传 ApiResult
(HTTP 恒 200,按 body.code 判登录态与业务失败)。delete 用查询串传 projectId。
- detail.get.ts 补发 Authorization:详情接口内联了 favorited,而它此前是匿名调用,
已收藏的项目会显示成「未收藏」。未登录时不带这个头,行为与改动前完全一致
(返回体仍整体返回 data,favorited 正是靠这一点透传的)。
- 「我的收藏」做成**模板无关的公共路由** app/pages/tender/favorites.vue(10 套模板共用),
顶栏 HjcUserBar 在「我的订单」后加入口。列表按收藏时间倒序 + 加载更多;
只渲染后端算好的 saleState/purchased(前端不再判一遍);失效项目**保留条目**、
点击只提示不进详情、仍可取消;取消收藏弹二次确认(复用 HjcConfirmDialog)。
取数用 useRequestFetch —— 裸 $fetch 在 SSR 不转发 cookie,会被代理当成匿名调用,
拿到 401 后 handleAuthCode 会清凭据跳登录,等于刷新页面把自己登出。
- template-07 详情页加收藏按钮(heart SVG 两态,不引图标库),未登录点它跳登录、
回跳带 favorite=1 后自动补一次收藏(只在客户端 onMounted 做,不改写 URL——
详情壳是 :key="route.fullPath",改 query 会重挂载并与收藏请求赛跑)。
取数同样改用 useRequestFetch,否则首屏 favorited 恒为 false。
- 只改 template-07:10 套模板里只有它有 TenderDetail.vue,其余按需再补。
|
2026-09-17 17:37:10 +08:00 |
|
weicw-dshsa
|
a7399e0624
|
feat(tender): 我的订单加「去支付」「取消订单」入口,并新建收银台
hjc-web 此前**没有收银台**——支付步骤内嵌在购标流程(BuyDocument 的 step='pay')里,
买家一旦离开就再也回不到未完成的支付。本提交补上按订单号付款的独立页面。
- 新建 /tender/pay 收银台:只认订单号,金额取自**订单本身**(by-no)而非支付响应
(支付一失败页面就会停在 0.00);进入先判状态,已支付/已取消/已退款**不发**统一下单,
就地显示结论——既无意义,也会多撞一次跨端 OUT_TRADE_NO_USED
- 订单列表:待支付卡片加两个按钮 + 手搓 Tailwind 二次确认弹窗(照 ConsultDialog 的风格,
不用 antd 的 Modal:买家页无先例,视觉与站点自建风格不一致)
- 状态口径改读 orderStatus(原先只看 payStatus,取消后会把已取消显示成「待支付」
并带上「去支付」),抽 app/utils/orderStatus.ts,与 hjc-h5 刻意保持同一套优先级
- 新增两个 Nitro 代理 order-by-no.get.ts / cancel.post.ts,照既有 my-orders / pay-status
的范式原样透传 ApiResult
- 标书详情「购买人数」改读 buyerCount(后端实时统计的已付款订单数)
- 跨端 OUT_TRADE_NO_USED:识别后端回带的 data.wechatCode 并给可行动提示,
不匹配 message 字符串(包装方式一改就会静默失效)
|
2026-09-17 03:39:59 +08:00 |
|
weicw-dshsa
|
81ef9317c7
|
feat(tender): 忘记密码与修改密码页(10 套模板通用)
密码找回(材料审核制,见 ADR 0008)
- app/pages/forgot-password.vue:两个页签——「提交申请」(企业名称 + 纳税人识别号 + 新密码 + 确认
+ 授权委托书,复用 POST /api/tender/upload,并照 HjcEnterpriseForm 做 5M 校验)与「查询进度」
(双要素查询,展示状态与时间、驳回原因)。提交后自动把条件带到查询页签。文案纪律:
「已通过」≠「已重置」。
修改密码(登录态,双因子)
- app/pages/change-password.vue:旧密码 + 短信验证码(60s 倒计时,照 register.vue)+ 新密码 +
确认;成功后清本机凭据并显示「去登录」面板。
BFF 与封装
- server/api/tender/password/{apply.post,status.get,sms.post,change.put}.ts:四条都照
register.post.ts 的透传范式(modulesApiBase + TenantId(header 与 query 都带)+ 原样返回
ApiResult,HTTP 恒 200)。前两条**匿名**(与 sms/upload 一致,不读 cookie);后两条需登录态,
从 cookie hjc_token 或 Authorization 头取 token 拼 Bearer。
- app/composables/useHjcPassword.ts:四条请求单独成一支,不塞进 useHjcAuth——找回的两条是匿名的、
不做 401 跳转;修改密码的两条经 handleAuthCode 处理登录态。
接线
- app/pages/login.vue:加「忘记密码?」入口。
- app/components/HjcUserBar.vue:已登录菜单加「修改密码」。
落点说明:新页面直接放 app/pages/*.vue——静态段路由优先于 app/pages/[slug].vue 的动态段,故不必
动 useTemplate.ts / templates/index.ts,与 login.vue、register.vue 完全同款做法,10 套模板自动可用。
验证:针对本次文件 npx eslint 0 error;pnpm run build 成功且四条新 BFF 都出现在产物里。
未验:未起 mp-java 做端到端(见 .scratch/hjc-password/issues/06)。
|
2026-09-17 02:35:45 +08:00 |
|
weicw-dshsa
|
5b6e1b67bc
|
feat(tender): 支付链接改为站内二维码,支付确认改走微信侧查单
- BuyDocument:支付步骤原先把后端 Native 下单返回的 codeUrl(weixin://wxpay/...)当明文
链接渲染成一个 <a target="_blank">,而 weixin:// 在浏览器里点击没有任何有效行为——标题写
着「请使用微信扫码支付」,页面上却没有二维码,PC 端 Native 支付实质不可用。改为渲染真正
的二维码,并删掉那个链接。
- HjcPayQrcode(新):uqr 站内生成,renderSVG() → data:image/svg+xml → <img :src>。不用
v-html(避开 vue/no-v-html),不用第三方外链(hjc-h5 用的 api.qrserver.com 在境内不可靠,
且等于把支付凭据交给第三方),也不改后端契约。
- useHjcPayStatus(新):支付结果一律以**微信侧**为准——轮询 pay-status(3s,页面隐藏暂停,
2 小时上限),手动「我已完成支付」按钮也走同一条查单通道。原先只有 mark-paid 一条路,而它
不向微信查单(HjcOrderController 的 javadoc 自陈「订单置为已支付只有 /mark-paid 一条路」),
用户一分钱不付、点一下就能把订单置为已支付并触发一站式推送。故 hjc-web 弃用它,并删除
server/api/tender/mark-paid.put.ts,不留这个入口给下一个人误用。
- 查单的另一好处:微信已支付而本地仍未支付时它会就地补写状态(幂等)。于是「付了钱但页面被
关掉/断网」这类漏单能被认出来——进入支付步骤即开始轮询,正是为了认出这种订单。
- 拿不到二维码时(例如租户支付配置错误)不再显示空白卡片,而是失败原因 +「重新获取二维码」。
微信 Native 码默认 2 小时且服务端不下发 expireTime,故按发起支付时刻本地计时,过期把二维码
置灰并提示重新获取;「重新获取二维码」重调 /api/tender/pay(同 out_trade_no 的 Native→
Native 重下微信允许)。
- 由此 hjc-web 与 hjc-h5/小程序端的支付确认语义**有意不一致**(那两端仍在用 mark-paid,改动
它们等于同时动三端线上支付路径)。理由与边界记在 ADR 0009。
- 依赖:新增 uqr;两份锁文件同步更新(pnpm 装,package-lock.json 同步)。
- 删除 BUY_TENDER_MAP_REPORT.md:530 行历史快照,结论与现状全面矛盾(称购买流程是桩函数、
/buy 不可用、没有登录流程、pay 代理路径写错),已实际误导过一次调研;历史价值留在 git 里。
|
2026-09-17 02:32:39 +08:00 |
|
weicw-dshsa
|
32098b69ac
|
fix(hjc-web): 修复刷新后登录态丢一半,以及顶栏企业名取错字段
- useHjcAuth:登录用户信息补持久化到 hjc_user cookie。原先用 useState,只活在内存与
本次 SSR payload 里,刷新后归 null,顶栏企业名退化成占位的「企业」,登录态看着像丢了
一半;H5 端把用户信息存本地存储,PC 端用同名 cookie 对齐。它**只用于展示**,鉴权一律
以 JWT 为准(后端不读用户信息)。顺带抽出 setCredentials() 统一写入 token + 展示信息。
- HjcUserBar:loggedIn 改 computed —— 原来 ref(isLoggedIn()) 只在挂载那一刻求值一次,
之后别处清凭据(401 处理、另一页签退出)本组件不跟着变;企业名改取 username 而非
nickname —— 核心实例建号时会把 nickname 无条件覆盖成打码手机号,拿它当企业名是错的,
username 才是「企业名称(登录账号)」。
- login:验证码图 object-cover 改 object-contain,避免被裁掉。
- tender/orders:改用 useRequestFetch()。SSR 期间裸 $fetch 不会把浏览器 Cookie 转发给
站内 /api 代理,代理会变成匿名调用并返回 code=401,从而被 401 分支误判为「凭据失效」
——刷新页面等于把用户登出。
|
2026-09-14 19:01:31 +08:00 |
|
weicw-dshsa
|
d0c2dd17cb
|
feat(tender): 登录加图形验证码、注册加短信验证码;改按 body.code 判定 401/403
- 新增 captcha / sms / logout 三个 Nuxt server 代理
- 修复代理把 ApiResult 拍扁成 data 的问题(my-orders、enterprise、order、pay、
mark-paid):登录态失败被前端当成「没有订单 / 未提交资质」,无法区分
- 新增 handleAuthCode 统一处理:401 → 清凭据并跳 /login?redirect=…;
403 → 只提示「没有访问权限」,不清 token、不跳登录页
- 登录页与注册页分别接入图形验证码与短信验证码(含 60s 倒计时)
- 修复回跳开放重定向:redirect 参数安全解码且只接受站内路径
(拒绝 //evil.com、https://… 及反斜杠变体 /\evil.com)
- 下单成功但发起支付失败时停在支付步,避免用户重提交产生重复订单
|
2026-09-10 23:44:19 +08:00 |
|
weicw-dshsa
|
5e7372d0c7
|
feat(tender): 企业注册与 h5 对齐(一站式表单 + 证件上传 + OCR 回填);修复登录/注册代理路由 404
- 新增 app/components/HjcEnterpriseForm.vue:与 h5 EnterpriseForm 行为一致的共享表单,
字段集 / 必填规则 / OCR 回填 / 提示文案逐条对齐
- register.vue:一站式注册,一次性提交企业 + 经办人 + 授权 + 证件材料;
企业联系电话、企业地址选填,其余(含企业邮箱)必填,4 类证件必传
- tender/qualification.vue:改用共享组件,补「经办人身份证号」,
以真实文件上传 + OCR 取代原「证件 URL 文本框」;
审核中(0)/已通过(1) 只读,驳回(2)/未提交(-1) 可编辑重提
- 新增 server/api/tender/upload.post.ts(multipart 原样转发 → /hjc/auth/upload,匿名,
登录前后均可用)与 server/api/tender/ocr/recognize.post.ts(→ /hjc/ocr/recognize)
- 修正 datetime-local(YYYY-MM-DDTHH:mm)与后端 yyyy-MM-dd HH:mm:ss 的格式转换
- fix: server/api/tender/auth/{login,register}.post.ts 实际路由为 /api/tender/auth/*,
而客户端调用 /api/tender/{login,register},导致登录与注册此前均 404;
已按文件注释与同级接口约定移至扁平路径 server/api/tender/{login,register}.post.ts
- register / login / enterprise-save 三个代理改为原样透传 ApiResult{code,message,data},
useHjcAuth 与资质页按 code===0 判定,避免后端校验失败信息被吞掉
|
2026-09-10 13:12:21 +08:00 |
|
weicw-dshsa
|
0f3fa3c050
|
revert(header): 撤回 Header 静态「标书中心」入口与登录/在线咨询重构,入口改由后台 /tender 导航驱动
|
2026-09-09 15:36:15 +08:00 |
|
weicw-dshsa
|
ea1b9c903a
|
feat(header): 在线咨询改右下角悬浮;右侧原位置放登录/注册或我的订单/个人中心入口
|
2026-09-09 15:33:45 +08:00 |
|
weicw-dshsa
|
1bba5eb58d
|
feat(tender): Header 导航加入「标书中心」入口(路径 /tender),解决官网无入口问题
|
2026-09-09 15:26:42 +08:00 |
|
weicw-dshsa
|
802b73b555
|
feat(tender): 阶段3c 我的订单 + 企业资质中心 + 登录态导航
- /tender/orders:我的订单列表(状态/金额/下单时间)
- /tender/qualification:企业资质(信息+证件URL+提交审核+审核状态/驳回原因)
- HjcUserBar:登录/注册或 我的订单/企业资质/退出(列表/详情页已接入)
- 代理:tender/my-orders.get, enterprise.get, enterprise/save.post
|
2026-09-08 22:48:17 +08:00 |
|
weicw-dshsa
|
0fbf122a57
|
feat(tender): 阶段3b 企业登录/注册 + 购买→支付→确认 闭环
- useHjcAuth:token 存 cookie(hjc_token),login/register/isLoggedIn
- 页面 /login /register(企业名称+密码)
- server/api/tender/{auth/login,auth/register,pay,mark-paid} 代理;order 代理从 cookie 读取 hjc_token 透传 Authorization
- BuyDocument:未登录跳登录;下单→pay(codeUrl)→确认 mark-paid→成功
- types 增 HjcUser
|
2026-09-08 22:44:30 +08:00 |
|
weicw-dshsa
|
2828ba6718
|
feat(tender): 汇吉采标书购买 阶段3 - C端标书列表/详情/购买入口
- server/api/tender/{list.get,detail.get,order.post}.ts 代理到 mp-api /api/hjc/bid-project|order
- app/types/tender.ts 前端视图模型
- app/templates/template-07/pages/{TenderList,TenderDetail,BuyDocument}.vue(Tailwind,仿 Product 页)
- app/pages/tender/index.vue + tender/[id].vue + buy.vue 路由,经 useTemplate 加载
- useTemplate.ts 注册 TenderList/TenderDetail/BuyDocument(全部模板安全可选)
- 附 BUY_TENDER_MAP_REPORT.md(hjc-web 结构映射参考)
|
2026-09-08 21:45:34 +08:00 |
|
weicw-dshsa
|
bbcb76485d
|
chore(nuxt): 忽略构建产物目录,记录模块API base 配置
|
2026-09-08 20:09:34 +08:00 |
|
gxwebsoft
|
427160e43d
|
chore(nuxt): 移除自动生成的类型和配置文件
- 删除.nuxt目录下自动生成的app.config相关类型定义和配置模块
- 移除所有自动生成的build、builder-env、imports、layouts、middleware、modules以及nitro相关的类型声明文件
- 清理多余的import类型定义,减少项目冗余文件
- 删除自动导出和声明的组件、插件、工具函数等类型定义,精简工程结构
|
2026-09-08 12:17:45 +08:00 |
|
gxwebsoft
|
2b69686795
|
feat(app): 添加多模板关于我们页面及相关路由和404页面
- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
|
2026-09-08 12:13:44 +08:00 |
|