You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

981 lines
20 KiB

  1. <template>
  2. <div class="pda-container">
  3. <!-- 头部栏 -->
  4. <div class="header-bar">
  5. <div class="header-left" @click="$router.back()">
  6. <i class="el-icon-arrow-left"></i>
  7. <span>生产订单入库</span>
  8. </div>
  9. <div class="header-right" @click="$router.push({ path: '/' })">
  10. 首页
  11. </div>
  12. </div>
  13. <!-- 搜索框 -->
  14. <div class="search-container">
  15. <el-input clearable class="compact-input"
  16. v-model="scanCode"
  17. placeholder="请扫描箱二维码"
  18. prefix-icon="el-icon-search"
  19. @keyup.enter.native="handleScan"
  20. ref="scanInput"
  21. />
  22. <div class="mode-switch">
  23. <el-switch
  24. class="custom-switch"
  25. v-model="isRemoveMode"
  26. active-color="#ff4949"
  27. inactive-color="#13ce66">
  28. </el-switch>
  29. <span v-if="isRemoveMode" class="switch-text">{{ '移除' }}</span>
  30. <span v-else class="switch-text2">{{ '添加' }}</span>
  31. </div>
  32. </div>
  33. <!-- 入库申请单信息卡片 -->
  34. <div class="material-info-card" v-if="inboundInfo.inboundNo">
  35. <div class="card-title">
  36. <span class="title-label">入库申请单号</span>
  37. <span class="title-value">{{ inboundInfo.inboundNo }}</span>
  38. </div>
  39. <div class="card-details">
  40. <div class="detail-item">
  41. <div class="detail-label">关联单号</div>
  42. <div class="detail-value">{{ inboundInfo.relatedNo }}</div>
  43. </div>
  44. <div class="detail-item">
  45. <div class="detail-label">标签张数</div>
  46. <div class="detail-value">
  47. <span class="qualified">{{ inboundInfo.createdLabels }}</span><span class="total">{{ inboundInfo.totalLabels }}</span>
  48. </div>
  49. </div>
  50. <div class="detail-item">
  51. <div class="detail-label">物料总数</div>
  52. <div class="detail-value">
  53. <span class="qualified">{{ inboundInfo.inboundQty }}</span><span class="total">{{ inboundInfo.totalQty }}</span>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. <!-- 入库信息确认标题 -->
  59. <div class="section-title">
  60. <div class="title-left">
  61. <i class="el-icon-circle-check"></i>
  62. <span>入库信息确认</span>
  63. </div>
  64. <div class="title-right">
  65. <span class="material-list-link" @click="showMaterialListDialog">物料清单</span>
  66. </div>
  67. </div>
  68. <!-- 标签列表 -->
  69. <div class="label-list">
  70. <div class="list-header">
  71. <div class="col-no">NO.</div>
  72. <div class="col-label">标签条码</div>
  73. <div class="col-part">物料编码</div>
  74. <div class="col-unit">单位</div>
  75. <div class="col-qty">标签数量</div>
  76. </div>
  77. <div
  78. v-for="(label, index) in labelList"
  79. :key="label.id"
  80. class="list-item"
  81. >
  82. <div class="col-no">{{ labelList.length - index }}</div>
  83. <div class="col-label">{{ label.labelCode }}</div>
  84. <div class="col-part">{{ label.partNo }}</div>
  85. <div class="col-unit">{{ label.unit || '个' }}</div>
  86. <div class="col-qty">{{ label.quantity }}</div>
  87. </div>
  88. <!-- 空状态 -->
  89. <div v-if="labelList.length === 0" class="empty-labels">
  90. <p>暂无扫描标签</p>
  91. </div>
  92. </div>
  93. <!-- 底部操作按钮 -->
  94. <div class="bottom-actions">
  95. <button class="action-btn secondary" @click="confirmInbound">
  96. 确定
  97. </button>
  98. <button class="action-btn secondary" style="margin-left: 10px;" @click="printLabels">
  99. 打印
  100. </button>
  101. <button class="action-btn secondary" style="margin-left: 10px;" @click="cancelInbound">
  102. 取消
  103. </button>
  104. </div>
  105. <!-- 物料清单弹窗 -->
  106. <div v-if="showMaterialDialog" class="material-overlay">
  107. <div class="material-modal">
  108. <div class="modal-header">
  109. <span class="modal-title">物料清单</span>
  110. <i class="el-icon-close close-btn" @click="closeMaterialDialog"></i>
  111. </div>
  112. <div class="modal-body">
  113. <!-- 加载状态 -->
  114. <div v-if="materialListLoading" class="loading-container">
  115. <i class="el-icon-loading"></i>
  116. <span>加载中...</span>
  117. </div>
  118. <!-- 物料表格 -->
  119. <div v-else-if="materialList.length > 0" class="material-table">
  120. <div class="table-header">
  121. <div class="col-no">NO.</div>
  122. <div class="col-material-code">物料编码</div>
  123. <div class="col-required-qty">需求数量</div>
  124. <div class="col-inbound-qty">已入库数量</div>
  125. </div>
  126. <div class="table-body">
  127. <div
  128. v-for="(item, index) in materialList"
  129. :key="index"
  130. class="table-row"
  131. >
  132. <div class="col-no">{{ index + 1 }}</div>
  133. <div class="col-material-code">{{ item.materialCode || item.partNo }}</div>
  134. <div class="col-required-qty">{{ item.requiredQty || 0 }}</div>
  135. <div class="col-inbound-qty">{{ item.inboundQty || 0 }}</div>
  136. </div>
  137. </div>
  138. </div>
  139. <!-- 空数据状态 -->
  140. <div v-else class="empty-material">
  141. <i class="el-icon-document"></i>
  142. <p>暂无物料数据</p>
  143. </div>
  144. </div>
  145. <div class="modal-footer">
  146. <button class="btn-close" @click="closeMaterialDialog">关闭</button>
  147. </div>
  148. </div>
  149. </div>
  150. </div>
  151. </template>
  152. <script>
  153. import { scanMaterialLabel, getRequestMaterials } from '@/api/production/production-inbound';
  154. import moment from 'moment';
  155. export default {
  156. data() {
  157. return {
  158. scanCode: '',
  159. inboundInfo: {},
  160. labelList: [],
  161. inboundNo: '',
  162. buNo: '',
  163. showMaterialDialog: false,
  164. materialList: [],
  165. materialListLoading: false,
  166. isRemoveMode: false // 默认为添加模式
  167. };
  168. },
  169. methods: {
  170. formatDate(date) {
  171. return date ? moment(date).format('YYYY-MM-DD') : '';
  172. },
  173. // 处理扫描
  174. handleScan() {
  175. if (!this.scanCode.trim()) {
  176. return;
  177. }
  178. if (this.isRemoveMode) {
  179. this.removeLabelByCode(this.scanCode.trim());
  180. } else {
  181. this.validateAndAddLabel(this.scanCode.trim());
  182. }
  183. this.scanCode = '';
  184. },
  185. // 验证标签并添加到列表
  186. validateAndAddLabel(labelCode) {
  187. const params = {
  188. labelCode: labelCode,
  189. notifyNo: this.inboundNo,
  190. site: this.$store.state.user.site,
  191. };
  192. scanMaterialLabel(params).then(({ data }) => {
  193. if (data && data.code === 0) {
  194. // 检查是否已经扫描过
  195. const exists = this.labelList.find(item => item.labelCode === labelCode);
  196. if (exists) {
  197. this.$message.warning('该标签已扫描,请勿重复扫描');
  198. return;
  199. }
  200. // 添加到列表
  201. this.labelList.push({
  202. id: Date.now(),
  203. labelCode: labelCode,
  204. partNo: data.labelInfo.partNo,
  205. quantity: data.labelInfo.quantity,
  206. unit: data.labelInfo.unit,
  207. batchNo: data.labelInfo.batchNo
  208. });
  209. this.$message.success('操作成功');
  210. } else {
  211. this.$message.error(data.msg || '该标签与入库申请单不符,请检查');
  212. }
  213. }).catch(error => {
  214. this.$message.error('操作失败');
  215. });
  216. },
  217. // 通过条码移除标签
  218. removeLabelByCode(labelCode) {
  219. const index = this.labelList.findIndex(item => item.labelCode === labelCode);
  220. if (index !== -1) {
  221. this.labelList.splice(index, 1);
  222. this.$message.success('操作成功');
  223. } else {
  224. this.$message.warning('未找到该标签');
  225. }
  226. },
  227. // 确认入库
  228. confirmInbound() {
  229. if (this.labelList.length === 0) {
  230. this.$message.warning('请先扫描标签');
  231. return;
  232. }
  233. const params = {
  234. site: this.inboundInfo.site,
  235. inboundNo: this.inboundNo,
  236. labels: this.labelList.map(label => ({
  237. labelCode: label.labelCode,
  238. quantity: label.quantity,
  239. batchNo: label.batchNo,
  240. partNo: label.partNo
  241. }))
  242. };
  243. confirmProductionInbound(params).then(({ data }) => {
  244. if (data && data.code === 0) {
  245. this.$message.success('操作成功');
  246. this.$router.back();
  247. } else {
  248. this.$message.error(data.msg || '操作失败');
  249. }
  250. }).catch(error => {
  251. console.error('入库确认失败:', error);
  252. this.$message.error('操作失败');
  253. });
  254. },
  255. // 打印标签
  256. printLabels() {
  257. if (this.labelList.length === 0) {
  258. this.$message.warning('暂无标签可打印');
  259. return;
  260. }
  261. this.$message.warning('打印功能开发中...');
  262. },
  263. // 取消入库
  264. cancelInbound() {
  265. if (this.labelList.length > 0) {
  266. this.$confirm('取消后将清空已扫描的标签,确定取消吗?', '提示', {
  267. confirmButtonText: '确定',
  268. cancelButtonText: '继续操作',
  269. type: 'warning'
  270. }).then(() => {
  271. this.$router.back();
  272. }).catch(() => {
  273. // 用户选择继续操作
  274. });
  275. } else {
  276. this.$router.back();
  277. }
  278. },
  279. // 显示物料清单弹窗
  280. showMaterialListDialog() {
  281. this.showMaterialDialog = true;
  282. this.loadMaterialList();
  283. },
  284. // 加载物料清单
  285. loadMaterialList() {
  286. console.log('加载物料清单', this.inboundInfo, this.inboundNo);
  287. if (!this.$store.state.user.site || !this.inboundNo) {
  288. this.$message.error('缺少必要参数,无法获取物料清单');
  289. return;
  290. }
  291. this.materialListLoading = true;
  292. const params = {
  293. site: this.$store.state.user.site,
  294. inboundNo: this.inboundNo
  295. };
  296. getRequestMaterials(params).then(({ data }) => {
  297. this.materialListLoading = false;
  298. if (data && data.code === 0) {
  299. this.materialList = data.materials || [];
  300. } else {
  301. this.$message.error(data.msg || '获取物料清单失败');
  302. this.materialList = [];
  303. }
  304. }).catch(error => {
  305. this.materialListLoading = false;
  306. this.$message.error('获取物料清单失败');
  307. this.materialList = [];
  308. });
  309. },
  310. // 关闭物料清单弹窗
  311. closeMaterialDialog() {
  312. this.showMaterialDialog = false;
  313. },
  314. // 加载入库申请单详情
  315. loadInboundDetails() {
  316. const params = {
  317. inboundNo: this.inboundNo,
  318. site: this.$store.state.user.site,
  319. };
  320. console.log('加载入库申请单详情参数:', params);
  321. /* getInboundDetails(params).then(({ data }) => {
  322. if (data && data.code === 0) {
  323. this.inboundInfo = data.data;
  324. } else {
  325. this.$message.error(data.msg || '获取入库申请单详情失败');
  326. }
  327. }).catch(error => {
  328. console.error('获取入库申请单详情失败:', error);
  329. this.$message.error('获取入库申请单详情失败');
  330. }); */
  331. }
  332. },
  333. mounted() {
  334. // 获取路由参数
  335. this.inboundNo = this.$route.params.inboundNo;
  336. console.log("入库申请单号:", this.inboundNo);
  337. if (!this.inboundNo) {
  338. this.$message.error('参数错误');
  339. this.$router.back();
  340. return;
  341. }
  342. // 聚焦扫描框
  343. this.$nextTick(() => {
  344. if (this.$refs.scanInput) {
  345. this.$refs.scanInput.focus();
  346. }
  347. });
  348. // 加载入库申请单详情
  349. this.loadInboundDetails();
  350. }
  351. };
  352. </script>
  353. <style scoped>
  354. /* 复用生产领料页面的样式,只修改必要的部分 */
  355. .pda-container {
  356. width: 100vw;
  357. height: 100vh;
  358. display: flex;
  359. flex-direction: column;
  360. background: #f5f5f5;
  361. }
  362. /* 头部栏 */
  363. .header-bar {
  364. display: flex;
  365. justify-content: space-between;
  366. align-items: center;
  367. padding: 8px 16px;
  368. background: #17B3A3;
  369. color: white;
  370. height: 40px;
  371. min-height: 40px;
  372. }
  373. .header-left {
  374. display: flex;
  375. align-items: center;
  376. cursor: pointer;
  377. font-size: 16px;
  378. font-weight: 500;
  379. }
  380. .header-left i {
  381. margin-right: 8px;
  382. font-size: 18px;
  383. }
  384. .header-right {
  385. cursor: pointer;
  386. font-size: 16px;
  387. font-weight: 500;
  388. }
  389. /* 搜索容器 */
  390. .search-container {
  391. padding: 12px 16px;
  392. background: white;
  393. display: flex;
  394. align-items: center;
  395. gap: 12px;
  396. }
  397. .search-container .el-input {
  398. width: 240px;
  399. margin-right: 12px;
  400. }
  401. /* 紧凑型输入框样式 */
  402. .compact-input ::v-deep .el-input__inner {
  403. height: 36px;
  404. padding: 0 12px 0 35px;
  405. font-size: 14px;
  406. }
  407. .compact-input ::v-deep .el-input__prefix {
  408. left: 10px;
  409. }
  410. .compact-input ::v-deep .el-input__suffix {
  411. right: 30px;
  412. }
  413. /* 模式切换开关 */
  414. .mode-switch {
  415. position: relative;
  416. display: inline-block;
  417. }
  418. .custom-switch {
  419. transform: scale(1.3);
  420. }
  421. /* 中间文字 */
  422. .switch-text {
  423. position: absolute;
  424. left: 25%;
  425. transform: translateX(-50%);
  426. top: 50%;
  427. transform: translateY(-50%) translateX(-50%);
  428. font-size: 12px;
  429. font-weight: 500;
  430. color: #606266;
  431. white-space: nowrap;
  432. pointer-events: none;
  433. z-index: 1;
  434. top: 53%;
  435. transform: translate(-50%, -50%);
  436. font-size: 12px;
  437. font-weight: bold;
  438. color: white;
  439. pointer-events: none;
  440. z-index: 2;
  441. }
  442. .switch-text2 {
  443. position: absolute;
  444. left: 75%;
  445. transform: translateX(-50%);
  446. top: 50%;
  447. transform: translateY(-50%) translateX(-50%);
  448. font-size: 12px;
  449. font-weight: 500;
  450. color: #606266;
  451. white-space: nowrap;
  452. pointer-events: none;
  453. z-index: 1;
  454. top: 53%;
  455. transform: translate(-50%, -50%);
  456. font-size: 12px;
  457. font-weight: bold;
  458. color: white;
  459. pointer-events: none;
  460. z-index: 2;
  461. }
  462. /* 调整 switch 尺寸以便容纳文字 */
  463. .custom-switch ::v-deep .el-switch__core {
  464. width: 60px;
  465. height: 28px;
  466. }
  467. /* 物料信息卡片 */
  468. .material-info-card {
  469. background: white;
  470. margin: 4px 16px;
  471. padding: 6px 20px;
  472. border-radius: 8px;
  473. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  474. border: 1px solid #f0f0f0;
  475. }
  476. .card-title {
  477. margin-bottom: 16px;
  478. }
  479. .title-label {
  480. font-size: 11px;
  481. color: #999;
  482. display: block;
  483. margin-bottom: 6px;
  484. font-weight: normal;
  485. }
  486. .title-value {
  487. font-size: 18px;
  488. font-weight: bold;
  489. color: #333;
  490. line-height: 1.2;
  491. margin-left: 20px;
  492. }
  493. .card-details {
  494. display: flex;
  495. justify-content: space-between;
  496. align-items: flex-start;
  497. gap: 4px;
  498. }
  499. .detail-item {
  500. flex: 1;
  501. text-align: center;
  502. min-width: 60px;
  503. max-width: 60px;
  504. }
  505. .detail-label {
  506. font-size: 11px;
  507. color: #999;
  508. margin-bottom: 6px;
  509. font-weight: normal;
  510. line-height: 1.2;
  511. margin-left: -12px;
  512. }
  513. .detail-value {
  514. font-size: 13px;
  515. color: #333;
  516. font-weight: 500;
  517. line-height: 1.2;
  518. margin-left: -12px;
  519. }
  520. .detail-value .qualified {
  521. color: #17B3A3;
  522. font-weight: 500;
  523. }
  524. .detail-value .total {
  525. color: #333;
  526. font-weight: 500;
  527. }
  528. .detail-value .total::before {
  529. content: '/';
  530. color: #333;
  531. }
  532. /* 区域标题 */
  533. .section-title {
  534. display: flex;
  535. align-items: center;
  536. justify-content: space-between;
  537. padding: 6px 8px;
  538. background: white;
  539. margin: 0 16px;
  540. margin-top: 4px;
  541. border-radius: 8px 8px 0 0;
  542. border-bottom: 2px solid #17B3A3;
  543. }
  544. .title-left {
  545. display: flex;
  546. align-items: center;
  547. }
  548. .title-left i {
  549. color: #17B3A3;
  550. font-size: 16px;
  551. margin-right: 8px;
  552. }
  553. .title-left span {
  554. color: #17B3A3;
  555. font-size: 14px;
  556. font-weight: 500;
  557. }
  558. .title-right {
  559. display: flex;
  560. align-items: center;
  561. }
  562. .material-list-link {
  563. color: #17B3A3;
  564. font-size: 14px;
  565. font-weight: 500;
  566. cursor: pointer;
  567. text-decoration: underline;
  568. transition: color 0.2s ease;
  569. }
  570. .material-list-link:hover {
  571. color: #0d8f7f;
  572. }
  573. /* 标签列表 */
  574. .label-list {
  575. background: white;
  576. margin: 0 16px 12px;
  577. border-radius: 0 0 8px 8px;
  578. overflow: hidden;
  579. }
  580. .list-header {
  581. display: flex;
  582. background: #f8f9fa;
  583. padding: 12px 8px;
  584. border-bottom: 1px solid #e0e0e0;
  585. font-size: 12px;
  586. color: #666;
  587. font-weight: 500;
  588. }
  589. .list-item {
  590. display: flex;
  591. padding: 12px 8px;
  592. border-bottom: 1px solid #f0f0f0;
  593. font-size: 12px;
  594. color: #333;
  595. }
  596. .list-item:last-child {
  597. border-bottom: none;
  598. }
  599. .col-no {
  600. width: 20px;
  601. text-align: center;
  602. }
  603. .col-label {
  604. flex: 2;
  605. text-align: center;
  606. }
  607. .col-part {
  608. flex: 2;
  609. text-align: center;
  610. }
  611. .col-unit {
  612. width: 40px;
  613. text-align: center;
  614. }
  615. .col-qty {
  616. width: 60px;
  617. text-align: center;
  618. }
  619. .empty-labels {
  620. padding: 40px 20px;
  621. text-align: center;
  622. color: #999;
  623. }
  624. .empty-labels p {
  625. margin: 0;
  626. font-size: 14px;
  627. }
  628. /* 底部操作按钮 */
  629. .bottom-actions {
  630. display: flex;
  631. padding: 16px;
  632. gap: 20px;
  633. background: white;
  634. margin-top: auto;
  635. }
  636. .action-btn {
  637. flex: 1;
  638. padding: 12px;
  639. border: 1px solid #17B3A3;
  640. background: white;
  641. color: #17B3A3;
  642. border-radius: 20px;
  643. font-size: 14px;
  644. cursor: pointer;
  645. transition: all 0.2s ease;
  646. }
  647. .action-btn:hover {
  648. background: #17B3A3;
  649. color: white;
  650. }
  651. .action-btn:active {
  652. transform: scale(0.98);
  653. }
  654. /* 物料清单弹窗样式 */
  655. .material-overlay {
  656. position: fixed;
  657. top: 0;
  658. left: 0;
  659. right: 0;
  660. bottom: 0;
  661. background: rgba(0, 0, 0, 0.5);
  662. z-index: 9999;
  663. display: flex;
  664. align-items: center;
  665. justify-content: center;
  666. padding: 20px;
  667. }
  668. .material-modal {
  669. background: white;
  670. border-radius: 12px;
  671. width: 100%;
  672. max-width: 800px;
  673. max-height: 80vh;
  674. box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  675. overflow: hidden;
  676. display: flex;
  677. flex-direction: column;
  678. }
  679. .material-modal .modal-header {
  680. background: #17B3A3;
  681. color: white;
  682. padding: 5px 16px;
  683. display: flex;
  684. justify-content: space-between;
  685. align-items: center;
  686. min-height: 28px;
  687. }
  688. .close-btn {
  689. font-size: 16px;
  690. cursor: pointer;
  691. color: white;
  692. transition: color 0.2s ease;
  693. padding: 4px;
  694. display: flex;
  695. align-items: center;
  696. justify-content: center;
  697. }
  698. .close-btn:hover {
  699. color: #e0e0e0;
  700. }
  701. .material-modal .modal-title {
  702. font-size: 16px;
  703. font-weight: 500;
  704. margin: 0;
  705. line-height: 1.2;
  706. }
  707. .material-modal .modal-body {
  708. flex: 1;
  709. overflow: auto;
  710. padding: 0;
  711. }
  712. .material-table {
  713. width: 100%;
  714. }
  715. .table-header {
  716. display: flex;
  717. background: #f8f9fa;
  718. padding: 10px 6px;
  719. border-bottom: 2px solid #17B3A3;
  720. font-size: 12px;
  721. color: #333;
  722. font-weight: 600;
  723. position: sticky;
  724. top: 0;
  725. z-index: 1;
  726. }
  727. .table-body {
  728. max-height: 400px;
  729. overflow-y: auto;
  730. }
  731. .table-row {
  732. display: flex;
  733. padding: 10px 6px;
  734. border-bottom: 1px solid #f0f0f0;
  735. font-size: 12px;
  736. color: #333;
  737. transition: background-color 0.2s ease;
  738. }
  739. .table-row:hover {
  740. background-color: #f8f9fa;
  741. }
  742. .table-row:last-child {
  743. border-bottom: none;
  744. }
  745. .material-table .col-no {
  746. width: 25px;
  747. text-align: center;
  748. flex-shrink: 0;
  749. font-size: 12px;
  750. }
  751. .material-table .col-material-code {
  752. flex: 1.8;
  753. text-align: center;
  754. min-width: 100px;
  755. font-size: 12px;
  756. word-break: break-all;
  757. }
  758. .material-table .col-required-qty {
  759. flex: 0.8;
  760. text-align: center;
  761. min-width: 65px;
  762. font-size: 12px;
  763. }
  764. .material-table .col-inbound-qty {
  765. flex: 0.8;
  766. text-align: center;
  767. min-width: 65px;
  768. font-size: 12px;
  769. }
  770. .material-modal .modal-footer {
  771. padding: 15px 20px;
  772. display: flex;
  773. justify-content: center;
  774. border-top: 1px solid #f0f0f0;
  775. }
  776. .btn-close {
  777. padding: 10px 20px;
  778. border-radius: 6px;
  779. font-size: 14px;
  780. cursor: pointer;
  781. transition: all 0.2s;
  782. border: 1px solid #17B3A3;
  783. background: white;
  784. color: #17B3A3;
  785. }
  786. .btn-close:hover {
  787. background: #17B3A3;
  788. color: white;
  789. }
  790. /* 加载状态样式 */
  791. .loading-container {
  792. display: flex;
  793. flex-direction: column;
  794. align-items: center;
  795. justify-content: center;
  796. padding: 60px 20px;
  797. color: #666;
  798. }
  799. .loading-container i {
  800. font-size: 24px;
  801. margin-bottom: 12px;
  802. color: #17B3A3;
  803. }
  804. .loading-container span {
  805. font-size: 14px;
  806. }
  807. /* 空数据状态样式 */
  808. .empty-material {
  809. display: flex;
  810. flex-direction: column;
  811. align-items: center;
  812. justify-content: center;
  813. padding: 60px 20px;
  814. color: #999;
  815. }
  816. .empty-material i {
  817. font-size: 48px;
  818. margin-bottom: 16px;
  819. color: #ddd;
  820. }
  821. .empty-material p {
  822. margin: 0;
  823. font-size: 14px;
  824. }
  825. /* 响应式设计 */
  826. @media (max-width: 360px) {
  827. .header-bar {
  828. padding: 8px 12px;
  829. }
  830. .search-container {
  831. padding: 8px 12px;
  832. }
  833. .material-info-card {
  834. margin: 4px 12px;
  835. padding: 6px 16px;
  836. }
  837. .section-title {
  838. margin: 0 12px;
  839. margin-top: 4px;
  840. }
  841. .label-list {
  842. margin: 0 12px 8px;
  843. }
  844. .card-details {
  845. flex-wrap: wrap;
  846. gap: 6px;
  847. }
  848. .detail-item {
  849. flex: 0 0 48%;
  850. margin-bottom: 6px;
  851. min-width: 50px;
  852. }
  853. .list-header, .list-item {
  854. font-size: 11px;
  855. }
  856. .col-label, .col-part {
  857. flex: 1.5;
  858. }
  859. }
  860. </style>