Compare commits

..
50 Commits
Author SHA1 Message Date
ops fdb9f5109f ci: apk 源统一走 aliyun(规避 dl-cdn 时段性被拦卡 60s) 2026-10-21 01:37:01 +00:00
chenxing 5a080f502d style(一周安排小组件): 选中态上下让出间距、时间列移到信息行最右端、标题改 14px
build / build (push) Successful in 46s
① 选中态不再「挤」:星期数 <span> 加 padding-bottom:3px(数字位置不动,把今日方块与
   圆点整体让下去)+ 圆点 bottom -8→-11px(今日格 -5.5→-8.5px,七格仍同线)
   ⇒ 星期数↔方块 4.1→6.6px、方块↔圆点 1.5→4.5px,七日条 63→66px
   ⚠️ 用 padding-bottom 而非 margin-bottom:后者会与 b 的 margin-top 折叠
   (max(正)+min(负)),今日格 −1px 与其余格 2px 走不同结果 ⇒ 今日数字偏低 1.75px
② 时间列移到信息行最右端:列表 DOM 由 .line[标题+时间] 改为
   content(独占一行) + .meta[.meta-txt + .time];.meta 用 flex space-between、
   .time flex:0 0 auto;无时间不留位。标题可用宽度 232→314px(带时间那条)
③ 标题字号 15→14px(信息行 12.5px 不变)
④ 结构化骨架同步:星期条占位改 24px 外框(21 行盒 + 3 下留白)+ 内层 ::before 画 10px 条;
   ⚠️ 内层定位用父级 padding-top,不用子元素 margin-top(会塌出父级多 5.5px)

harness 真组件复测:四态 367.58/367.59/367.58/367.58(差 0.01px);今日墨迹中心 87 vs
其余 87.25(0.25px);七格圆点中心全 107.5;.time 父级=meta、content 14px/block。
2026-10-16 15:27:26 +08:00
chenxing 04c12e2076 style(一周安排小组件): 箭头加 hover 药丸、今日方块 28px 同基线、加载骨架结构化三态同高、查看概览移卡头直跳
build / build (push) Successful in 44s
① 翻页箭头:定尺寸 24×24 inline-flex 双向居中 + 圆角 4 + 过渡;
   hover 灰底药丸(#eef1f5/#344449),active 加深一档,禁用态不响应
② 今日方块:height 28px + line-height 28px,margin-top 由 5px 改 −1px
   (28px 行盒使数字中心下移 5.5px,−0.75 取整补回,与其余 6 天同基线);
   圆点改锚数字块(b::after bottom:-8px),今日格圆点 bottom:-5.5px 补位,七格圆点同线
③ 加载态:通用 4 行 Skeleton(158px)换成结构化骨架(标题 40 + 七日条 63 + 列表 171
   + 备注区 66.59),与内容逐段同构同高;备注区恒占位(min-height 58.59px,无备注只留白)
   ⇒ 加载/空周/有备注周三态恒等 364.6px,切换零高度跳变(方案 B)
④ 删除「日常详情」标题行;「查看概览」改 a 标签直跳(target=_blank),
   Teleport 进卡头右侧 #wg-hdr-<id> 锚点(与课程表班级切换器同机制),
   样式复刻 .cls-trigger 一族;index.vue 不用改

harness 真组件复测:三态 364.58/364.58/364.59;今日墨迹中心 84 vs 其余 84.25(差 0.25px);
七格圆点中心全 101.5;箭头药丸 24×24 双盒一致;ov-link 落位卡头右区、关闭按钮左侧 6px。
2026-10-16 14:38:25 +08:00
chenxing 84bbf2faf4 style(一周安排小组件): 节假日去红同周末灰、备注「收起」贴末行右端、汉字时间降一档、今日方块数字改 flex 居中
build / build (push) Successful in 43s
- ① 节假日日期不再标红:#e64545 撤除,与周末统一 #98a2b0(.d.rest b, .d.holiday b)
- ② 备注「收起」不再另起一行:.rk-more 由「仅折叠态」改恒绝对定位(right:10px / bottom:8px),
  .rk-txt 恒 padding-right:34px 给按钮让位;移除已无用的 collapsed 类
  实测:按钮落在最后一行区间内、超出正文底边 0px、右端 gap 0px、正文仍 4 行未多占一行
- ③ times 含汉字时降一档:新增 isCjk(/[\u4e00-\u9fa5]/) + .time.is-cjk{font-size:13px}
  依据:同字号下汉字字面高 18px vs 数字 14px(截图像素实测),「全天」与「14:00-15:00」观感拉平
- ④ 今日方块数字居中:.d.is-on b 改 display:flex + align/justify:center + height:22px + line-height:1
  原 1.5 行盒含 descender 空白 ⇒ 数字视觉偏上 1.2px;修后偏 +0.5px(渲染量化噪声底),
  且与其余 6 天墨迹行完全一致(64..85,差 0.00px);水平方向经「圆点反推格中心」校验方块为精确居中,
  残余偏差来自字体字怀(「1」开头的数字墨迹心普遍右偏 0.2~1.0px),故不加固定位移
2026-10-16 10:19:44 +08:00
chenxing 5d7b8526f4 fix(一周安排小组件): 面板关横向滚动(修外框 X 轴滚动条、日期条被裁)+ 色系 #5979ea、列表区固定 3 条、信息行全空落「-」、备注无则不渲染
build / build (push) Successful in 43s
- 色系:#2d8cf0 / #1d4ed8 整族换 #5979ea(hover #4864d8),覆盖今日方块、圆点、查看概览、展开、今日星期
- 列表区:268px(≈5 条) → calc(var(--wk-row) * 3) = 171px(正好 3 条 + 滚动),新增 --wk-row: 57px
- 条目等高 57px;信息行(地点 · 负责人 · 出席对象)恒渲染,三者全空落「-」,不再留白
- 备注:无备注整块不渲染;超 2 行才出「展开」且贴第二行末尾;remarkText 加 trim;换周重置 remarkOverflow
- 「查看概览 ›」→「查看概览」(去掉箭头字符)
- 修 X 轴滚动条根因(views/index.vue):widgetOptions 的 scrollPanel 关掉 scrollingX
  原 scrollingX=true 时 vuescroll 给 .__view 内联 width:fit-content,包含块被最长文本撑到 ≈425px
  ⇒ 面板 scrollWidth 561 > clientWidth 391,外框出 #333 横向条、日期条 7 列被裁成 5 列、长条目省略号失效
  同时 .content { min-width: 0 } 兜底(flex 项默认 min-width:auto 会让 nowrap 文本不收缩)
2026-10-16 09:50:39 +08:00
chenxing 651e7e16f3 style(一周安排小组件): 列表区固定5条高度+滚动/空态等高、字号对齐旧版、备注与数据区分
build / build (push) Successful in 48s
- 列表区 .wk-list-area 固定 268px(旧版实测行距≈54px×5):超出滚动、空态同高,切「休/节假日」卡片高度不再跳(实测三态卡片高 554px 完全一致)
- 日期条圆点改绝对定位+常驻占位(visibility):修「整周无安排时日期条矮 6px」;今日蓝底方块不再把圆点盖成同色
- 字号对齐旧版:标题 14→15、星期 12→14、日期 13→15、日常详情 14→16、查看概览 12→13、列表内容/时间 12.5→15、meta 11.5→12.5、备注 12→13、空态 13→14
- 备注与安排数据区分:上分割线 + #f7f8fa 浅底块 + 6px 圆角
2026-10-15 21:25:31 +08:00
chenxing 8af636641f feat(一周安排小组件): 标题/日期精简 + 日常详情加重 + 外跳「查看概览」+ 备注两行折叠
build / build (push) Successful in 2m44s
- 标题改合成简称「10月12日~10月18日 第N周」,接口全称留 hover(title 属性)
- 日期条只留「日」(10.12→12),今日改蓝底白字方块(原浅蓝底)
- 「日常详情」12px/400/#6e7c87 → 14px/700/#1f2329,同排右侧新增「查看概览」外跳(新窗口)
- 外跳地址由后端下发(props.overviewUrl);缺配置则不渲染入口
- 备注 line-clamp:2 + 溢出才出「展开/收起」,支持含换行的多行文本
- index.vue 透传 overview-url;WidgetEditModal 配置页加「外跳入口」行,超管保存/校管覆盖/清除覆盖三链路带上
2026-10-15 20:26:07 +08:00
chenxing 8305129c73 feat(一周安排小组件): 对接 workplan oapi 单周对象 + 周偏移翻页
build / build (push) Successful in 50s
- 直吃 oapi data 单周对象(title/year/term/week/monday/days[7]/remark/hasData/minWeek/maxWeek)
- 箭头翻页按 minWeek/maxWeek 门控,非本周默认落周一,本周按今日定位
- 空周门控 hasWeek(title 非空)替代 hasData:空周保留标题行+箭头+七日条,不再翻进去出不来
- 修复形参 week 遮蔽 ref 致 loading 永驻骨架(ref 改名 weekData,loading/reportHeight 移入 finally)
- 大图标空态改模板内联 SVG
2026-10-15 16:30:13 +08:00
chenxing 57cb98f49e fix(小组件): 空态仪表盘改用纯矢量图标 —— 原 widget-empty.svg 是内嵌 PNG 的假 SVG,currentColor/color 对其无效;按 alpha 轮廓亚像素反推(9 轮廓/245 顶点,IoU 98.2%)
build / build (push) Successful in 46s
2026-10-14 11:38:25 +08:00
chenxing c7a295521d style(小组件): 「+」添加小组件下拉改为与卡片同族 —— 复用玻璃令牌,浮层底色加深一档,白字/白描边/大投影
build / build (push) Successful in 45s
2026-10-14 10:30:36 +08:00
chenxing 2f4ee76b7b style(小组件): 「+」添加小组件下拉去雾做锐 —— 1px 实描边接管边界、投影收紧减淡
build / build (push) Successful in 43s
- Dropdown 加 transfer-class-name="wg-dd",把皮肤严格限定在这一个下拉上
  (库的 dropdownCls 会把该类挂到面板 .ivu-select-dropdown,不影响全站其他下拉/选择器)
- 面板:border 1px solid rgba(15,23,42,.08) 接管边界;box-shadow 由库默认的
  0 1px 6px rgba(0,0,0,.2) 收紧减淡为 0 2px 8px rgba(15,23,42,.12);radius 4->6;padding 5px 0 -> 4px 0
- 白底、文字色(#515a6e)、item hover(#f3f3f3) 一律不动;卡片玻璃效果不动
- 选择器用 .ivu-select-dropdown.wg-dd(0,2,0)稳压库默认 .ivu-select-dropdown(0,1,0)
2026-10-14 09:49:22 +08:00
chenxing 27ce68a76e style(课表小组件): 下拉选中态改品牌色(#5979ea/#eef2ff);表格限高 352px 只露 7 节、超出滚动、表头 sticky 常驻
build / build (push) Successful in 41s
- .cls-item.on 由 #2d8cf0/#f0f7ff 改为 var(--color-primary, #5979ea) / var(--color-primary-weak, #eef2ff),
  与 WsToastLayer.vue 既有约定一致(CSS 变量 + 回退值);hover 改 #f4f7ff
- 表格外套 .tt-scroll:max-height 352px(表头 44 + 7×44)+ overflow-y auto + 6px 细滚动条
- th 加 position sticky / top 0 / background #fff;因 sticky + border-collapse 会丢 cell border,
  分隔线由 border-bottom 改为 box-shadow inset 0 -1px 0 #e9edf1
2026-10-14 09:08:06 +08:00
chenxing 3a7502f106 style(课表小组件): 表头垂直居中、左右留白 8px、行高 44px、科目 2 行省略号兜底
build / build (push) Successful in 46s
- th 补 vertical-align: middle —— base/_reset.scss(meyerweb) 给 th/td 统一设了 baseline,
  scoped 只给 td 写了 middle 导致表头文字按基线对齐、偏上,视觉上像"贴住卡片 header"
- .table-wrap padding 2px 15px 12px → 8px 8px 10px(小组件窄,收敛左右留白)
- td height 52 → 44px
- 科目包 <span class="sub" :title>,-webkit-line-clamp:2:超长科目最多 2 行、省略号收尾、悬停看全文
2026-10-14 08:44:27 +08:00
chenxing 479f7b22a7 fix(课表小组件): 三项修复——header 显示「年级+班级」、body 去班级行、空态改内联 SVG、表格换私有类名去掉全局竖线
build / build (push) Successful in 3m52s
- header 与下拉项显示 gradeName + className(「高一 1班」)
- body 单元格只显示科目,不再重复班级
- 空态由「CSS 背景图 + 空 div」改为模板内联 SVG + 「暂无课表数据」
- 表格类名 my-table → tt:避开全局 componets/_my_table.scss 带进的 #c7c7c7 竖线与 th #fafafa 灰底
- 表头去灰底并加 1px 分隔线(#e9edf1),行间横线加深 #eef1f4,表头字色 #344449
2026-10-13 21:02:41 +08:00
chenxing 0baba07707 fix(小组件): 内容卡补回不透明白底(#fff)——旧版由iframe自带,内置化后丢失导致整卡糊成一色
build / build (push) Failing after 44s
2026-10-13 16:52:06 +08:00
chenxing 6f4b3f07d4 feat(课表小组件): SyllabusWidget改版直吃AcaSyllabu oapi结构——班级下拉切换器Teleport进卡头(通用header插槽能力),行=slotNo中文数字、列=周一~周五(周末有课才追加)、单元格=班级/科目;空态换原版no-data-box.svg插画;卡头钉死#f7f8f9+overflow visible供浮层溢出
build / build (push) Successful in 1m38s
2026-10-13 12:27:41 +08:00
chenxing a3ddb90a8a fix(小组件): 空态图标按场景分家 + 桌面面板拖拽态翻白
build / build (push) Successful in 42s
- 管理台空态改用新线性图标 widget-empty-line.svg(虚线框+加号,currentColor 可着色)
- 桌面小工具面板空态还原原版 widget-empty.svg(内嵌灰度仪表盘 PNG,4279f99 版)
- _widget.scss 拖拽态翻白:背景/边框/阴影与前景令牌一并反转,避免重演「白底压白字」
2026-10-12 08:47:45 +08:00
chenxing 5a19a4ed79 feat(小组件管理改版): 卡片网格管理台 + 校级覆盖层 + 退役系统设置/应用管理
build / build (push) Successful in 42s
后端
- widget_catalog 加 3 列:scope_type(三态可见范围)/ role_types(可见角色)/ role_alias(角色专属命名 JSON)
- 新增两表:widget_catalog_school(点名表,uk_widget_school)、widget_school_setting(校级覆盖层,uk_widget_sch)
- WidgetController 新增 GetWidgetCatalogList / SaveWidgetCatalog / DeleteWidgetCatalog /
  GetWidgetSchoolSetting / SaveWidgetSchoolSetting;权限拆 checkSuperAdmin(仅超管)与
  checkSchAdmin(超管或 roleId∈{2,5,7})
- SaveWidgetSchoolSetting 强制 schId 取当前登录校,前端传参不采信(防越权)
- 显示名三级链:校级别名 > 角色专属命名 > 组件名;role_alias 坏 JSON 降级不抛
- 启动期幂等 seeding(空库才写 3 条内置目录行)
- 手工 DDL 脚本 resources/sql/widget_catalog_v2.sql(含回滚)

前端
- WidgetManage 重写为卡片网格:超管/校管双视角、类型页签 + 搜索、拖拽排序、启停、
  删除、登记内置组件、空态引导
- 新增 WidgetCard / WidgetEditModal / WidgetRegisterModal
- UserSettingApi 加 6 个方法;types 加 WidgetCatalog 接口
- 管理端列表整行回传(SaveWidgetCatalog 为整行 merge)

退役
- 删除 SysSetting.vue / SysTempManage.vue / AppSettingApi.ts 与后端 AppSettingController /
  AppCategory(SQL) 全链路,清理路由、Settings 导航与样式分支
- 保留 SysSettingApi.ts(壁纸/logo 池管理仍在使用)
2026-10-11 21:40:31 +08:00
chenxing 9980ea1264 外观SDK化A:sync 件跟版 20261011-1332-246e1e3(侧栏默认翻转 sideDeep→false)
build / build (push) Successful in 2m50s
2026-10-11 13:35:12 +08:00
chenxing f5faa29018 feat(小组件内置化): 面板三分支渲染 + 三个内置组件 + 自定义片段 srcdoc + 玻璃层对比度
build / build (push) Successful in 42s
- components/widgets:widgetRegistry(defineAsyncComponent 按需加载)+ EvaluateWidget/SyllabusWidget/WeekplanWidget,props widgetId、emit loaded、内部自行取数、ResizeObserver 自报真实高度;呈现只保留语义不逐像素复刻旧 html
- views/index.vue:iframe 单分支改三分支(内置组件 / compType=2 走 :srcdoc + sandbox="allow-scripts allow-same-origin allow-forms"(不给 allow-top-navigation)/ 兜底「该小工具暂不可用」不白屏);:src="item.url" 与候选池 url 依赖删除;postMessage 身份下发只服务片段分支,高度统一收口 find.height
- utils/widgetFragment.ts:wrapFragment 两段注入——取数桥在 head(早于片段自身脚本,否则 yhWidget undefined)、高度上报在 body 之后;</script> 拆拼防提前闭合门户脚本;节流用 setTimeout 尾沿 + 300/1200ms 兜底(iframe 隐藏期子文档不出动画帧,rAF 会把上报永久吞掉、帧高卡 min-height 撑出内层滚动);桥 URL 走 serviceHost 且自行解平台信封 data
- views/Settings.vue:新增 admin pane「widget」(ADMIN_PANES/ALL_PANES/「系统」组导航项/v-else-if 链分支),普通用户导航隐藏且 URL 直达落 no-perm 黄条
- views/widget/WidgetManage.vue:双卡管理页(内置/自定义分组列表 + 名称/键/类型/data_code/排序/启用/sch_id 表单 + CodeMirror + 上传 .html 走 FileReader 填编辑器,不落地文件不产生 URL;内置条目 content 只读)
- _widget.scss:--wg-* 六令牌 + 深玻璃 blur(18px) saturate(140%) + 描边 + 投影;拖拽态加深 blur(22px) 不再翻白;空态与 +/− 前景改走 token(配套 widget-add/sub/empty.svg 由硬编码色改 currentColor,widget-empty 原为内嵌 PNG 无法着色故换线性版);.widget-item 浅底深字保持不动
- UserSettingApi.ts:getWidgetData / getWidgetContent / GetWidgetCatalogList / SaveWidgetCatalog
- 另含 src/store/index.ts 的 getWidgetAppIds 未配置态 .reverse()(非本会话所写,按用户确认一并提交:与 getWidgetAppList 降序比较器对齐,使未配置态按 widget_catalog.sort 正序渲染)
2026-10-11 08:50:49 +08:00
chenxing be0dac6bfa chore(theme): 版本戳跟版 20261009-1655-488a3c3(YschTheme skin 16px 定稿)
build / build (push) Successful in 44s
2026-10-09 17:08:10 +08:00
chenxing 1b812bc9c9 fix(切换身份联动): 消息角标/消息页/设置中心随身份切换自动重拉——Header 摘要挂 switchRole、msg 页与 Settings pane watch curRoleUid(桌面/应用中心既有机制不变),无需手动刷新
build / build (push) Successful in 41s
2026-10-09 15:33:26 +08:00
chenxing ac67215c78 feat(header): WS 实时推送卡片落地 design/03 .ws-toast——类型色条+图标章+进度条 8s 自动消退+点击进 /msg,替代 Notice.info 临时卡片(审批直批按钮本期不做)
build / build (push) Successful in 1m32s
2026-10-09 15:06:23 +08:00
chenxing 0621ef1ede fix(壁纸): 删除当前生效壁纸后重拉用户设置即时回落兜底(设置 pane 与 Header 模态框两处删除入口) 2026-10-09 14:53:19 +08:00
chenxing 0264d41428 fix(设置): LOGO 池预览改正方形缩略(LOGO文字与主题JSON化增补)
build / build (push) Successful in 47s
2026-10-09 12:29:32 +08:00
chenxing d1a371d257 feat(header): 铃铛新消息按当前身份学校过滤(getCurSchId 口径,平台级/超管放行)——消息按学校隔离 批次4前端 2026-10-09 12:23:17 +08:00
chenxing e7f70f46a8 fix(门户+设置): LOGO 文字贴徽标左对齐并放大字号(修 space-between 居中);壁纸 pane 管理员选本级默认(LOGO文字与主题JSON化增补)
build / build (push) Successful in 44s
2026-10-09 11:54:17 +08:00
chenxing b774d2e733 chore(theme): theme.ts 同步通道 1038 版本戳(LOGO文字与主题JSON化)
build / build (push) Successful in 41s
2026-10-09 10:49:37 +08:00
chenxing 2819f96dfd feat(设置+门户): LOGO 文字配置(校/平台两级,pane 内维护)+ header 徽标旁显示;个人主题保存改 JSON 形态(LOGO文字与主题JSON化)
build / build (push) Successful in 1m27s
2026-10-09 10:35:25 +08:00
chenxing bdc8898b93 chore(theme): YschTheme sync 件更新(版本 20261009-0054-5732ee2,信封兼容)
build / build (push) Successful in 43s
2026-10-09 01:06:15 +08:00
chenxing 49f15b8a05 feat(settings): 设置中心三级重构(一层一角色)+ 审计缺陷修复
build / build (push) Successful in 44s
三级重构(S1-S6,方案见 docs/设置中心三级重构-执行方案-20261008.md):
- Settings.vue 三层化主体:curLayer=my/school/platform 单 pane 分层,主题/头像/壁纸/桌面/LOGO 按身份只渲染本级
- 桌面应用三级默认 pane(used_app SCHOOL/BASE 读写 + 角色分段 + ≤8 上限)+ 统计设置真身迁入(StatsBarModal 退役)
- SysSetting.vue 去基础设置/机构树;ThemePreview 预览壳套 .layout-wrap; UsedAppApi 新增
审计缺陷修复(设置中心三级重构与消息搜索-审计报告-20261008):
- 【P0】DESKTOP_ROLE_TYPES 角色 1/2 标签对齐 SysRoleEnum(1教师/2校领导/3学生),桌面默认不再张冠李戴
- 命令面板:Enter/↑↓ 加 isComposing 守卫防中文输入法误触;过滤后高亮索引归零;stagger 延迟 --i 封顶 20
- WS 通知标题移除 frame.appKey 死消费;BaseApi summary todos 类型同步去 appKey
2026-10-08 23:08:16 +08:00
chenxing 2bd7ef3b80 refactor(header): 命令面板去背景联动,结果右侧标注应用类型
build / build (push) Successful in 1m21s
用户三点修订:
1. 面板已是模态框,去掉背景应用列表的同步过滤(解开 mittBus.searchChange 整条链)
2. 结果右侧灰色小字显示应用类型(来源 BoaAppType.name,与 /apps 分组标题同源)
3. 类型呈现暂按方案 A(右侧灰字);方案 B(类型分组)对照稿见 design/07

- Header.vue: watch(searchAppText) 不再 emit("searchChange");cmdkResult 由
  getFlattenAppList(纯 flatten,会丢类型名)改为遍历 curUserAppList 分组展开并挂
  appTypeName;模板加 .app-cmdk-type
- AppList.vue: 删 searchAppText / searchAppList / isSearch 与模板搜索态分支、
  .no-search-box 样式、孤儿导入 flatten(lodash) 与 requireImg;删 mittBus 监听
- utils/mitt.ts: 删 searchChange 事件类型
- assets/styles/header.scss: 加 .app-cmdk-type 样式
- harness-main.ts: mock curUserAppList 补齐 BoaAppType 分组结构(id + name),
  原 mock 丢了 name 导致类型名取不到

注:本仓工作区另有并行会话 WIP(StatsBarModal 迁入 Settings / 主题预览),
本提交只含本案 5 个文件与 hunks,未触碰对方改动。
2026-10-08 19:10:14 +08:00
chenxing 4f36ff9ceb 外观偏好异步补齐D:设置页选择端双写服务端真源(fire-and-forget,本地体验不变)
- BaseApi 加三方法:getAppearance / saveMyTheme(紧凑编码,null=跟随)/ saveMyAvatarStyle
- Settings.vue 五个写键分支旁挂双写:pickMyTheme / followSchoolTheme(置 NULL) / pickMyAvatarStyle / followSchoolAvatar(置 NULL) / pickSide(写 yh-theme 的全部分支)
- 双写失败 console.warn 不弹错不回滚本地(本地体验与改造前逐字节一致)
- App.vue loadSchThemeDefault/loadSchAvatarDefault 保留不动(与 init 异步补齐幂等收敛)
- sync 件:UserAvatar.vue 监听 yh-appearance-updated + theme.ts 版本戳 20261008-1831-d9db725
- 注:本仓工作区另有并行会话 WIP(harness/命令面板),本提交只含本案文件与 hunks
2026-10-08 18:58:30 +08:00
chenxing b2307f583f chore(harness): 补齐全局脚本引入 + 命令面板取证钩子
build / build (push) Successful in 42s
- harness.html 照抄 index.html:30-34 的 ztree.css / jquery / lodash / jquery.ztree:
  main.ts 不 import 这几个全局脚本,靠 html 提供;缺 jquery 会稳定报
  "Uncaught ReferenceError: $ is not defined"(本项目既有坑)
- harness-main.ts 新增 /apps 空壳路由(只需 route.name === "apps" 让 Header 渲染放大镜,
  不挂真实 AppList 以免本机无后端时报错污染控制台)与 ?cmd=1[&q=xx] 取证钩子
  (自动点开放大镜并可选输入关键词)
2026-10-08 17:45:33 +08:00
chenxing ec696d5187 feat(header): 搜索框改居中命令面板,应用列表数据与 loading 与 AppList 共享
- header.scss: 删旧 .search-box 与 fade1/search-animation/icon-animation 动画段,
  新增 app-cmdk-* 面板样式。样式段必须放顶层——面板 Teleport 到 body,嵌进
  .default-header 会生成后代选择器而匹配不到
- Header.vue: 搜索 li 收敛为单图标 + openSearch;模板末尾追加 <Teleport to="body">
  命令面板,支持实时过滤 / ↑↓ 键盘导航 / Enter 打开 / Esc 关闭 / 空结果态;
  删 watch(isSearching) 与空函数 showSeachBox;挂/卸 window keydown
- store/index.ts: 新增 appListLoading 字段与 setAppListLoading
- utils/bschLinkPage.ts: 抽出 openAppPage(app, ifameAppIdArr),与点击应用图标同一路径
- AppList.vue: reloadAppData 写 store(数据 + loading,try/finally);
  linkPage(item) 委托 openAppPage

硬约束保持不动:watch(searchAppText) -> mittBus.emit("searchChange")(背景应用网格靠它过滤)、
isSearchIconShow(route.name === "apps")。
2026-10-08 17:45:25 +08:00
chenxing f9f97db272 feat(msg): 计数口径改消息总数 + 标识切换 appId
build / build (push) Successful in 43s
- 按分类计数改分类总数(sysTotal/bizTotal/approvalTotal,与列表内容对齐),已读=已读总数、全部=全部总数
- 按应用角标改 countByApp 按应用消息总数(含已读,已读后不清零),总数>0 才显示、总数降序
- 应用匹配/筛选全面改 appId:行与计数出参带 appId、筛选传 appId,appKey 不再出现在消息中心前端
2026-10-08 16:37:22 +08:00
chenxing 3250de382a fix(header): 去掉身份列表上擅自添加的 padding/margin/圆角,完全对齐原样式
build / build (push) Successful in 1m30s
上一轮回滚时虽已恢复灰卡片形态,但额外加了列表 padding 6px、行的 margin 0 8px
与 border-radius 6px,导致与原「切换身份」观感仍有出入。本次全部移除。

移除(非原样式):
- .user-card-roles 的 padding: 6px 0
- .u-role 的 margin: 0 8px 与 border-radius: 6px
- .who 的 min-width/ellipsis 系列

恢复(原样式组成部分):
- .user-card 顶层 svg{20px},等价原 .roleinfo-wrap 首段声明(原圆点尺寸就靠它,
  上一版只写了 margin 导致圆点尺寸失去约束)
- .u-role 用 height: 62px 替代 min-height
- .who 回到 .user-wrap 的 padding: 9px 0 + flex: auto
- .nm 内 .t 间距回到 mr-10

实测 9 条身份 scrollHeight=558(9 × 62px,整数倍⇒ 确认已无任何额外间距),
仍正确出滚动条;1 条时 62=62 不滚动。菜单行数管理员 2 / 普通用户 1 不变。
2026-10-08 16:09:34 +08:00
chenxing 97090eb08b fix(header): 身份列表回滚为原灰卡片样式,只在卡片底部追加三项菜单
build / build (push) Successful in 1m16s
用户反馈整合后的身份选择观感不符预期,要求保留原「切换身份」样式,
仅在列表下方追加个人信息 / 后台管理 / 退出登录。

回滚内容(对齐原 .roleinfo-wrap .roles-ul li):
- 灰底 #f9f9f9 + 圆角 6px + 左右 8px 外边距 + 列表内 6px 上下留白
- 行高62px(原为 padding 9px 16px 的紧凑行)
- hover 用 color.adjust(#f9f9f9, lightness -5%),恢复 @use "sass:color"
- 勾选圆点回到 20px + margin 0 16px
- .who 恢复 border-bottom 1px #e9e9e9,末行不画(同原:last-child .user-wrap)

保留不变:卡片骨架、标题行、滚动条(max-height 310px + 6px 自绘)、
底部菜单与权限判定。实测 scrollHeight 570 > clientHeight 310 仍正确出滚动条。

验证:vite build 通过;mock 取证 9 条身份溢出滚动正常、1 条不滚动、
菜单行数管理员 2 / 普通用户 1。
2026-10-08 15:46:55 +08:00
chenxing e46df62c0b refactor(header): 用户入口整合为单卡片——人像图标承载切换身份+个人信息+后台管理+退出登录
build / build (push) Successful in 45s
铃铛与齿轮两枚图标下线,人像图标成为唯一入口,点击展开一张卡片:
切换身份列表(9条实测溢出滚动)+ 个人信息 + 后台管理(仅管理员)+ 退出登录。

删除无功能损失的冗余入口:原齿轮菜单的 sys/logo/sidebar/statset/backend 五项
已于 2026-09-30 迁入 /settings(Settings.vue:620 ALL_PANES),齿轮成为纯冗余。
消息中心仍走左侧菜单 /msg,LeftMenu 未读角标不受影响。

改动要点:
- isUserInfoShow + isRoleInfoShow 合并为 isUserCardShow,9 处函数体同步改名;
  删除 onUserinfoClickRoles、storeToRefs import 与 unreadCount 解构(模板已无 Badge)
- showUserInfo 改跳 /settings?pane=profile,不再 emit showUserInfoModal
  (该事件仍有 AppHeader/BschIframe/harness-main 三处消费方,不可删)
- :key 用 roleId-schId-childId 复合键,避免同校多身份时 roleId 重复
- header.scss 删 .roleinfo-wrap 与随之失效的 @use "sass:color",新增 .user-card
  (身份列表 max-height:310px + overflow-y:scroll + 6px 自绘滚动条)
- settingsWallpaper 等 6 个入口函数保留:对应 Modal 仍挂模板尾部且 logoList
  是 header 徽标数据源,只改内部变量名并加注释

验证:未声明标识符全量扫 47 个 .vue 零问题;vite build 通过;mock 取证实测
scrollHeight 683 > clientHeight 310 出滚动条、1 条时 75=75 不滚动、
menu-rows 管理员 2/普通用户 1、bell-count 与 gear-count 均为 0。

另:.gitignore 忽略卡片取证三件套(本地临时用,与 harness-* 同类不进 git)。
2026-10-08 15:28:44 +08:00
chenxing 297934f862 feat(msg): 「按应用」清单接真实数据——GetUserApp 应用全集 + 按应用未读数角标
build / build (push) Successful in 1m59s
- 应用清单改与桌面网格同源 GetUserApp(BoaApp 自带 appKey/name):原实现读 store.getFlattenAppList,但 setApps 无调用方、列表恒空,且 MenuBar 本身无 appKey 字段——「按应用」此前只剩「全部」一行
- 角标接新代理端点 msgCenter/unreadCountByApp({appKey: 未读数}),未读多的应用排前,替代原 summary.todos 待办数语义
- 卡片 appName 缺失降级改同源匹配用户应用清单
2026-10-08 12:00:05 +08:00
chenxing 19e1bbc9d7 设置界面更新
build / build (push) Successful in 1m8s
2026-10-08 10:08:22 +08:00
chenxing e2c937f424 feat(avatar): 默认头像轮前端集成——设置页两级样式 + 登录写学校默认键 + 顶栏三态头像
build / build (push) Successful in 5m35s
- BaseApi:schAvatarStyle/saveSchAvatarStyle/clearSchAvatarStyle 三端点(后端 SchSettingsController 配套,本仓 service 仓随轮提交)
- App.vue:登录后 loadSchAvatarDefault()(与 loadSchThemeDefault 同构:失败/404/空→不写键不报错不阻塞),写 localStorage[yh-avatar-sch-default]
- Settings.vue:新增 avatar pane(我的头像样式人人可见 + 本校默认管理员可配,watch 进 pane 拉取)
- AppHeader/UserInfoModal:头像展示位换 UserAvatar 三态组件
- ThemePreview:预览页头像形态联动
运行时联调与部署验证待人工(后端端点须随 service 发版)
2026-10-06 20:20:44 +08:00
chenxing 4d9da5e3a6 feat(appicon): AppIcon 资产库接入(应用网格矢量图标渲染,YschAppIcons 10-04 轮 P3)
- AppIcon.vue:矢量图标渲染组件(iconKey+iconColor → mask data-uri,无键无 URL 回退关键词映射占位)
- constants/appIconRules.ts:应用名关键词→图标键兜底映射(D4,两端各持一份,与 MobilePortal 关键词列一致;仅 icon_key 未配置且无 URL 时生效,有 URL 恒定位图零回归)
- AppList/SearchPanel/index:应用网格与搜索结果图标位换 AppIcon
- appicon.mask.css:资产库 mask 样式;yunhai-logo.svg:站点 Logo 矢量件
- main.scss/_app_container.scss:网格图标容器样式配套
依据:根目录《AppIcon资产库落地-执行报告-20261004.md》P3 UserHome(PC)接入
2026-10-06 20:20:32 +08:00
chenxing 93249cf5f5 chore(sync): YschTheme sync 件刷新(theme.ts 20261006-2013-75c1d10 + avatar 两件首次入库)+ view-ui-plus ^1.3.24 对齐
theme.ts 仅版本戳行变更(20260930-1248 → 20261006-2013);avatar.ts/UserAvatar.vue 为 YschTheme 默认头像轮 sync 下发公共源;package.json view-ui-plus ^1.3.19 → ^1.3.24 对齐通道生成基线(YschTheme iview-version 版本锁基准)
2026-10-06 20:20:30 +08:00
chenxing 1d34e5745d feat(settings): 个人信息手机号/邮箱开放自助修改——保存按钮启用走 /api/user/UpdateContact(前端校验与后端同口径:手机号 1[3-9] 段位/邮箱格式/长度),成功以接口返回的最新 BoaUser 合并 store.userInfo 即时回显(规避 CAS principal 缓存旧值);BaseApi 新增 updateContact(任务B·前端) 2026-10-02 08:56:46 +08:00
chenxing f52ce4136e feat(settings): 我的壁纸 pane(mywallpaper,主题分组,所有人可见)——能力复制自 Header 设置壁纸模态框(模态框保留不动):系统/校区/我的上传三组网格点选即保存(checkWallpaper)、当前值回显 store 用户设置、上传走 /api/wallpaperUpload、个人壁纸可删;零新接口(任务A) 2026-10-02 08:45:47 +08:00
chenxing 7e239a0c73 style(settings): 边栏设置 pane 列宽与样式微调——未设宽列补 width/minWidth(名称120/图标70/地址220/打开方式100),地址列 tooltip 超长省略,操作列固定右侧,工具栏加分隔线收紧间距;Header「边栏设置」菜单改跳 /settings?pane=sidebar 并移除 test 残留按钮与旧 MenuBarModal 挂载(组件文件保留)(任务D) 2026-10-02 08:44:06 +08:00
chenxing 41f4dade91 fix(settings): 个人信息「所属部门」显示组路径——BoaUser.dept 是对象直显成 [object Object],改为取 groups 链学校组(type=2)→挂载组区段反向 join('/')(如「云海小学/校长室」),无学校组回退挂载组名、链空回退 dept.name、兜底 '-'(任务C) 2026-10-02 08:42:16 +08:00
chenxing 9bf2d3dbb1 feat(settings): 边栏设置 pane 对接真实管理(自 Header MenuBarModal 迁入)
build / build (push) Successful in 2m43s
- sidebar pane 静态示意(drag-list 占位)替换为真实管理:getMenuBarSchList 列表 + 新建/编辑/删除/toggleMenuBarShow 显示开关,列结构与图一 MenuBarModal 完全一致(名称/图标/角色/地址/打开方式/系统页面/是否显示/排序号/操作,isEdit 控制操作权限)
- 新建/编辑表单照抄:roleIds 多选(全部/半选态)、名称/网址、图标 iconUpload 直传(.svg + 网关头,可移除重传)、排序号、悬浮底部/系统页面开关、非系统页面时打开方式 Radio(排除 Modal)、IFrame 时显示头部开关;删除走 MyConfirm 二次确认
- 编辑弹窗为页面级 iview Modal(transfer);保存/删除/开关语义与 Header 弹窗一致(Header 入口未删,两处同数据同接口)
- 打开 pane 懒加载列表;静态 sidebarItems/drag-list 样式删除
2026-09-30 14:28:49 +08:00
chenxing 449696af04 ci: 重触发构建与自动发布——302aec5 建档后线上 /userhome/front/ 持续空响应(index.html 0B),projman auto 发布疑似下载/persist 中断,重跑完整链路重试
build / build (push) Successful in 2m56s
2026-09-30 13:36:20 +08:00
234 changed files with 18883 additions and 2363 deletions
+4 -1
View File
@@ -19,7 +19,10 @@ jobs:
options: --network infra-infra-net
steps:
- name: 安装 git / curl / zip(alpine)
run: apk add --no-cache git curl zip
run: |
# 统一走 aliyun 源:dl-cdn 时段性被拦会卡满 60s×2(2026-10-20 事故)
sed -i 's#dl-cdn.alpinelinux.org#mirrors.aliyun.com#g' /etc/apk/repositories
apk add --no-cache git curl zip
# 内网 Gitea 无法访问 GitHub 拉 actions/checkout,手动 clone 本仓库
- name: 拉取源码(内网无 GitHub,手动 clone 本仓库)
+14
View File
@@ -12,6 +12,20 @@ dist
dist-ssr
*.local
# 视觉取证 harness(本地临时用,不进 git;与 harness-* 同类)
.vite-card-harness
dist_card_harness
card-harness.html
card-harness.vite.config.ts
src/card-harness-main.ts
# 小组件内置化取证 harness(同一类,本地临时)
dist_widget_harness
widget-harness.html
widget-harness.vite.config.ts
src/widget-harness-main.ts
.tmp-build
yarn.lock
.npmrc
# Editor directories and files
+53
View File
@@ -0,0 +1,53 @@
/* 一次性校验脚本(默认头像轮 2026-09-30):parse + compileScript + compileTemplate + compileStyle(preprocessLang) */
const { parse, compileScript, compileTemplate, compileStyle } = require("@vue/compiler-sfc");
const fs = require("fs");
const files = [
"D:/SoftProject/yunhai/YschTheme/assets-src/pc/UserAvatar.vue",
"D:/SoftProject/yunhai/UserHome/front/src/components/UserAvatar.vue",
"D:/SoftProject/yunhai/UserHome/front/src/views/Settings.vue",
"D:/SoftProject/yunhai/UserHome/front/src/views/ThemePreview.vue",
"D:/SoftProject/yunhai/UserHome/front/src/components/AppHeader.vue",
"D:/SoftProject/yunhai/UserHome/front/src/components/UserInfoModal.vue",
"D:/SoftProject/yunhai/UserHome/front/src/App.vue",
"D:/SoftProject/yunhai/UserBase/front/src/components/UserAvatar.vue",
"D:/SoftProject/yunhai/UserBase/front/src/components/layout.vue",
"D:/SoftProject/yunhai/Notice/front/src/components/UserAvatar.vue",
"D:/SoftProject/yunhai/Notice/front/src/components/layout.vue",
];
let bad = 0;
for (const f of files) {
const src = fs.readFileSync(f, "utf8");
const { descriptor, errors } = parse(src, { filename: f });
const fail = msg => {
bad++;
console.log("FAIL", f, "::", msg);
};
if (errors && errors.length) {
fail("parse: " + errors.map(e => e.message || String(e)).join(" | "));
continue;
}
try {
compileScript(descriptor, { id: "check" });
} catch (e) {
fail("script: " + e.message);
continue;
}
if (descriptor.template) {
const t = compileTemplate({ source: descriptor.template.content, filename: f, id: "check" });
if (t.errors && t.errors.length) {
fail("template: " + t.errors.map(e => e.message || String(e)).join(" | "));
continue;
}
}
for (const s of descriptor.styles) {
const r = compileStyle({ source: s.content, filename: f, id: "check", scoped: !!s.scoped, preprocessLang: s.lang });
if (r.errors && r.errors.length) {
fail(`style(lang=${s.lang}): ` + r.errors.map(e => e.message || String(e)).join(" | "));
}
}
if (!bad) console.log("OK ", f);
}
console.log(bad ? `\n${bad} 处失败` : "\n全部通过");
process.exit(bad ? 1 : 0);
@@ -0,0 +1 @@
.app-container{width:92px;height:100px;border-radius:2px;margin:10px 15px;cursor:pointer;display:flex;flex-direction:column;text-align:center;justify-content:center;align-items:center;-webkit-user-select:none;user-select:none;transition:background-color .2s ease-in-out}.app-container:hover,.app-container__focus{background-color:#ffffff4d}.app-container a{display:inline-block;width:90%;height:85%}.app-container img{width:60px;height:60px;object-fit:cover;border-radius:18%;display:inline-block}.app-container .app-name{margin-top:2px;color:#fff;font-weight:500;max-width:99%;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.app-container__mask{margin-right:40px;margin-bottom:20px}.app-container__mask .app-name{color:#344449}.app-container__mask:hover,.app-container__mask+.app-container__focus{background-color:#ffffff80}
@@ -0,0 +1 @@
.header-container{background:transparent;transition:all .3s;box-shadow:0 10px 20px #cbcbcb17;height:var(--appHeaderH);background-color:#577afb;width:100%}.header-container .icon-box{margin:0 24px;cursor:pointer;background-repeat:no-repeat;background-position:30px center;background-size:14px}.header-container .icon-btn{background:transparent;height:24px;width:24px;line-height:24px;box-sizing:border-box;border-radius:2px;transition:all .5s}.header-container .icon-btn i{color:#fff;font-size:22px;font-weight:100}.header-container .icon-btn.active{transform:rotate(90deg)}.header-container .delimiter{width:2px;border-left:1px solid rgba(255,255,255,.5);height:20px}.header-container h4{font-size:19px;color:#fff;margin-left:12px;font-weight:700;font-family:SimSun}.header-container .school-bg{position:absolute;top:0;height:100%;width:100%;left:0;right:0;z-index:-1}.header-container .header-aside{max-width:260px;height:var(--appHeaderH)}.header-container .header-aside img{float:left;width:28px;height:28px;border-radius:50%;cursor:pointer}.header-container .header-aside .name{max-width:90px;color:#fff;margin:0 32px 0 14px}.header-container .header-aside a{outline:none}.header-container .header-aside a:hover{opacity:.8}.header-container .header-aside .logout{padding:5px;margin:0 25px}.header-container .header-aside .logout i{color:#fff;font-size:18px}
+1
View File
@@ -0,0 +1 @@
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body,#app{height:100%;width:100%;overflow:hidden}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}a{text-decoration:none}
@@ -0,0 +1 @@
@charset "UTF-8";[bsch-title]{position:relative}[bsch-title]:hover:after{opacity:1;transition:all .1s ease .5s;visibility:visible}[bsch-title]:after{content:attr(bsch-title);position:absolute;padding:5px 10px;bottom:-30px;left:100%;border-radius:4px;color:#fff;background-color:#504f4fcc;box-shadow:0 0 4px #00000029;font-size:14px;white-space:nowrap;visibility:hidden;opacity:0;z-index:2}
@@ -0,0 +1 @@
.my-table{width:100%;border-bottom:1px solid #c7c7c7;border-right:1px solid #c7c7c7;border-collapse:separate}.my-table .td-title{background:#fafafa;vertical-align:middle;color:#111;font-weight:550}.my-table th{background:#fafafa;height:20px;line-height:20px;padding:12px}.my-table td{height:20px;line-height:20px;padding:12px}.my-table th,.my-table td{border-top:1px solid #c7c7c7;border-left:1px solid #c7c7c7;margin-left:-1px;margin-top:-1px;text-align:center}
+1
View File
@@ -0,0 +1 @@
div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:"";content:none}table{border-collapse:collapse;border-spacing:0}
@@ -0,0 +1 @@
table.small-table{border:1px solid #ebeef5;border-radius:5px}table.small-table th{background-color:#fafafa;border-bottom:1px solid #ebeef5;padding:10px 20px}table.small-table td{padding:5px 20px}table.small-table tr:first-child td{padding-top:10px}table.small-table tr:last-child td{padding-bottom:10px}table.small-table .input-box{width:100px;vertical-align:text-bottom;display:inline-block}table.small-table .ivu-input-wrapper{vertical-align:text-bottom}
@@ -0,0 +1 @@
.stats-container{background:#fff;height:calc(100% - var(--appHeaderH));padding:16px 24px}.widget-ul{display:flex;flex-wrap:wrap;gap:12px;height:60px}.widget-ul li{width:140px;height:60px;padding:6px 16px;border-radius:4px;border:1px solid #ebeef5;background:#f6f8f9}.widget-ul .title{font-size:12px;font-style:normal;font-weight:400;line-height:24px;color:#333}.widget-ul .target{font-size:16px;font-style:normal;font-weight:700;line-height:24px;color:#333}.search-wrap{background:#f7f7f7;padding:10px 12px;height:52px}.search-wrap_sel{width:180px!important;float:left}
+1
View File
@@ -0,0 +1 @@
.status-color-1{color:#969799}.status-color-2{color:#e6a23c}.status-color-3{color:#45b972}.status-color-4{color:#eb0404}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
@charset "UTF-8";
+1
View File
@@ -0,0 +1 @@
.widget-wrap{width:380px;min-height:200px;z-index:100;border-radius:5px;background:#00000059}.widget-wrap .widget-header{display:flex;height:48px}.widget-wrap .widget-header .widget-header-drag{flex:2 auto;cursor:move}.widget-wrap .widget-header .operate-btn{padding:12px;height:38px}.widget-wrap .widget-header .operate-btn svg{cursor:pointer;width:24px;flex-shrink:1}.widget-wrap .widget-header .operate-btn:nth-child(2){padding-left:0}.widget-wrap .widget-body{padding:0 4px 18px;height:calc(100% - 48px)}.widget-wrap .widget-body .widget-item{border-radius:6px;background:#fffffff2;overflow:hidden;margin:18px 14px 0}.widget-wrap .widget-body .widget-item:first-child{margin-top:0}.widget-wrap .widget-body .widget-app-header{height:46px;display:flex;padding:0 16px;justify-content:space-between;align-items:center;border-bottom:1px solid #e9e9e9;color:#344449;font-weight:700;font-size:16px}.widget-wrap .widget-body .widget-app-header svg{cursor:pointer}.widget-wrap .widget-body iframe{width:100%;display:block;min-height:150px}.widget-wrap__drag{background:#fff9}.widget-wrap__drag .widget-header{background:#ffffff80}.widget-empty-box{height:calc(100% - 30px);display:flex;align-items:center;justify-content:center;flex-direction:column;color:#828c96}.widget-empty-box h4{font-weight:500;margin-top:20px}
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 1024 1024" width="1em" height="1em"><path d="M740.238222 573.781333a29.013333 29.013333 0 0 1-38.968889 12.743111A395.036444 395.036444 0 0 0 519.964444 543.288889c-222.776889 0-404.252444 181.475556-404.252444 404.252444a29.013333 29.013333 0 0 1-28.842667 28.899556 29.013333 29.013333 0 0 1-28.899555-28.899556c0-209.123556 139.832889-385.991111 330.638222-442.766222a245.191111 245.191111 0 0 1-114.062222-206.904889A245.873778 245.873778 0 0 1 519.964444 52.337778a245.873778 245.873778 0 0 1 245.475556 245.475555c0 87.04-45.511111 163.384889-113.777778 206.904889a444.871111 444.871111 0 0 1 75.776 30.321778c14.222222 7.224889 19.911111 24.576 12.743111 38.741333z m-407.893333-275.968c0 103.424 84.195556 187.676444 187.733333 187.676445 103.424 0 187.676444-84.195556 187.676445-187.733334 0-103.424-84.195556-187.676444-187.733334-187.676444-103.424 0-187.676444 84.195556-187.676444 187.733333z m601.884444 465.863111c23.324444 12.117333 38.172444 36.181333 38.456889 62.577778a71.111111 71.111111 0 0 1-40.220444 63.488 38.343111 38.343111 0 0 0-17.294222 17.066667c-2.389333 4.551111-5.063111 8.931556-7.68 13.255111a42.325333 42.325333 0 0 0-6.542223 24.576c1.251556 26.453333-12.231111 50.972444-35.100444 64.227556-22.869333 13.255111-50.801778 12.515556-73.159111-1.706667a43.747556 43.747556 0 0 0-24.576-6.485333 159.288889 159.288889 0 0 1-15.132445 0 39.651556 39.651556 0 0 0-23.608889 6.485333 70.428444 70.428444 0 0 1-39.936 12.288 70.257778 70.257778 0 0 1-70.257777-74.126222 50.403556 50.403556 0 0 0-5.063111-23.552c-1.422222-2.446222-3.128889-4.835556-4.551112-7.452445-1.422222-2.446222-2.673778-5.12-4.096-7.736889a53.76 53.76 0 0 0-17.806222-16.099555 70.428444 70.428444 0 0 1-38.513778-62.805334 71.111111 71.111111 0 0 1 40.220445-63.544888 39.594667 39.594667 0 0 0 17.294222-17.066667c2.161778-4.323556 4.551111-8.704 7.224889-12.743111a41.642667 41.642667 0 0 0 6.485333-25.031111 70.428444 70.428444 0 0 1 108.999111-62.805334 39.253333 39.253333 0 0 0 24.803556 6.940445c4.835556-0.227556 9.898667-0.227556 14.677333 0a39.253333 39.253333 0 0 0 23.608889-6.485334c22.357333-15.132444 51.768889-16.384 75.093334-2.844444 22.926222 13.198222 36.522667 38.229333 35.100444 64.682667a50.403556 50.403556 0 0 0 5.063111 23.608889c1.422222 2.389333 3.128889 4.778667 4.551111 7.395555 1.479111 2.446222 2.673778 5.12 4.096 7.736889 2.161778 4.096 10.808889 12.515556 17.806222 16.156444z m-22.698666 83.000889a24.632889 24.632889 0 0 0 13.482666-20.195555 22.186667 22.186667 0 0 0-12.231111-19.968c-13.027556-6.542222-30.606222-20.935111-38.741333-37.091556-0.739556-1.934222-1.934222-3.584-2.901333-5.518222-1.194667-1.934222-2.161778-3.868444-3.413334-5.518222-9.841778-14.961778-13.425778-37.546667-12.743111-51.996445a22.186667 22.186667 0 0 0-11.036444-20.707555 22.869333 22.869333 0 0 0-24.064 0.967111 86.471111 86.471111 0 0 1-52.679111 14.904889c-3.640889 0-6.997333-0.227556-10.638223 0a90.851556 90.851556 0 0 1-53.134222-14.677334 22.186667 22.186667 0 1 0-34.702222 19.740445c0.967111 19.000889-3.811556 37.546667-13.937778 53.475555-1.934222 2.844444-3.584 5.973333-5.290667 9.102223a87.381333 87.381333 0 0 1-39.253333 38.229333 22.755556 22.755556 0 0 0-12.970667 20.252444 22.186667 22.186667 0 0 0 12.288 19.911112c12.970667 6.542222 30.549333 20.992 38.741334 37.091555 0.739556 1.934222 1.934222 3.640889 2.844444 5.575111 1.251556 1.877333 2.218667 3.811556 3.413334 5.518222 9.841778 14.904889 13.482667 37.546667 12.743111 51.939556a22.186667 22.186667 0 0 0 34.872889 19.740444c15.416889-10.581333 33.450667-15.872 52.736-14.904888 3.584 0.227556 7.395556 0.227556 11.036444 0 18.545778-0.739556 36.864 4.096 52.508444 14.222222 6.997333 4.551111 15.985778 4.835556 23.324445 0.682666a22.072889 22.072889 0 0 0 11.036444-20.48 88.007111 88.007111 0 0 1 13.994667-52.394666c1.934222-3.128889 3.811556-6.542222 5.518222-9.671111 8.931556-16.839111 22.357333-30.037333 39.253334-38.229334z m-188.871111-85.447111a76.231111 76.231111 0 0 1 103.936 27.932445c10.126222 17.578667 12.8 38.001778 7.452444 57.457777a75.491556 75.491556 0 0 1-73.102222 56.149334 75.889778 75.889778 0 0 1-38.286222-141.539556z m64.512 72.704a26.112 26.112 0 0 0-2.901334-20.707555 27.875556 27.875556 0 0 0-37.774222-10.353778 26.965333 26.965333 0 0 0-13.027556 16.839111 29.013333 29.013333 0 0 0 2.901334 20.935111 27.534222 27.534222 0 0 0 37.774222 10.126222 26.965333 26.965333 0 0 0 13.027556-16.839111z"></path></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

+1
View File
@@ -0,0 +1 @@
*::-webkit-scrollbar{width:10px;height:10px}*::-webkit-scrollbar-thumb{background-color:#0000000d;border-radius:10px;-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.1)}*:hover::-webkit-scrollbar-thumb{background-color:#0003;border-radius:10px;-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.1)}*::-webkit-scrollbar-thumb:hover{background-color:#0000004d;-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.1)}*::-webkit-scrollbar-track{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0);background-color:#fff}*::-webkit-scrollbar-track:hover{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.4);background-color:#00000003}.scroll2::-webkit-scrollbar{width:10px;height:10px}.scroll2::-webkit-scrollbar-track{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0);background-color:#fff}.scroll2::-webkit-scrollbar-thumb{background-color:#0000000d;border-radius:10px;-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.1)}.scroll2:hover::-webkit-scrollbar-thumb{background-color:#0003;border-radius:10px;-webkit-box-shadow:inset 1px 1px 0 rgba(0,0,0,.1)}.scroll2::-webkit-scrollbar-track:hover{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.4)}.scroll2::-webkit-scrollbar-thumb:hover{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.4)}
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.
@@ -0,0 +1 @@
.lightapp-wrap{height:calc(100% - var(--headerH));overflow:hidden}.lightapp-wrap .left-box{width:180px;float:left;height:100%;border-right:1px solid #ccc}.lightapp-wrap .left-box h3{font-weight:400;margin:0;padding:10px 0 10px 20px;font-size:28px;height:50px;line-height:50px;letter-spacing:2px;box-sizing:content-box}.lightapp-wrap .left-box .group-ul{width:100%}.lightapp-wrap .left-box .group-ul li{padding-left:30px;text-align:left;height:38px;line-height:38px;border-radius:5px;margin:0 10px;transition:all .3s ease-in-out;cursor:pointer;-webkit-user-select:none;user-select:none}.lightapp-wrap .left-box .group-ul li:hover{background-color:#f1f6ff}.lightapp-wrap .left-box .group-ul li.active{background-color:#f9f9f9}.lightapp-wrap .left-box .group-ul li.active{padding-left:40px}.lightapp-wrap .right-box{margin-left:180px;padding:0 20px;height:100%}.lightapp-wrap .right-box h4.title{font-size:20px;height:50px;font-weight:400;border-bottom:1px solid #ccc;display:flex;justify-content:space-between;align-items:center}.lightapp-wrap .right-box .app-main-box{height:calc(100% - 50px);padding:20px 0}.lightapp-wrap .right-box ul.app-ul li{cursor:pointer;text-align:center;float:left;margin:0 20px 20px 0;width:140px;height:200px;background:#fff;border:1px solid #ddd;position:relative;transition:.16s all;border-radius:4px;box-shadow:0 1px 2px #0000001a}.lightapp-wrap .right-box ul.app-ul li:hover{box-shadow:0 10px 50px #0000001a,0 20px 30px #0000000d}.lightapp-wrap .right-box ul.app-ul li .app-box{width:90%;margin:15px auto 0;display:flex;flex-direction:column;align-items:center;font-size:13px}.lightapp-wrap .right-box ul.app-ul li .app-box img{width:60px;height:60px;object-fit:cover;border-radius:18%;display:inline-block}.lightapp-wrap .right-box ul.app-ul li .app-box .app-name,.lightapp-wrap .right-box ul.app-ul li .app-box .app-desc{margin-top:8px;line-height:16px;height:32px;display:flex;align-items:center}.lightapp-wrap .right-box ul.app-ul li .app-box .app-desc{margin:5px 0 8px;color:#aaa}.lightapp-wrap .right-box ul.app-ul li .operate-box{position:absolute;right:0;top:0;width:30px;height:30px;display:flex;align-items:center;justify-content:center;border-radius:3px}.lightapp-wrap .right-box ul.app-ul li .operate-box:hover{background-color:#f2f2f2}
Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg">
<path d="M6.51133 11.9177C5.79328 11.9177 5.09135 11.7047 4.49432 11.3058C3.89729 10.9069 3.43196 10.3399 3.15719 9.67646C2.88241 9.01306 2.81053 8.28308 2.95064 7.57883C3.09075 6.87458 3.43655 6.22769 3.9443 5.71998C4.45206 5.21226 5.09898 4.86651 5.80324 4.72646C6.5075 4.58641 7.23748 4.65835 7.90085 4.93318C8.56423 5.208 9.13121 5.67338 9.5301 6.27044C9.92898 6.86751 10.1419 7.56945 10.1418 8.2875C10.1411 9.25012 9.75837 10.1731 9.07767 10.8538C8.39697 11.5344 7.47395 11.9171 6.51133 11.9177ZM6.51133 6.53203C6.16413 6.53203 5.82473 6.63499 5.53604 6.82788C5.24736 7.02078 5.02236 7.29494 4.88949 7.61571C4.75662 7.93648 4.72186 8.28945 4.78959 8.62998C4.85733 8.9705 5.02452 9.2833 5.27003 9.52881C5.51553 9.77431 5.82833 9.9415 6.16885 10.0092C6.50938 10.077 6.86235 10.0422 7.18312 9.90934C7.50389 9.77648 7.77806 9.55147 7.97095 9.26279C8.16384 8.9741 8.2668 8.6347 8.2668 8.2875C8.26587 7.82232 8.08058 7.37647 7.75154 7.04764C7.42249 6.71881 6.97652 6.53382 6.51133 6.53321V6.53203ZM23.5659 11.9177C22.8479 11.9177 22.1459 11.7049 21.5488 11.306C20.9518 10.9071 20.4864 10.3401 20.2116 9.67666C19.9367 9.01327 19.8648 8.28328 20.0049 7.57901C20.145 6.87474 20.4907 6.22783 20.9985 5.72008C21.5062 5.21233 22.1532 4.86656 22.8574 4.72648C23.5617 4.58641 24.2917 4.65833 24.9551 4.93315C25.6185 5.20797 26.1855 5.67334 26.5844 6.27041C26.9833 6.86748 27.1962 7.56944 27.1961 8.2875C27.1949 9.24993 26.8121 10.1726 26.1316 10.8531C25.451 11.5337 24.5283 11.9165 23.5659 11.9177ZM23.5659 6.53203C23.2187 6.53198 22.8793 6.63488 22.5906 6.82774C22.3018 7.0206 22.0768 7.29475 21.9439 7.61551C21.811 7.93628 21.7761 8.28925 21.8439 8.6298C21.9116 8.97034 22.0787 9.28317 22.3242 9.5287C22.5697 9.77424 22.8825 9.94146 23.223 10.0092C23.5636 10.077 23.9166 10.0422 24.2373 9.90937C24.5581 9.77651 24.8323 9.55151 25.0252 9.26282C25.2181 8.97413 25.3211 8.63471 25.3211 8.2875C25.3202 7.82237 25.1349 7.37656 24.8059 7.04774C24.477 6.71892 24.0311 6.5339 23.5659 6.53321V6.53203ZM6.55615 25.3638C5.83811 25.3638 5.1362 25.1508 4.53917 24.7519C3.94215 24.353 3.47682 23.786 3.20204 23.1226C2.92726 22.4592 2.85536 21.7293 2.99544 21.025C3.13553 20.3208 3.48129 19.6739 3.98902 19.1662C4.49676 18.6584 5.14364 18.3127 5.84788 18.1726C6.55213 18.0325 7.28209 18.1044 7.94547 18.3792C8.60886 18.654 9.17586 19.1193 9.57478 19.7163C9.9737 20.3134 10.1866 21.0153 10.1866 21.7333C10.1855 22.6958 9.80269 23.6186 9.12208 24.2992C8.44147 24.9798 7.51868 25.3627 6.55615 25.3638ZM6.55615 19.9781C6.20894 19.9781 5.86953 20.0811 5.58084 20.274C5.29215 20.4669 5.06714 20.7411 4.93428 21.0619C4.80143 21.3827 4.76668 21.7356 4.83444 22.0762C4.9022 22.4167 5.06942 22.7295 5.31495 22.975C5.56049 23.2205 5.87331 23.3877 6.21386 23.4554C6.55441 23.5231 6.90738 23.4883 7.22815 23.3554C7.54891 23.2224 7.82306 22.9974 8.01592 22.7087C8.20877 22.4199 8.31168 22.0805 8.31162 21.7333C8.31093 21.268 8.12574 20.8219 7.79667 20.4929C7.4676 20.1639 7.02149 19.9787 6.55615 19.9781ZM23.5659 25.3638C22.8479 25.3638 22.1459 25.151 21.5489 24.7521C20.9518 24.3532 20.4864 23.7862 20.2116 23.1228C19.9368 22.4594 19.8648 21.7295 20.0049 21.0252C20.1449 20.321 20.4907 19.674 20.9984 19.1663C21.5061 18.6585 22.153 18.3127 22.8573 18.1726C23.5615 18.0325 24.2915 18.1044 24.9549 18.3792C25.6183 18.6539 26.1853 19.1193 26.5842 19.7163C26.9832 20.3133 27.1961 21.0153 27.1961 21.7333C27.195 22.6958 26.8122 23.6185 26.1317 24.2991C25.4511 24.9797 24.5284 25.3626 23.5659 25.3638ZM23.5659 19.9781C23.2187 19.9781 22.8793 20.081 22.5905 20.2739C22.3018 20.4667 22.0767 20.7409 21.9438 21.0617C21.8109 21.3825 21.7761 21.7354 21.8439 22.076C21.9116 22.4166 22.0788 22.7294 22.3243 22.9749C22.5698 23.2204 22.8827 23.3876 23.2232 23.4553C23.5638 23.5231 23.9168 23.4883 24.2376 23.3554C24.5583 23.2225 24.8325 22.9974 25.0254 22.7087C25.2182 22.42 25.3212 22.0805 25.3211 21.7333C25.3204 21.268 25.1353 20.822 24.8062 20.493C24.4772 20.164 24.0312 19.9788 23.5659 19.9781ZM15.1732 22.2041C14.4552 22.2042 13.7532 21.9913 13.1561 21.5924C12.559 21.1934 12.0937 20.6264 11.8189 19.963C11.5441 19.2996 11.4722 18.5696 11.6122 17.8653C11.7523 17.1611 12.0981 16.5141 12.6059 16.0064C13.1137 15.4987 13.7606 15.1529 14.4649 15.0129C15.1692 14.8728 15.8992 14.9448 16.5626 15.2197C17.226 15.4945 17.793 15.9599 18.1918 16.5571C18.5907 17.1542 18.8035 17.8561 18.8034 18.5742C18.8022 19.5366 18.4193 20.4592 17.7388 21.1397C17.0582 21.8201 16.1356 22.2029 15.1732 22.2041ZM15.1732 16.8185C14.826 16.8184 14.4866 16.9213 14.1979 17.1141C13.9092 17.307 13.6841 17.5811 13.5512 17.9019C13.4183 18.2226 13.3835 18.5756 13.4512 18.9161C13.5188 19.2567 13.686 19.5695 13.9314 19.815C14.1769 20.0606 14.4897 20.2278 14.8302 20.2956C15.1707 20.3634 15.5237 20.3287 15.8445 20.1959C16.1653 20.0631 16.4395 19.8381 16.6324 19.5495C16.8253 19.2608 16.9284 18.9214 16.9284 18.5742C16.9279 18.1088 16.7428 17.6627 16.4138 17.3335C16.0848 17.0044 15.6386 16.8192 15.1732 16.8185Z" />
<path d="M7.27539 10.6952L8.68788 9.4621L13.967 15.5094L12.5545 16.7425L7.27539 10.6952ZM17.424 16.7428L16.0115 15.5097L21.2906 9.46245L22.7031 10.6956L17.424 16.7428Z" />
<path d="M14.3686 10.2044C14.8105 9.76241 15.2524 9.76241 15.6944 10.2044L23.4424 17.9523C23.8843 18.3943 23.8843 18.8362 23.4424 19.2782C23.0004 19.7201 22.5585 19.7201 22.1166 19.2782L14.3686 11.5302C13.9266 11.0882 13.9266 10.6463 14.3686 10.2044Z" />
<path d="M6.61954 19.2634C6.1776 18.8214 6.1776 18.3795 6.61954 17.9375L14.3675 10.1895C14.8095 9.74761 15.2514 9.74761 15.6934 10.1895C16.1353 10.6315 16.1353 11.0734 15.6934 11.5154L7.94537 19.2634C7.50343 19.7053 7.06148 19.7053 6.61954 19.2634Z" />
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./js/bschcrypto.min.js"></script>
</head>
<body>
<div style="overflow: hidden">
<div style="width: 45%; float: left">
<textarea id="textarea1" rows="5" style="width: 100%"></textarea>
<br />
<button onclick="decrypt()">decrypt</button>
</div>
<div style="width: 45%; float: right">
<textarea id="textarea2" rows="5" style="width: 100%"></textarea>
<br />
<button onclick="encrypt()">encrypt</button>
</div>
</div>
<br />
<br />
<br />
<textarea id="textarea3" rows="5" style="width: 100%"></textarea>
<script>
const bschCrypto = new BschCryptoUtil();
function decrypt() {
var data = document.getElementById("textarea1").value;
console.log(data);
const plaintext = bschCrypto.decrypt(data);
console.log(plaintext);
document.getElementById("textarea3").value = JSON.stringify(plaintext);
}
function encrypt() {
var data = document.getElementById("textarea2").value;
const ciphertext = bschCrypto.encrypt(data);
console.log(ciphertext);
document.getElementById("textarea3").value = ciphertext;
}
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>harness-取证</title>
<script type="module" crossorigin src="./assets/harness-yV9bTKyt.js"></script>
<link rel="stylesheet" crossorigin href="./assets/harness-BT-Hyg0t.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

+47
View File
@@ -0,0 +1,47 @@
(function (global) {
/* ---------- 1. 默认 16 字节密钥 ---------- */
const DEFAULT_KEY_WA = CryptoJS.MD5("bsch2025"); // WordArray(16 byte)
class BschCryptoUtil {
#aesKey;
constructor(key) {
// 支持外部传入字符串或 WordArray,默认用隐藏后的 MD5
this.#aesKey = key != null ? key : DEFAULT_KEY_WA;
}
encrypt(data) {
const message = typeof data === "string" ? data : JSON.stringify(data);
const encrypted = CryptoJS.AES.encrypt(message, this.#aesKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString(); // Base64
}
decrypt(cipherText) {
if (!cipherText) throw new Error("cipherText is empty");
const decrypted = CryptoJS.AES.decrypt(cipherText, this.#aesKey, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
});
const plain = decrypted.toString(CryptoJS.enc.Utf8);
if (!plain) throw new Error("decrypt failed");
try {
return JSON.parse(plain);
} catch (_) {
return plain;
}
}
static encrypt(data, key) {
return new BschCryptoUtil(key).encrypt(data);
}
static decrypt(cipherText, key) {
return new BschCryptoUtil(key).decrypt(cipherText);
}
}
/* ---------- 6. 暴露到全局 ---------- */
global.BschCryptoUtil = BschCryptoUtil;
})(typeof window !== "undefined" ? window : this);
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
"use strict";function _instanceof(n,e){return null!=e&&"undefined"!=typeof Symbol&&e[Symbol.hasInstance]?!!e[Symbol.hasInstance](n):n instanceof e}function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _classCallCheck(a,n){if(!_instanceof(a,n))throw new TypeError("Cannot call a class as a function");}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t)}function _classPrivateFieldInitSpec(e,t,a){_checkPrivateRedeclaration(e,t),t.set(e,a)}function _checkPrivateRedeclaration(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object");}function _classPrivateFieldGet(s,a){return s.get(_assertClassBrand(s,a))}function _classPrivateFieldSet(s,a,r){return s.set(_assertClassBrand(s,a),r),r}function _assertClassBrand(e,t,n){if("function"==typeof e?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object");}var _isDev=new WeakMap();var _appId=new WeakMap();var BschLoadUtil=function(){function BschLoadUtil(){_classCallCheck(this,BschLoadUtil);_classPrivateFieldInitSpec(this,_isDev,false);_classPrivateFieldInitSpec(this,_appId,null);if(!BschLoadUtil.instance){this.isSelf=window.self===window.top;_classPrivateFieldSet(_appId,this,this.uuid());this.ticket=null;this.roleInfo={roleId:null,schId:null,childId:null};BschLoadUtil.instance=this}return BschLoadUtil.instance}return _createClass(BschLoadUtil,[{key:"getTicket",value:function getTicket(){if(!_classPrivateFieldGet(_isDev,this)){var ticket=this.getUrlParam("ticket"),roleInfoStr=this.getUrlParam("role");var roleInfo=this.roleDecode(roleInfoStr);this.ticket=ticket;this.roleInfo=roleInfo}return{ticket:this.ticket,roleInfo:this.roleInfo}}},{key:"goBackDesktop",value:function goBackDesktop(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:1}),"*")}},{key:"reloadParent",value:function reloadParent(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:2}),"*")}},{key:"showUserInfo",value:function showUserInfo(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:3}),"*")}},{key:"roleDecode",value:function roleDecode(roleInfoStr){try{var str=window.atob(roleInfoStr);str=decodeURIComponent(str);var obj=JSON.parse(str);return obj}catch(error){console.error(error);return{id:null,ticket:"",roleInfo:{}}}}},{key:"setDevTicket",value:function setDevTicket(ticket,roleInfo){if(this.isSelf){this.ticket=ticket;this.roleInfo=roleInfo;_classPrivateFieldSet(_isDev,this,true)}}},{key:"getIsSelf",value:function getIsSelf(){if(_classPrivateFieldGet(_isDev,this))return false;else return this.isSelf}},{key:"getUrlParam",value:function getUrlParam(name){var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)");var r=window.location.search.substr(1).match(reg);if(r!=null)return unescape(r[2]);else return null}},{key:"uuid",value:function uuid(){return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=="x"?r:r&0x3|0x8;return v.toString(16)})}}],[{key:"getInstance",value:function getInstance(){if(!this.instance){return this.instance=new BschLoadUtil()}return this.instance}}])}();
+1
View File
@@ -0,0 +1 @@
"use strict";function _instanceof(n,e){return null!=e&&"undefined"!=typeof Symbol&&e[Symbol.hasInstance]?!!e[Symbol.hasInstance](n):n instanceof e}function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function _classCallCheck(a,n){if(!_instanceof(a,n))throw new TypeError("Cannot call a class as a function");}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t)}function _classPrivateFieldInitSpec(e,t,a){_checkPrivateRedeclaration(e,t),t.set(e,a)}function _checkPrivateRedeclaration(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object");}function _classPrivateFieldGet(s,a){return s.get(_assertClassBrand(s,a))}function _classPrivateFieldSet(s,a,r){return s.set(_assertClassBrand(s,a),r),r}function _assertClassBrand(e,t,n){if("function"==typeof e?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object");}var _isDev=new WeakMap();var _appId=new WeakMap();var BschLoadUtil=function(){function BschLoadUtil(){_classCallCheck(this,BschLoadUtil);_classPrivateFieldInitSpec(this,_isDev,false);_classPrivateFieldInitSpec(this,_appId,null);if(!BschLoadUtil.instance){this.isSelf=window.self===window.top;_classPrivateFieldSet(_appId,this,this.uuid());this.ticket=null;this.roleInfo={userId:null,roleId:null,schId:null,childId:null};BschLoadUtil.instance=this}return BschLoadUtil.instance}return _createClass(BschLoadUtil,[{key:"getTicket",value:function getTicket(){if(!_classPrivateFieldGet(_isDev,this)){var ticket=this.getUrlParam("ticket"),roleInfoStr=this.getUrlParam("role");var roleInfo=this.roleDecode(roleInfoStr);this.ticket=ticket;this.roleInfo=roleInfo}return{ticket:this.ticket,roleInfo:this.roleInfo}}},{key:"goBackDesktop",value:function goBackDesktop(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:1}),"*")}},{key:"reloadParent",value:function reloadParent(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:2}),"*")}},{key:"showUserInfo",value:function showUserInfo(){if(_classPrivateFieldGet(_isDev,this)){console.error("调试模式,无效操作!");return}parent.postMessage(JSON.stringify({id:_classPrivateFieldGet(_appId,this),code:3}),"*")}},{key:"roleDecode",value:function roleDecode(roleInfoStr){try{var str=window.atob(roleInfoStr);str=decodeURIComponent(str);var obj=JSON.parse(str);return obj}catch(error){console.error(error);return{id:null,ticket:"",roleInfo:{}}}}},{key:"setDevTicket",value:function setDevTicket(ticket,roleInfo){if(this.isSelf){this.ticket=ticket;this.roleInfo=roleInfo;_classPrivateFieldSet(_isDev,this,true)}}},{key:"getIsSelf",value:function getIsSelf(){if(_classPrivateFieldGet(_isDev,this))return false;else return this.isSelf}},{key:"getUrlParam",value:function getUrlParam(name){var reg=new RegExp("(^|&)"+name+"=([^&]*)(&|$)");var r=window.location.search.substr(1).match(reg);if(r!=null)return unescape(r[2]);else return null}},{key:"uuid",value:function uuid(){return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=="x"?r:r&0x3|0x8;return v.toString(16)})}}],[{key:"getInstance",value:function getInstance(){if(!this.instance){return this.instance=new BschLoadUtil()}return this.instance}}])}();
+128
View File
@@ -0,0 +1,128 @@
/**
* 数字基座内嵌加载帮助类
*/
class BschLoadUtil {
#isDev = false;
#appId = null;
#headerInfo = {};
constructor() {
if (!BschLoadUtil.instance) {
this.isSelf = window.self === window.top;
this.ticket = null;
this.roleInfo = {
roleId: null,
schId: null,
childId: null,
};
BschLoadUtil.instance = this;
}
return BschLoadUtil.instance;
}
getTicket() {
if (this.#isDev) return Promise.resolve({ ticket: this.ticket, roleInfo: this.roleInfo });
else
return new Promise((resolve, reject) => {
window.addEventListener(
"message",
e => {
var { id, ticket, roleInfo, headerInfo } = this.roleDecode(e.data);
this.#appId = id;
this.#headerInfo = headerInfo;
this.ticket = ticket;
this.roleInfo = roleInfo;
resolve({ ticket, roleInfo });
},
false
);
});
}
replaceHeaderStyle(el) {
if (this.#headerInfo == null) return false;
const { appName, avatar, username } = this.#headerInfo;
let headerStr = `
<header class="header-container fix">
<h4 class="fl align-middle">${appName}</h4>
<div class="header-aside fr">
<img id="js_comp_user_phone" src="${avatar}" class="fl align-middle">
<a id="js_comp_user_name" class="name fl align-middle text-ellipsis" href="javascript:void(0);">${username}</a>
<div class="delimiter fl align-middle"></div>
<a href="javascript:;" id="js_comp_operate" class="logout fl align-middle" title="返回桌面">
<i class="iconfont icon-shouye"></i>
</a>
</div>
</header>
`;
const _this = this;
$(el).append(headerStr);
$(el)
.find("#js_comp_user_phone")
.click(() => _this.showUserInfo());
$(el)
.find("#js_comp_user_name")
.click(() => _this.showUserInfo());
$(el)
.find("#js_comp_operate")
.click(() => _this.goBackDesktop());
}
goBackDesktop() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 1 }), "*");
}
reloadParent() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 2 }), "*");
}
showUserInfo() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 3 }), "*");
}
roleDecode(roleInfoStr) {
try {
var str = window.atob(roleInfoStr);
str = decodeURIComponent(str);
var obj = JSON.parse(str);
return obj;
} catch (error) {
console.error(error);
return {
id: null,
ticket: "",
roleInfo: {},
};
}
}
setDevTicket(ticket, roleInfo) {
if (this.isSelf) {
this.ticket = ticket;
this.roleInfo = roleInfo;
this.#isDev = true;
}
}
getIsSelf() {
if (this.#isDev) return false;
else return this.isSelf;
}
static getInstance() {
if (!this.instance) {
return (this.instance = new BschLoadUtil());
}
return this.instance;
}
}
+106
View File
@@ -0,0 +1,106 @@
/**
* 数字基座内嵌加载帮助类
*/
class BschLoadUtil {
#isDev = false;
#appId = null;
constructor() {
if (!BschLoadUtil.instance) {
this.isSelf = window.self === window.top;
this.#appId = this.uuid();
this.ticket = null;
this.roleInfo = {
userId: null,
roleId: null,
schId: null,
childId: null,
};
BschLoadUtil.instance = this;
}
return BschLoadUtil.instance;
}
getTicket() {
if (!this.#isDev) {
const ticket = this.getUrlParam("ticket"),
roleInfoStr = this.getUrlParam("role");
var roleInfo = this.roleDecode(roleInfoStr);
this.ticket = ticket;
this.roleInfo = roleInfo;
}
return { ticket: this.ticket, roleInfo: this.roleInfo };
}
goBackDesktop() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 1 }), "*");
}
reloadParent() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 2 }), "*");
}
showUserInfo() {
if (this.#isDev) {
console.error("调试模式,无效操作!");
return;
}
parent.postMessage(JSON.stringify({ id: this.#appId, code: 3 }), "*");
}
roleDecode(roleInfoStr) {
try {
var str = window.atob(roleInfoStr);
str = decodeURIComponent(str);
var obj = JSON.parse(str);
return obj;
} catch (error) {
console.error(error);
return {
id: null,
ticket: "",
roleInfo: {},
};
}
}
setDevTicket(ticket, roleInfo) {
if (this.isSelf) {
this.ticket = ticket;
this.roleInfo = roleInfo;
this.#isDev = true;
}
}
getIsSelf() {
if (this.#isDev) return false;
else return this.isSelf;
}
getUrlParam(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
let r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
else return null;
}
uuid() {
return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
let r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
static getInstance() {
if (!this.instance) {
return (this.instance = new BschLoadUtil());
}
return this.instance;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,628 @@
/*
* JQuery zTree excheck v3.5.28
* http://treejs.cn/
*
* Copyright (c) 2010 Hunter.z
*
* Licensed same as jquery - MIT License
* http://www.opensource.org/licenses/mit-license.php
*
* email: hunter.z@263.net
* Date: 2017-01-20
*/
(function($){
//default consts of excheck
var _consts = {
event: {
CHECK: "ztree_check"
},
id: {
CHECK: "_check"
},
checkbox: {
STYLE: "checkbox",
DEFAULT: "chk",
DISABLED: "disable",
FALSE: "false",
TRUE: "true",
FULL: "full",
PART: "part",
FOCUS: "focus"
},
radio: {
STYLE: "radio",
TYPE_ALL: "all",
TYPE_LEVEL: "level"
}
},
//default setting of excheck
_setting = {
check: {
enable: false,
autoCheckTrigger: false,
chkStyle: _consts.checkbox.STYLE,
nocheckInherit: false,
chkDisabledInherit: false,
radioType: _consts.radio.TYPE_LEVEL,
chkboxType: {
"Y": "ps",
"N": "ps"
}
},
data: {
key: {
checked: "checked"
}
},
callback: {
beforeCheck:null,
onCheck:null
}
},
//default root of excheck
_initRoot = function (setting) {
var r = data.getRoot(setting);
r.radioCheckedList = [];
},
//default cache of excheck
_initCache = function(treeId) {},
//default bind event of excheck
_bindEvent = function(setting) {
var o = setting.treeObj,
c = consts.event;
o.bind(c.CHECK, function (event, srcEvent, treeId, node) {
event.srcEvent = srcEvent;
tools.apply(setting.callback.onCheck, [event, treeId, node]);
});
},
_unbindEvent = function(setting) {
var o = setting.treeObj,
c = consts.event;
o.unbind(c.CHECK);
},
//default event proxy of excheck
_eventProxy = function(e) {
var target = e.target,
setting = data.getSetting(e.data.treeId),
tId = "", node = null,
nodeEventType = "", treeEventType = "",
nodeEventCallback = null, treeEventCallback = null;
if (tools.eqs(e.type, "mouseover")) {
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) {
tId = tools.getNodeMainDom(target).id;
nodeEventType = "mouseoverCheck";
}
} else if (tools.eqs(e.type, "mouseout")) {
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) {
tId = tools.getNodeMainDom(target).id;
nodeEventType = "mouseoutCheck";
}
} else if (tools.eqs(e.type, "click")) {
if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) {
tId = tools.getNodeMainDom(target).id;
nodeEventType = "checkNode";
}
}
if (tId.length>0) {
node = data.getNodeCache(setting, tId);
switch (nodeEventType) {
case "checkNode" :
nodeEventCallback = _handler.onCheckNode;
break;
case "mouseoverCheck" :
nodeEventCallback = _handler.onMouseoverCheck;
break;
case "mouseoutCheck" :
nodeEventCallback = _handler.onMouseoutCheck;
break;
}
}
var proxyResult = {
stop: nodeEventType === "checkNode",
node: node,
nodeEventType: nodeEventType,
nodeEventCallback: nodeEventCallback,
treeEventType: treeEventType,
treeEventCallback: treeEventCallback
};
return proxyResult
},
//default init node of excheck
_initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {
if (!n) return;
var checkedKey = setting.data.key.checked;
if (typeof n[checkedKey] == "string") n[checkedKey] = tools.eqs(n[checkedKey], "true");
n[checkedKey] = !!n[checkedKey];
n.checkedOld = n[checkedKey];
if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true");
n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck);
if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true");
n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled);
if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true");
n.halfCheck = !!n.halfCheck;
n.check_Child_State = -1;
n.check_Focus = false;
n.getCheckStatus = function() {return data.getCheckStatus(setting, n);};
if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && n[checkedKey] ) {
var r = data.getRoot(setting);
r.radioCheckedList.push(n);
}
},
//add dom for check
_beforeA = function(setting, node, html) {
var checkedKey = setting.data.key.checked;
if (setting.check.enable) {
data.makeChkFlag(setting, node);
html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true?" style='display:none;'":""),"></span>");
}
},
//update zTreeObj, add method of check
_zTreeTools = function(setting, zTreeTools) {
zTreeTools.checkNode = function(node, checked, checkTypeFlag, callbackFlag) {
var checkedKey = this.setting.data.key.checked;
if (node.chkDisabled === true) return;
if (checked !== true && checked !== false) {
checked = !node[checkedKey];
}
callbackFlag = !!callbackFlag;
if (node[checkedKey] === checked && !checkTypeFlag) {
return;
} else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) {
return;
}
if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) {
node[checkedKey] = checked;
var checkObj = $$(node, consts.id.CHECK, this.setting);
if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
view.setChkClass(this.setting, checkObj, node);
view.repairParentChkClassWithSelf(this.setting, node);
if (callbackFlag) {
this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]);
}
}
}
zTreeTools.checkAllNodes = function(checked) {
view.repairAllChk(this.setting, !!checked);
}
zTreeTools.getCheckedNodes = function(checked) {
var childKey = this.setting.data.key.children;
checked = (checked !== false);
return data.getTreeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey], checked);
}
zTreeTools.getChangeCheckedNodes = function() {
var childKey = this.setting.data.key.children;
return data.getTreeChangeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey]);
}
zTreeTools.setChkDisabled = function(node, disabled, inheritParent, inheritChildren) {
disabled = !!disabled;
inheritParent = !!inheritParent;
inheritChildren = !!inheritChildren;
view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren);
view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent);
}
var _updateNode = zTreeTools.updateNode;
zTreeTools.updateNode = function(node, checkTypeFlag) {
if (_updateNode) _updateNode.apply(zTreeTools, arguments);
if (!node || !this.setting.check.enable) return;
var nObj = $$(node, this.setting);
if (nObj.get(0) && tools.uCanDo(this.setting)) {
var checkObj = $$(node, consts.id.CHECK, this.setting);
if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node);
view.setChkClass(this.setting, checkObj, node);
view.repairParentChkClassWithSelf(this.setting, node);
}
}
},
//method of operate data
_data = {
getRadioCheckedList: function(setting) {
var checkedList = data.getRoot(setting).radioCheckedList;
for (var i=0, j=checkedList.length; i<j; i++) {
if(!data.getNodeCache(setting, checkedList[i].tId)) {
checkedList.splice(i, 1);
i--; j--;
}
}
return checkedList;
},
getCheckStatus: function(setting, node) {
if (!setting.check.enable || node.nocheck || node.chkDisabled) return null;
var checkedKey = setting.data.key.checked,
r = {
checked: node[checkedKey],
half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (node[checkedKey] ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0)))
};
return r;
},
getTreeCheckedNodes: function(setting, nodes, checked, results) {
if (!nodes) return [];
var childKey = setting.data.key.children,
checkedKey = setting.data.key.checked,
onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL);
results = !results ? [] : results;
for (var i = 0, l = nodes.length; i < l; i++) {
if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] == checked) {
results.push(nodes[i]);
if(onlyOne) {
break;
}
}
data.getTreeCheckedNodes(setting, nodes[i][childKey], checked, results);
if(onlyOne && results.length > 0) {
break;
}
}
return results;
},
getTreeChangeCheckedNodes: function(setting, nodes, results) {
if (!nodes) return [];
var childKey = setting.data.key.children,
checkedKey = setting.data.key.checked;
results = !results ? [] : results;
for (var i = 0, l = nodes.length; i < l; i++) {
if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] != nodes[i].checkedOld) {
results.push(nodes[i]);
}
data.getTreeChangeCheckedNodes(setting, nodes[i][childKey], results);
}
return results;
},
makeChkFlag: function(setting, node) {
if (!node) return;
var childKey = setting.data.key.children,
checkedKey = setting.data.key.checked,
chkFlag = -1;
if (node[childKey]) {
for (var i = 0, l = node[childKey].length; i < l; i++) {
var cNode = node[childKey][i];
var tmp = -1;
if (setting.check.chkStyle == consts.radio.STYLE) {
if (cNode.nocheck === true || cNode.chkDisabled === true) {
tmp = cNode.check_Child_State;
} else if (cNode.halfCheck === true) {
tmp = 2;
} else if (cNode[checkedKey]) {
tmp = 2;
} else {
tmp = cNode.check_Child_State > 0 ? 2:0;
}
if (tmp == 2) {
chkFlag = 2; break;
} else if (tmp == 0){
chkFlag = 0;
}
} else if (setting.check.chkStyle == consts.checkbox.STYLE) {
if (cNode.nocheck === true || cNode.chkDisabled === true) {
tmp = cNode.check_Child_State;
} else if (cNode.halfCheck === true) {
tmp = 1;
} else if (cNode[checkedKey] ) {
tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1;
} else {
tmp = (cNode.check_Child_State > 0) ? 1 : 0;
}
if (tmp === 1) {
chkFlag = 1; break;
} else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) {
chkFlag = 1; break;
} else if (chkFlag === 2 && tmp > -1 && tmp < 2) {
chkFlag = 1; break;
} else if (tmp > -1) {
chkFlag = tmp;
}
}
}
}
node.check_Child_State = chkFlag;
}
},
//method of event proxy
_event = {
},
//method of event handler
_handler = {
onCheckNode: function (event, node) {
if (node.chkDisabled === true) return false;
var setting = data.getSetting(event.data.treeId),
checkedKey = setting.data.key.checked;
if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true;
node[checkedKey] = !node[checkedKey];
view.checkNodeRelation(setting, node);
var checkObj = $$(node, consts.id.CHECK, setting);
view.setChkClass(setting, checkObj, node);
view.repairParentChkClassWithSelf(setting, node);
setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]);
return true;
},
onMouseoverCheck: function(event, node) {
if (node.chkDisabled === true) return false;
var setting = data.getSetting(event.data.treeId),
checkObj = $$(node, consts.id.CHECK, setting);
node.check_Focus = true;
view.setChkClass(setting, checkObj, node);
return true;
},
onMouseoutCheck: function(event, node) {
if (node.chkDisabled === true) return false;
var setting = data.getSetting(event.data.treeId),
checkObj = $$(node, consts.id.CHECK, setting);
node.check_Focus = false;
view.setChkClass(setting, checkObj, node);
return true;
}
},
//method of tools for zTree
_tools = {
},
//method of operate ztree dom
_view = {
checkNodeRelation: function(setting, node) {
var pNode, i, l,
childKey = setting.data.key.children,
checkedKey = setting.data.key.checked,
r = consts.radio;
if (setting.check.chkStyle == r.STYLE) {
var checkedList = data.getRadioCheckedList(setting);
if (node[checkedKey]) {
if (setting.check.radioType == r.TYPE_ALL) {
for (i = checkedList.length-1; i >= 0; i--) {
pNode = checkedList[i];
if (pNode[checkedKey] && pNode != node) {
pNode[checkedKey] = false;
checkedList.splice(i, 1);
view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
if (pNode.parentTId != node.parentTId) {
view.repairParentChkClassWithSelf(setting, pNode);
}
}
}
checkedList.push(node);
} else {
var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting);
for (i = 0, l = parentNode[childKey].length; i < l; i++) {
pNode = parentNode[childKey][i];
if (pNode[checkedKey] && pNode != node) {
pNode[checkedKey] = false;
view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode);
}
}
}
} else if (setting.check.radioType == r.TYPE_ALL) {
for (i = 0, l = checkedList.length; i < l; i++) {
if (node == checkedList[i]) {
checkedList.splice(i, 1);
break;
}
}
}
} else {
if (node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.Y.indexOf("s") > -1)) {
view.setSonNodeCheckBox(setting, node, true);
}
if (!node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.N.indexOf("s") > -1)) {
view.setSonNodeCheckBox(setting, node, false);
}
if (node[checkedKey] && setting.check.chkboxType.Y.indexOf("p") > -1) {
view.setParentNodeCheckBox(setting, node, true);
}
if (!node[checkedKey] && setting.check.chkboxType.N.indexOf("p") > -1) {
view.setParentNodeCheckBox(setting, node, false);
}
}
},
makeChkClass: function(setting, node) {
var checkedKey = setting.data.key.checked,
c = consts.checkbox, r = consts.radio,
fullStyle = "";
if (node.chkDisabled === true) {
fullStyle = c.DISABLED;
} else if (node.halfCheck) {
fullStyle = c.PART;
} else if (setting.check.chkStyle == r.STYLE) {
fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART;
} else {
fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART);
}
var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle;
chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName;
return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName;
},
repairAllChk: function(setting, checked) {
if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) {
var checkedKey = setting.data.key.checked,
childKey = setting.data.key.children,
root = data.getRoot(setting);
for (var i = 0, l = root[childKey].length; i<l ; i++) {
var node = root[childKey][i];
if (node.nocheck !== true && node.chkDisabled !== true) {
node[checkedKey] = checked;
}
view.setSonNodeCheckBox(setting, node, checked);
}
}
},
repairChkClass: function(setting, node) {
if (!node) return;
data.makeChkFlag(setting, node);
if (node.nocheck !== true) {
var checkObj = $$(node, consts.id.CHECK, setting);
view.setChkClass(setting, checkObj, node);
}
},
repairParentChkClass: function(setting, node) {
if (!node || !node.parentTId) return;
var pNode = node.getParentNode();
view.repairChkClass(setting, pNode);
view.repairParentChkClass(setting, pNode);
},
repairParentChkClassWithSelf: function(setting, node) {
if (!node) return;
var childKey = setting.data.key.children;
if (node[childKey] && node[childKey].length > 0) {
view.repairParentChkClass(setting, node[childKey][0]);
} else {
view.repairParentChkClass(setting, node);
}
},
repairSonChkDisabled: function(setting, node, chkDisabled, inherit) {
if (!node) return;
var childKey = setting.data.key.children;
if (node.chkDisabled != chkDisabled) {
node.chkDisabled = chkDisabled;
}
view.repairChkClass(setting, node);
if (node[childKey] && inherit) {
for (var i = 0, l = node[childKey].length; i < l; i++) {
var sNode = node[childKey][i];
view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit);
}
}
},
repairParentChkDisabled: function(setting, node, chkDisabled, inherit) {
if (!node) return;
if (node.chkDisabled != chkDisabled && inherit) {
node.chkDisabled = chkDisabled;
}
view.repairChkClass(setting, node);
view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit);
},
setChkClass: function(setting, obj, node) {
if (!obj) return;
if (node.nocheck === true) {
obj.hide();
} else {
obj.show();
}
obj.attr('class', view.makeChkClass(setting, node));
},
setParentNodeCheckBox: function(setting, node, value, srcNode) {
var childKey = setting.data.key.children,
checkedKey = setting.data.key.checked,
checkObj = $$(node, consts.id.CHECK, setting);
if (!srcNode) srcNode = node;
data.makeChkFlag(setting, node);
if (node.nocheck !== true && node.chkDisabled !== true) {
node[checkedKey] = value;
view.setChkClass(setting, checkObj, node);
if (setting.check.autoCheckTrigger && node != srcNode) {
setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
}
}
if (node.parentTId) {
var pSign = true;
if (!value) {
var pNodes = node.getParentNode()[childKey];
for (var i = 0, l = pNodes.length; i < l; i++) {
if ((pNodes[i].nocheck !== true && pNodes[i].chkDisabled !== true && pNodes[i][checkedKey])
|| ((pNodes[i].nocheck === true || pNodes[i].chkDisabled === true) && pNodes[i].check_Child_State > 0)) {
pSign = false;
break;
}
}
}
if (pSign) {
view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode);
}
}
},
setSonNodeCheckBox: function(setting, node, value, srcNode) {
if (!node) return;
var childKey = setting.data.key.children,
checkedKey = setting.data.key.checked,
checkObj = $$(node, consts.id.CHECK, setting);
if (!srcNode) srcNode = node;
var hasDisable = false;
if (node[childKey]) {
for (var i = 0, l = node[childKey].length; i < l; i++) {
var sNode = node[childKey][i];
view.setSonNodeCheckBox(setting, sNode, value, srcNode);
if (sNode.chkDisabled === true) hasDisable = true;
}
}
if (node != data.getRoot(setting) && node.chkDisabled !== true) {
if (hasDisable && node.nocheck !== true) {
data.makeChkFlag(setting, node);
}
if (node.nocheck !== true && node.chkDisabled !== true) {
node[checkedKey] = value;
if (!hasDisable) node.check_Child_State = (node[childKey] && node[childKey].length > 0) ? (value ? 2 : 0) : -1;
} else {
node.check_Child_State = -1;
}
view.setChkClass(setting, checkObj, node);
if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) {
setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]);
}
}
}
},
_z = {
tools: _tools,
view: _view,
event: _event,
data: _data
};
$.extend(true, $.fn.zTree.consts, _consts);
$.extend(true, $.fn.zTree._z, _z);
var zt = $.fn.zTree,
tools = zt._z.tools,
consts = zt.consts,
view = zt._z.view,
data = zt._z.data,
event = zt._z.event,
$$ = tools.$;
data.exSetting(_setting);
data.addInitBind(_bindEvent);
data.addInitUnBind(_unbindEvent);
data.addInitCache(_initCache);
data.addInitNode(_initNode);
data.addInitProxy(_eventProxy, true);
data.addInitRoot(_initRoot);
data.addBeforeA(_beforeA);
data.addZTreeTools(_zTreeTools);
var _createNodes = view.createNodes;
view.createNodes = function(setting, level, nodes, parentNode, index) {
if (_createNodes) _createNodes.apply(view, arguments);
if (!nodes) return;
view.repairParentChkClassWithSelf(setting, parentNode);
}
var _removeNode = view.removeNode;
view.removeNode = function(setting, node) {
var parentNode = node.getParentNode();
if (_removeNode) _removeNode.apply(view, arguments);
if (!node || !parentNode) return;
view.repairChkClass(setting, parentNode);
view.repairParentChkClass(setting, parentNode);
}
var _appendNodes = view.appendNodes;
view.appendNodes = function(setting, level, nodes, parentNode, index, initFlag, openFlag) {
var html = "";
if (_appendNodes) {
html = _appendNodes.apply(view, arguments);
}
if (parentNode) {
data.makeChkFlag(setting, parentNode);
}
return html;
}
})(jQuery);
File diff suppressed because it is too large Load Diff
+95
View File
@@ -0,0 +1,95 @@
/*-------------------------------------
zTree Style
version: 3.4
author: Hunter.z
email: hunter.z@263.net
website: http://code.google.com/p/jquerytree/
-------------------------------------*/
.ztree * {padding:0; margin:0; font-size:14px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif}
.ztree {margin:0; padding:5px; color:#333}
.ztree li{padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0}
.ztree li ul{ margin:0; padding:0 0 0 18px}
.ztree li ul.line{ background:url(./img/line_conn.png) 0 0 repeat-y;}
.ztree li a {padding-right:3px; margin:0; cursor:pointer; height:21px; color:#333; background-color: transparent; text-decoration:none; vertical-align:top; display: inline-block}
.ztree li a:hover {text-decoration:underline}
.ztree li a.curSelectedNode {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; opacity:0.8;}
.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#e5e5e5; color:black; height:21px; border:1px #666 solid; opacity:0.8;}
.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#aaa; color:white; height:21px; border:1px #666 solid;
opacity:0.8; filter:alpha(opacity=80)}
.ztree li a.tmpTargetNode_prev {}
.ztree li a.tmpTargetNode_next {}
.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0;
font-size:12px; border:1px #585956 solid; *border:0px}
.ztree li span {line-height:21px; margin-right:2px}
.ztree li span.button {line-height:0; margin:0; padding: 0; width:21px; height:21px; display: inline-block; vertical-align:middle;
border:0 none; cursor: pointer;outline:none;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
background-image:url("./img/bootstrap.png");}
.ztree li span.button.chk {width:13px; height:13px; margin:0 2px; cursor: auto}
.ztree li span.button.chk.checkbox_false_full {background-position: -5px -5px;}
.ztree li span.button.chk.checkbox_false_full_focus {background-position: -5px -26px;}
.ztree li span.button.chk.checkbox_false_part {background-position: -5px -48px;}
.ztree li span.button.chk.checkbox_false_part_focus {background-position: -5px -68px;}
.ztree li span.button.chk.checkbox_false_disable {background-position: -5px -89px;}
.ztree li span.button.chk.checkbox_true_full {background-position: -26px -5px;}
.ztree li span.button.chk.checkbox_true_full_focus {background-position: -26px -26px;}
.ztree li span.button.chk.checkbox_true_part {background-position: -26px -48px;}
.ztree li span.button.chk.checkbox_true_part_focus {background-position: -26px -68px;}
.ztree li span.button.chk.checkbox_true_disable {background-position: -26px -89px;}
.ztree li span.button.chk.radio_false_full {background-position: -47px -5px;}
.ztree li span.button.chk.radio_false_full_focus {background-position: -47px -26px;}
.ztree li span.button.chk.radio_false_part {background-position: -47px -47px;}
.ztree li span.button.chk.radio_false_part_focus {background-position: -47px -68px;}
.ztree li span.button.chk.radio_false_disable {background-position: -47px -89px;}
.ztree li span.button.chk.radio_true_full {background-position: -68px -5px;}
.ztree li span.button.chk.radio_true_full_focus {background-position: -68px -26px;}
.ztree li span.button.chk.radio_true_part {background-position: -68px -47px;}
.ztree li span.button.chk.radio_true_part_focus {background-position: -68px -68px;}
.ztree li span.button.chk.radio_true_disable {background-position: -68px -89px;}
.ztree li span.button.switch {width:21px; height:21px}
.ztree li span.button.root_open{background-position:-105px -63px}
.ztree li span.button.root_close{background-position:-126px -63px}
.ztree li span.button.roots_open{background-position: -105px 0;}
.ztree li span.button.roots_close{background-position: -126px 0;}
.ztree li span.button.center_open{background-position: -105px -21px;}
.ztree li span.button.center_close{background-position: -126px -21px;}
.ztree li span.button.bottom_open{background-position: -105px -42px;}
.ztree li span.button.bottom_close{background-position: -126px -42px;}
.ztree li span.button.noline_open{background-position: -105px -84px;}
.ztree li span.button.noline_close{background-position: -126px -84px;}
.ztree li span.button.root_docu{ background:none;}
.ztree li span.button.roots_docu{background-position: -84px 0;}
.ztree li span.button.center_docu{background-position: -84px -21px;}
.ztree li span.button.bottom_docu{background-position: -84px -42px;}
.ztree li span.button.noline_docu{ background:none;}
.ztree li span.button.ico_open{margin-right:2px; background-position: -147px -21px; vertical-align:top; *vertical-align:middle}
.ztree li span.button.ico_close{margin-right:2px; margin-right:2px; background-position: -147px 0; vertical-align:top; *vertical-align:middle}
.ztree li span.button.ico_docu{margin-right:2px; background-position: -147px -43px; vertical-align:top; *vertical-align:middle}
.ztree li span.button.edit {margin-left:2px; margin-right: -1px; background-position: -189px -21px; vertical-align:top; *vertical-align:middle}
.ztree li span.button.edit:hover {
background-position: -168px -21px;
}
.ztree li span.button.remove {margin-left:2px; margin-right: -1px; background-position: -189px -42px; vertical-align:top; *vertical-align:middle}
.ztree li span.button.remove:hover {
background-position: -168px -42px;
}
.ztree li span.button.add {margin-left:2px; margin-right: -1px; background-position: -189px 0; vertical-align:top; *vertical-align:middle}
.ztree li span.button.add:hover {
background-position: -168px 0;
}
ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)}
span.tmpzTreeMove_arrow {width:16px; height:21px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
background-position:-168px -84px; background-image:url("./img/bootstrap.png");}
ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)}
.ztreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute}
@@ -0,0 +1,3 @@
.ztree li span.button {background-image:url("./img/bootstrap3.png");}
span.tmpzTreeMove_arrow {background-image:url("./img/bootstrap3.png");}
@@ -0,0 +1 @@
.app-container{width:92px;height:100px;border-radius:2px;margin:10px 15px;cursor:pointer;display:flex;flex-direction:column;text-align:center;justify-content:center;align-items:center;-webkit-user-select:none;user-select:none;transition:background-color .2s ease-in-out}.app-container:hover,.app-container__focus{background-color:#ffffff4d}.app-container a{display:inline-block;width:90%;height:85%}.app-container img{width:60px;height:60px;object-fit:cover;border-radius:18%;display:inline-block}.app-container .app-name{margin-top:2px;color:#fff;font-weight:500;max-width:99%;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.app-container__mask{margin-right:40px;margin-bottom:20px}.app-container__mask .app-name{color:#344449}.app-container__mask:hover,.app-container__mask+.app-container__focus{background-color:#ffffff80}
@@ -0,0 +1 @@
.header-container{background:transparent;transition:all .3s;box-shadow:0 10px 20px #cbcbcb17;height:var(--appHeaderH);background-color:#577afb;width:100%}.header-container .icon-box{margin:0 24px;cursor:pointer;background-repeat:no-repeat;background-position:30px center;background-size:14px}.header-container .icon-btn{background:transparent;height:24px;width:24px;line-height:24px;box-sizing:border-box;border-radius:2px;transition:all .5s}.header-container .icon-btn i{color:#fff;font-size:22px;font-weight:100}.header-container .icon-btn.active{transform:rotate(90deg)}.header-container .delimiter{width:2px;border-left:1px solid rgba(255,255,255,.5);height:20px}.header-container h4{font-size:19px;color:#fff;margin-left:12px;font-weight:700;font-family:SimSun}.header-container .school-bg{position:absolute;top:0;height:100%;width:100%;left:0;right:0;z-index:-1}.header-container .header-aside{max-width:260px;height:var(--appHeaderH)}.header-container .header-aside img{float:left;width:28px;height:28px;border-radius:50%;cursor:pointer}.header-container .header-aside .name{max-width:90px;color:#fff;margin:0 32px 0 14px}.header-container .header-aside a{outline:none}.header-container .header-aside a:hover{opacity:.8}.header-container .header-aside .logout{padding:5px;margin:0 25px}.header-container .header-aside .logout i{color:#fff;font-size:18px}
@@ -0,0 +1 @@
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body,#app{height:100%;width:100%;overflow:hidden}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}a{text-decoration:none}
@@ -0,0 +1 @@
@charset "UTF-8";[bsch-title]{position:relative}[bsch-title]:hover:after{opacity:1;transition:all .1s ease .5s;visibility:visible}[bsch-title]:after{content:attr(bsch-title);position:absolute;padding:5px 10px;bottom:-30px;left:100%;border-radius:4px;color:#fff;background-color:#504f4fcc;box-shadow:0 0 4px #00000029;font-size:14px;white-space:nowrap;visibility:hidden;opacity:0;z-index:2}
@@ -0,0 +1 @@
.my-table{width:100%;border-bottom:1px solid #c7c7c7;border-right:1px solid #c7c7c7;border-collapse:separate}.my-table .td-title{background:#fafafa;vertical-align:middle;color:#111;font-weight:550}.my-table th{background:#fafafa;height:20px;line-height:20px;padding:12px}.my-table td{height:20px;line-height:20px;padding:12px}.my-table th,.my-table td{border-top:1px solid #c7c7c7;border-left:1px solid #c7c7c7;margin-left:-1px;margin-top:-1px;text-align:center}
@@ -0,0 +1 @@
div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:"";content:none}table{border-collapse:collapse;border-spacing:0}
@@ -0,0 +1 @@
table.small-table{border:1px solid #ebeef5;border-radius:5px}table.small-table th{background-color:#fafafa;border-bottom:1px solid #ebeef5;padding:10px 20px}table.small-table td{padding:5px 20px}table.small-table tr:first-child td{padding-top:10px}table.small-table tr:last-child td{padding-bottom:10px}table.small-table .input-box{width:100px;vertical-align:text-bottom;display:inline-block}table.small-table .ivu-input-wrapper{vertical-align:text-bottom}
@@ -0,0 +1 @@
.stats-container{background:#fff;height:calc(100% - var(--appHeaderH));padding:16px 24px}.widget-ul{display:flex;flex-wrap:wrap;gap:12px;height:60px}.widget-ul li{width:140px;height:60px;padding:6px 16px;border-radius:4px;border:1px solid #ebeef5;background:#f6f8f9}.widget-ul .title{font-size:12px;font-style:normal;font-weight:400;line-height:24px;color:#333}.widget-ul .target{font-size:16px;font-style:normal;font-weight:700;line-height:24px;color:#333}.search-wrap{background:#f7f7f7;padding:10px 12px;height:52px}.search-wrap_sel{width:180px!important;float:left}

Some files were not shown because too many files have changed in this diff Show More