oa-approval-transfer-demo.html 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1" />
  6. <title>OA 审批 · 转交 Demo(Fresh Mint)</title>
  7. <style>
  8. :root {
  9. --primary: #10b981;
  10. --primary-dark: #059669;
  11. --primary-bg: #ecfdf5;
  12. --text: #0f172a;
  13. --text-2: #334155;
  14. --muted: #64748b;
  15. --border: #e2e8f0;
  16. --bg: #f1f5f9;
  17. --card: #fff;
  18. --warn: #d97706;
  19. --warn-bg: #fff7ed;
  20. --danger: #dc2626;
  21. --radius: 10px;
  22. }
  23. * { box-sizing: border-box; }
  24. body {
  25. margin: 0;
  26. min-height: 100vh;
  27. font: 14px/1.5 Inter, system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  28. color: var(--text);
  29. background: linear-gradient(180deg, #eefcf6 0%, var(--bg) 160px) fixed;
  30. }
  31. .page {
  32. max-width: 1080px;
  33. margin: 0 auto;
  34. padding: 24px 20px 80px;
  35. }
  36. .hero {
  37. margin-bottom: 16px;
  38. padding: 16px 18px;
  39. background: #fff;
  40. border: 1px solid var(--border);
  41. border-radius: var(--radius);
  42. }
  43. .hero h1 {
  44. margin: 0 0 6px;
  45. font-size: 18px;
  46. font-weight: 700;
  47. color: var(--primary-dark);
  48. }
  49. .hero p {
  50. margin: 0;
  51. color: var(--text-2);
  52. font-size: 13px;
  53. }
  54. .hero .hint {
  55. margin-top: 10px;
  56. padding: 8px 12px;
  57. background: #f8fafc;
  58. border: 1px dashed var(--border);
  59. border-radius: 8px;
  60. font-size: 12px;
  61. color: var(--muted);
  62. }
  63. .tabs {
  64. display: flex;
  65. flex-wrap: wrap;
  66. gap: 8px;
  67. margin-bottom: 16px;
  68. }
  69. .tab {
  70. border: 1px solid var(--border);
  71. background: #fff;
  72. border-radius: 8px;
  73. padding: 8px 14px;
  74. font: inherit;
  75. font-size: 13px;
  76. cursor: pointer;
  77. color: var(--text-2);
  78. }
  79. .tab:hover { border-color: #a7f3d0; }
  80. .tab.is-on {
  81. color: var(--primary-dark);
  82. background: var(--primary-bg);
  83. border-color: #a7f3d0;
  84. font-weight: 600;
  85. }
  86. .panel {
  87. background: var(--card);
  88. border: 1px solid var(--border);
  89. border-radius: var(--radius);
  90. padding: 16px 20px;
  91. margin-bottom: 16px;
  92. }
  93. .panel-top {
  94. display: flex;
  95. align-items: flex-start;
  96. justify-content: space-between;
  97. gap: 16px;
  98. flex-wrap: wrap;
  99. padding-bottom: 14px;
  100. border-bottom: 1px solid var(--border);
  101. margin-bottom: 16px;
  102. }
  103. .title-wrap {
  104. display: flex;
  105. align-items: center;
  106. gap: 10px;
  107. flex-wrap: wrap;
  108. }
  109. .btn {
  110. border: 1px solid var(--border);
  111. background: #fff;
  112. border-radius: 8px;
  113. padding: 7px 14px;
  114. cursor: pointer;
  115. font: inherit;
  116. font-size: 13px;
  117. display: inline-flex;
  118. align-items: center;
  119. gap: 6px;
  120. color: var(--text);
  121. height: 36px;
  122. }
  123. .btn:hover { border-color: #a7f3d0; background: #f8fafc; }
  124. .btn.primary {
  125. background: var(--primary);
  126. border-color: var(--primary);
  127. color: #fff;
  128. }
  129. .btn.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
  130. .btn.transfer {
  131. border-color: #93c5fd;
  132. color: #1d4ed8;
  133. background: #eff6ff;
  134. }
  135. .btn.transfer:hover { background: #dbeafe; }
  136. .btn:disabled { opacity: .45; cursor: not-allowed; }
  137. .actions { display: flex; flex-wrap: wrap; gap: 8px; }
  138. h2.title {
  139. margin: 0;
  140. font-size: 16px;
  141. font-weight: 600;
  142. display: flex;
  143. align-items: center;
  144. gap: 8px;
  145. }
  146. h2.title::before {
  147. content: "";
  148. width: 3px;
  149. height: 16px;
  150. background: var(--primary);
  151. border-radius: 2px;
  152. }
  153. .tag {
  154. display: inline-block;
  155. padding: 2px 8px;
  156. border-radius: 6px;
  157. font-size: 12px;
  158. background: var(--warn-bg);
  159. color: var(--warn);
  160. }
  161. .tag.ok { background: var(--primary-bg); color: var(--primary-dark); }
  162. .tag.info { background: #f1f5f9; color: var(--muted); }
  163. .tag.xfer { background: #eff6ff; color: #1d4ed8; }
  164. .section { margin-bottom: 20px; }
  165. .section h3 {
  166. margin: 0 0 10px;
  167. font-size: 14px;
  168. font-weight: 600;
  169. color: var(--text-2);
  170. }
  171. .form-view {
  172. display: grid;
  173. grid-template-columns: 1fr 1fr;
  174. gap: 12px 16px;
  175. padding: 12px;
  176. background: #f8fafc;
  177. border-radius: 8px;
  178. border: 1px solid var(--border);
  179. }
  180. .field label {
  181. display: block;
  182. font-size: 11px;
  183. color: var(--muted);
  184. margin-bottom: 4px;
  185. }
  186. .field .val {
  187. font-size: 14px;
  188. color: var(--text);
  189. min-height: 22px;
  190. }
  191. .field.span2 { grid-column: 1 / -1; }
  192. @media (max-width: 720px) {
  193. .form-view { grid-template-columns: 1fr; }
  194. }
  195. /* progress chain */
  196. .chain { display: flex; flex-direction: column; gap: 0; }
  197. .chain-item {
  198. display: grid;
  199. grid-template-columns: 28px 1fr;
  200. gap: 12px;
  201. position: relative;
  202. padding-bottom: 18px;
  203. }
  204. .chain-item:last-child { padding-bottom: 0; }
  205. .dot {
  206. width: 28px;
  207. height: 28px;
  208. border-radius: 50%;
  209. display: flex;
  210. align-items: center;
  211. justify-content: center;
  212. font-size: 12px;
  213. font-weight: 600;
  214. z-index: 1;
  215. background: var(--primary-bg);
  216. color: var(--primary-dark);
  217. border: 2px solid #a7f3d0;
  218. }
  219. .dot.pending { background: var(--warn-bg); color: var(--warn); border-color: #fdba74; }
  220. .dot.xfer { background: #eff6ff; color: #1d4ed8; border-color: #93c5fd; }
  221. .dot.done { background: var(--primary-bg); color: var(--primary-dark); }
  222. .dot.start { background: #f1f5f9; color: var(--muted); border-color: var(--border); }
  223. .chain-item::before {
  224. content: "";
  225. position: absolute;
  226. left: 13px;
  227. top: 28px;
  228. bottom: 0;
  229. width: 2px;
  230. background: var(--border);
  231. }
  232. .chain-item:last-child::before { display: none; }
  233. .card-body { min-width: 0; }
  234. .card-title {
  235. font-weight: 600;
  236. font-size: 14px;
  237. margin-bottom: 4px;
  238. display: flex;
  239. align-items: center;
  240. gap: 8px;
  241. flex-wrap: wrap;
  242. }
  243. .card-meta { font-size: 12px; color: var(--muted); }
  244. .card-lines {
  245. margin-top: 6px;
  246. font-size: 13px;
  247. color: var(--text-2);
  248. line-height: 1.55;
  249. }
  250. .card-lines .comment {
  251. margin-top: 4px;
  252. padding: 6px 8px;
  253. background: #f8fafc;
  254. border-radius: 6px;
  255. color: var(--muted);
  256. font-size: 12px;
  257. }
  258. /* modal */
  259. .mask {
  260. position: fixed;
  261. inset: 0;
  262. background: rgba(15, 23, 42, .45);
  263. display: none;
  264. align-items: center;
  265. justify-content: center;
  266. z-index: 50;
  267. padding: 16px;
  268. backdrop-filter: none;
  269. }
  270. .mask.open { display: flex; }
  271. .dialog {
  272. width: min(520px, 100%);
  273. background: #fff;
  274. border-radius: var(--radius);
  275. border: 1px solid var(--border);
  276. max-height: calc(100vh - 100px);
  277. display: flex;
  278. flex-direction: column;
  279. box-shadow: 0 20px 40px rgba(15, 23, 42, .12);
  280. }
  281. .dialog-hd {
  282. padding: 14px 18px;
  283. border-bottom: 1px solid var(--border);
  284. font-weight: 600;
  285. font-size: 15px;
  286. }
  287. .dialog-bd {
  288. padding: 16px 18px;
  289. overflow: auto;
  290. }
  291. .dialog-ft {
  292. padding: 12px 18px;
  293. border-top: 1px solid var(--border);
  294. display: flex;
  295. justify-content: flex-end;
  296. gap: 8px;
  297. }
  298. .form-item { margin-bottom: 14px; }
  299. .form-item:last-child { margin-bottom: 0; }
  300. .form-item > label {
  301. display: block;
  302. font-size: 12px;
  303. color: var(--muted);
  304. margin-bottom: 6px;
  305. }
  306. .form-item .req { color: var(--danger); margin-left: 2px; }
  307. select, textarea, input[type="text"] {
  308. width: 100%;
  309. border: 1px solid var(--border);
  310. border-radius: 8px;
  311. padding: 8px 10px;
  312. font: inherit;
  313. height: 36px;
  314. background: #fff;
  315. }
  316. textarea { height: auto; min-height: 72px; resize: vertical; }
  317. select:focus, textarea:focus, input:focus {
  318. outline: none;
  319. border-color: var(--primary);
  320. box-shadow: 0 0 0 3px rgba(16, 185, 129, .15);
  321. }
  322. .note {
  323. font-size: 12px;
  324. color: var(--muted);
  325. margin-top: 6px;
  326. }
  327. .toast {
  328. position: fixed;
  329. top: 24px;
  330. left: 50%;
  331. transform: translateX(-50%) translateY(-12px);
  332. background: #0f172a;
  333. color: #fff;
  334. padding: 10px 16px;
  335. border-radius: 8px;
  336. font-size: 13px;
  337. opacity: 0;
  338. pointer-events: none;
  339. transition: .2s ease;
  340. z-index: 60;
  341. }
  342. .toast.show {
  343. opacity: 1;
  344. transform: translateX(-50%) translateY(0);
  345. }
  346. .compare {
  347. display: grid;
  348. grid-template-columns: 1fr 1fr;
  349. gap: 12px;
  350. }
  351. @media (max-width: 800px) {
  352. .compare { grid-template-columns: 1fr; }
  353. }
  354. .mini-card {
  355. border: 1px solid var(--border);
  356. border-radius: 8px;
  357. padding: 12px;
  358. background: #f8fafc;
  359. }
  360. .mini-card h4 {
  361. margin: 0 0 8px;
  362. font-size: 13px;
  363. color: var(--primary-dark);
  364. }
  365. .mini-card ul {
  366. margin: 0;
  367. padding-left: 18px;
  368. font-size: 12px;
  369. color: var(--text-2);
  370. line-height: 1.7;
  371. }
  372. .highlight-btn {
  373. outline: 2px solid #3b82f6;
  374. outline-offset: 2px;
  375. animation: pulse 1.4s ease-in-out infinite;
  376. }
  377. @keyframes pulse {
  378. 0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, .35); }
  379. 50% { box-shadow: 0 0 0 6px rgba(59, 130, 246, 0); }
  380. }
  381. .view { display: none; }
  382. .view.is-on { display: block; }
  383. </style>
  384. </head>
  385. <body>
  386. <div class="page">
  387. <div class="hero">
  388. <h1>OA 审批 ·【转交】交互 Demo</h1>
  389. <p>在现有「同意 / 拒绝 / 打回 / 加签」旁增加「转交」。本页演示审批详情顶栏、转交弹窗与转交后进度展示。</p>
  390. <div class="hint">
  391. 已定语义:转交 = 将<strong>本人当前待办</strong>交给另一人处理;转交后本人不再持有该待办;进度记录「已转交」。
  392. 与加签区别:加签是<strong>新增</strong>审批人,本人待办仍在。说明可选;无应用开关;可选租户内用户(排除本人与本节点已有待办)。
  393. </div>
  394. </div>
  395. <div class="tabs" role="tablist">
  396. <button class="tab is-on" data-tab="detail" type="button">1. 详情顶栏(含转交)</button>
  397. <button class="tab" data-tab="dialog" type="button">2. 转交弹窗</button>
  398. <button class="tab" data-tab="after" type="button">3. 转交后进度</button>
  399. <button class="tab" data-tab="diff" type="button">4. 与加签对比</button>
  400. </div>
  401. <!-- View 1: detail -->
  402. <div class="view is-on" id="view-detail">
  403. <section class="panel">
  404. <div class="panel-top">
  405. <div class="title-wrap">
  406. <button class="btn" type="button" disabled>← 返回</button>
  407. <h2 class="title">差旅报销 · 张三 · 2026-07-23</h2>
  408. <span class="tag">审批中</span>
  409. </div>
  410. <div class="actions">
  411. <button class="btn primary" type="button">✓ 同意</button>
  412. <button class="btn" type="button">✕ 拒绝</button>
  413. <button class="btn" type="button">↺ 打回</button>
  414. <button class="btn" type="button">+ 加签</button>
  415. <button class="btn transfer highlight-btn" type="button" id="btn-open-transfer">↗ 转交</button>
  416. </div>
  417. </div>
  418. <div class="section">
  419. <h3>表单内容</h3>
  420. <div class="form-view">
  421. <div class="field">
  422. <label>申请人</label>
  423. <div class="val">张三</div>
  424. </div>
  425. <div class="field">
  426. <label>部门</label>
  427. <div class="val">研发中心 / 平台组</div>
  428. </div>
  429. <div class="field">
  430. <label>报销金额</label>
  431. <div class="val">¥ 2,860.00</div>
  432. </div>
  433. <div class="field">
  434. <label>出差城市</label>
  435. <div class="val">合肥</div>
  436. </div>
  437. <div class="field span2">
  438. <label>事由</label>
  439. <div class="val">客户现场实施与验收</div>
  440. </div>
  441. </div>
  442. </div>
  443. <div class="section">
  444. <h3>审批进度</h3>
  445. <div class="chain" id="chain-before">
  446. <div class="chain-item">
  447. <div class="dot start">起</div>
  448. <div class="card-body">
  449. <div class="card-title">提交 <span class="tag ok">已提交</span></div>
  450. <div class="card-meta">张三 · 07-23 09:12</div>
  451. </div>
  452. </div>
  453. <div class="chain-item">
  454. <div class="dot pending">审</div>
  455. <div class="card-body">
  456. <div class="card-title">部门负责人 <span class="tag">审批中</span></div>
  457. <div class="card-meta">当前处理人:李四</div>
  458. <div class="card-lines">李四 · 待处理</div>
  459. </div>
  460. </div>
  461. <div class="chain-item">
  462. <div class="dot start">审</div>
  463. <div class="card-body">
  464. <div class="card-title">财务复核 <span class="tag info">未到达</span></div>
  465. <div class="card-meta">王五</div>
  466. </div>
  467. </div>
  468. </div>
  469. </div>
  470. </section>
  471. </div>
  472. <!-- View 2: dialog focus -->
  473. <div class="view" id="view-dialog">
  474. <section class="panel">
  475. <div class="panel-top">
  476. <div class="title-wrap">
  477. <h2 class="title">转交弹窗示意</h2>
  478. <span class="tag xfer">交互稿</span>
  479. </div>
  480. <div class="actions">
  481. <button class="btn transfer" type="button" id="btn-open-transfer-2">打开转交弹窗</button>
  482. </div>
  483. </div>
  484. <p style="margin:0 0 12px;color:var(--text-2);font-size:13px;">
  485. 字段对齐现有「加签」弹窗:选择用户 + 说明。差异点:转交人为<strong>单选</strong>(一人接手),说明<strong>可选</strong>。
  486. </p>
  487. <div class="compare">
  488. <div class="mini-card">
  489. <h4>字段</h4>
  490. <ul>
  491. <li>转交给(必填,单选用户)</li>
  492. <li>转交说明(可选)</li>
  493. <li>不可选:自己、已在本节点待办中的人</li>
  494. </ul>
  495. </div>
  496. <div class="mini-card">
  497. <h4>提交后效果</h4>
  498. <ul>
  499. <li>本人待办关闭为「已转交」</li>
  500. <li>目标人新增同节点 pending 待办</li>
  501. <li>进度展示「李四 已转交 …」+「赵六 待处理」</li>
  502. <li>无应用开关;全应用可转交;允许再转交</li>
  503. </ul>
  504. </div>
  505. </div>
  506. </section>
  507. </div>
  508. <!-- View 3: after transfer -->
  509. <div class="view" id="view-after">
  510. <section class="panel">
  511. <div class="panel-top">
  512. <div class="title-wrap">
  513. <button class="btn" type="button" disabled>← 返回</button>
  514. <h2 class="title">差旅报销 · 张三 · 2026-07-23</h2>
  515. <span class="tag">审批中</span>
  516. </div>
  517. <div class="actions">
  518. <span class="note" style="align-self:center;">李四已转交,本人操作区消失(非当前处理人)</span>
  519. </div>
  520. </div>
  521. <div class="section">
  522. <h3>审批进度(转交后)</h3>
  523. <div class="chain">
  524. <div class="chain-item">
  525. <div class="dot start">起</div>
  526. <div class="card-body">
  527. <div class="card-title">提交 <span class="tag ok">已提交</span></div>
  528. <div class="card-meta">张三 · 07-23 09:12</div>
  529. </div>
  530. </div>
  531. <div class="chain-item">
  532. <div class="dot pending">审</div>
  533. <div class="card-body">
  534. <div class="card-title">部门负责人 <span class="tag">审批中</span></div>
  535. <div class="card-meta">当前处理人:赵六</div>
  536. <div class="card-lines">
  537. 李四 · 已转交 · 07-23 10:05
  538. <div class="comment">转交说明:出差中,请赵六代为审批</div>
  539. 赵六 · 待处理
  540. </div>
  541. </div>
  542. </div>
  543. <div class="chain-item">
  544. <div class="dot start">审</div>
  545. <div class="card-body">
  546. <div class="card-title">财务复核 <span class="tag info">未到达</span></div>
  547. <div class="card-meta">王五</div>
  548. </div>
  549. </div>
  550. </div>
  551. </div>
  552. </section>
  553. </div>
  554. <!-- View 4: diff -->
  555. <div class="view" id="view-diff">
  556. <section class="panel">
  557. <div class="panel-top">
  558. <div class="title-wrap">
  559. <h2 class="title">转交 vs 加签</h2>
  560. </div>
  561. </div>
  562. <div class="compare">
  563. <div class="mini-card">
  564. <h4>转交</h4>
  565. <ul>
  566. <li>替换处理人:A → B</li>
  567. <li>A 待办结束(已转交)</li>
  568. <li>通常单选一人</li>
  569. <li>不改变节点人数语义(仍是「谁来批」)</li>
  570. <li>适合:请假/出差临时交接</li>
  571. </ul>
  572. </div>
  573. <div class="mini-card">
  574. <h4>加签</h4>
  575. <ul>
  576. <li>追加处理人:A + B(+C…)</li>
  577. <li>A 待办仍在</li>
  578. <li>可多选</li>
  579. <li>影响或签/会签收口</li>
  580. <li>适合:需要他人共同意见</li>
  581. </ul>
  582. </div>
  583. </div>
  584. </section>
  585. </div>
  586. </div>
  587. <!-- Transfer dialog -->
  588. <div class="mask" id="transfer-mask" aria-hidden="true">
  589. <div class="dialog" role="dialog" aria-labelledby="xfer-title">
  590. <div class="dialog-hd" id="xfer-title">转交</div>
  591. <div class="dialog-bd">
  592. <div class="form-item">
  593. <label>转交给<span class="req">*</span></label>
  594. <select id="xfer-user">
  595. <option value="">请选择用户</option>
  596. <option value="u6">赵六(zhaoliu)</option>
  597. <option value="u7">钱七(qianqi)</option>
  598. <option value="u8">孙八(sunba)</option>
  599. </select>
  600. <div class="note">不可选本人,以及本节点已有待办的用户。</div>
  601. </div>
  602. <div class="form-item">
  603. <label>转交说明(可选)</label>
  604. <textarea id="xfer-comment" placeholder="可填写转交原因,便于追溯"></textarea>
  605. </div>
  606. </div>
  607. <div class="dialog-ft">
  608. <button class="btn" type="button" id="btn-cancel-xfer">✕ 取消</button>
  609. <button class="btn primary" type="button" id="btn-confirm-xfer">✓ 确定转交</button>
  610. </div>
  611. </div>
  612. </div>
  613. <div class="toast" id="toast"></div>
  614. <script>
  615. (function () {
  616. var tabs = document.querySelectorAll('.tab')
  617. var views = {
  618. detail: document.getElementById('view-detail'),
  619. dialog: document.getElementById('view-dialog'),
  620. after: document.getElementById('view-after'),
  621. diff: document.getElementById('view-diff')
  622. }
  623. tabs.forEach(function (tab) {
  624. tab.addEventListener('click', function () {
  625. tabs.forEach(function (t) { t.classList.remove('is-on') })
  626. tab.classList.add('is-on')
  627. Object.keys(views).forEach(function (k) {
  628. views[k].classList.toggle('is-on', k === tab.dataset.tab)
  629. })
  630. })
  631. })
  632. var mask = document.getElementById('transfer-mask')
  633. var toast = document.getElementById('toast')
  634. function openMask() {
  635. mask.classList.add('open')
  636. mask.setAttribute('aria-hidden', 'false')
  637. }
  638. function closeMask() {
  639. mask.classList.remove('open')
  640. mask.setAttribute('aria-hidden', 'true')
  641. }
  642. function showToast(msg) {
  643. toast.textContent = msg
  644. toast.classList.add('show')
  645. setTimeout(function () { toast.classList.remove('show') }, 1800)
  646. }
  647. document.getElementById('btn-open-transfer').addEventListener('click', openMask)
  648. document.getElementById('btn-open-transfer-2').addEventListener('click', openMask)
  649. document.getElementById('btn-cancel-xfer').addEventListener('click', closeMask)
  650. mask.addEventListener('click', function (e) {
  651. if (e.target === mask) closeMask()
  652. })
  653. document.getElementById('btn-confirm-xfer').addEventListener('click', function () {
  654. var uid = document.getElementById('xfer-user').value
  655. var comment = (document.getElementById('xfer-comment').value || '').trim()
  656. if (!uid) {
  657. showToast('请选择转交人')
  658. return
  659. }
  660. closeMask()
  661. showToast(comment ? '已转交' : '已转交(无说明)')
  662. // jump to after view
  663. tabs.forEach(function (t) {
  664. t.classList.toggle('is-on', t.dataset.tab === 'after')
  665. })
  666. Object.keys(views).forEach(function (k) {
  667. views[k].classList.toggle('is-on', k === 'after')
  668. })
  669. })
  670. })()
  671. </script>
  672. </body>
  673. </html>