|
@@ -0,0 +1,672 @@
|
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
|
+<html lang="zh-CN">
|
|
|
|
|
+<head>
|
|
|
|
|
+ <meta charset="UTF-8">
|
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
|
|
+ <title>交货情况</title>
|
|
|
|
|
+ <meta property="og:title" content="交货情况">
|
|
|
|
|
+ <meta property="og:image" content="{:htmlentities(default_admin_avatar_url())}">
|
|
|
|
|
+ <link rel="shortcut icon" href="{:htmlentities(default_admin_avatar_url())}" type="image/png">
|
|
|
|
|
+ <link rel="icon" href="{:htmlentities(default_admin_avatar_url())}" type="image/png">
|
|
|
|
|
+ <link rel="apple-touch-icon" href="{:htmlentities(default_admin_avatar_url())}">
|
|
|
|
|
+ <style>
|
|
|
|
|
+ * { box-sizing: border-box; }
|
|
|
|
|
+ html, body { margin: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background: #f5f5f5; color: #333; }
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --bar-h: 52px;
|
|
|
|
|
+ --tabbar-h: 52px;
|
|
|
|
|
+ --side-w: 72px;
|
|
|
|
|
+ --safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
|
|
|
+ }
|
|
|
|
|
+ body.layout-orders { overflow: hidden; }
|
|
|
|
|
+ body.layout-me { overflow: hidden; }
|
|
|
|
|
+ .bar {
|
|
|
|
|
+ position: fixed; top: 0; left: 0; right: 0; z-index: 50;
|
|
|
|
|
+ height: var(--bar-h); padding: 0 14px;
|
|
|
|
|
+ background: #3c8dbc; color: #fff;
|
|
|
|
|
+ display: flex; align-items: center; justify-content: space-between;
|
|
|
|
|
+ }
|
|
|
|
|
+ .bar h1 { font-size: 1.05rem; margin: 0; font-weight: 600; }
|
|
|
|
|
+ .bar a { color: #fff; text-decoration: none; font-size: 13px; padding: 5px 10px; border: 1px solid rgba(255,255,255,.6); border-radius: 6px; }
|
|
|
|
|
+ body.layout-orders .bar-logout { display: none !important; }
|
|
|
|
|
+ #pane-orders {
|
|
|
|
|
+ position: fixed; left: 0; right: 0; z-index: 10;
|
|
|
|
|
+ top: var(--bar-h); bottom: calc(var(--tabbar-h) + var(--safe-bottom));
|
|
|
|
|
+ display: flex; flex-direction: column; overflow: hidden; background: #f5f5f5;
|
|
|
|
|
+ }
|
|
|
|
|
+ #pane-me {
|
|
|
|
|
+ position: fixed; left: 0; right: 0; z-index: 10;
|
|
|
|
|
+ top: var(--bar-h); bottom: calc(var(--tabbar-h) + var(--safe-bottom));
|
|
|
|
|
+ overflow-y: auto; -webkit-overflow-scrolling: touch; background: #f5f5f5;
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ .search-wrap {
|
|
|
|
|
+ flex-shrink: 0; padding: 10px 12px; background: #e8f4fc;
|
|
|
|
|
+ border-bottom: 1px solid #d2e7f4; width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .search-form { display: flex; gap: 8px; align-items: center; max-width: 640px; margin: 0 auto; }
|
|
|
|
|
+ .search-form input[type="search"],
|
|
|
|
|
+ .search-form input[type="text"] {
|
|
|
|
|
+ flex: 1; min-width: 0; padding: 10px 12px; border: 1px solid #bcd8ea;
|
|
|
|
|
+ border-radius: 8px; font-size: 15px; background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .search-form input:focus { outline: none; border-color: #3c8dbc; }
|
|
|
|
|
+ .search-form button[type="submit"] {
|
|
|
|
|
+ flex-shrink: 0; padding: 10px 16px; border: none; border-radius: 8px;
|
|
|
|
|
+ background: #3c8dbc; color: #fff; font-size: 14px; font-weight: 600;
|
|
|
|
|
+ }
|
|
|
|
|
+ .body-wrap { flex: 1 1 0%; min-height: 0; display: flex; overflow: hidden; }
|
|
|
|
|
+ .side {
|
|
|
|
|
+ width: var(--side-w); flex-shrink: 0; background: #fff;
|
|
|
|
|
+ border-right: 1px solid #e5e5e5; padding-top: 8px; overflow-y: auto;
|
|
|
|
|
+ }
|
|
|
|
|
+ .side .cat {
|
|
|
|
|
+ display: block; width: 100%; padding: 14px 6px; border: none;
|
|
|
|
|
+ background: transparent; color: #555; font-size: 13px;
|
|
|
|
|
+ text-align: center; line-height: 1.35; font-family: inherit;
|
|
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
+ .side .cat.active {
|
|
|
|
|
+ background: #f0f7fb; color: #3c8dbc; font-weight: 600;
|
|
|
|
|
+ box-shadow: inset 3px 0 0 #3c8dbc;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .score-summary {
|
|
|
|
|
+ margin-top: 8px; font-size: 12px; color: #666; line-height: 1.5;
|
|
|
|
|
+ display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .score-summary .res {
|
|
|
|
|
+ font-weight: 700; color: #27ae60;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .score-summary .res.is-fail { color: #e74c3c; }
|
|
|
|
|
+ .card .score-extra { margin-top: 6px; font-size: 12px; color: #666; line-height: 1.5; }
|
|
|
|
|
+ .card .score-time { margin-top: 6px; font-size: 12px; color: #888; }
|
|
|
|
|
+ .main {
|
|
|
|
|
+ flex: 1; min-width: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
|
|
|
|
|
+ padding: 10px; background: #f5f5f5;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card {
|
|
|
|
|
+ background: #fff; border-radius: 10px; padding: 12px;
|
|
|
|
|
+ margin-bottom: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.06);
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .ord {
|
|
|
|
|
+ font-size: 15px; font-weight: 700; color: #222; margin-bottom: 8px;
|
|
|
|
|
+ line-height: 1.45; word-break: break-all;
|
|
|
|
|
+ }
|
|
|
|
|
+ .card .meta { font-size: 13px; color: #555; line-height: 1.55; }
|
|
|
|
|
+ .card .meta b { color: #333; font-weight: 600; }
|
|
|
|
|
+ .actions { display: flex; gap: 8px; margin-top: 10px; justify-content: flex-end; }
|
|
|
|
|
+ .actions button {
|
|
|
|
|
+ min-width: 72px; padding: 6px 14px; border: none; border-radius: 6px;
|
|
|
|
|
+ font-size: 13px; font-weight: 600; color: #fff; font-family: inherit;
|
|
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
+ .btn-score { background: #3c8dbc; }
|
|
|
|
|
+ .btn-score:disabled { opacity: .55; }
|
|
|
|
|
+ .me-panel { padding: 16px 14px 24px; max-width: 480px; margin: 0 auto; }
|
|
|
|
|
+ .me-card { background: #fff; border-radius: 12px; padding: 18px 16px; box-shadow: 0 1px 6px rgba(0,0,0,.06); }
|
|
|
|
|
+ .me-row { font-size: 14px; line-height: 1.7; padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
|
|
|
|
|
+ .me-row:last-child { border-bottom: none; }
|
|
|
|
|
+ .me-row span { display: inline-block; min-width: 4.5em; color: #888; }
|
|
|
|
|
+ .btn-me-logout {
|
|
|
|
|
+ display: block; width: 100%; margin-top: 16px; padding: 12px;
|
|
|
|
|
+ border: 1px solid #e74c3c; border-radius: 8px; background: #fff;
|
|
|
|
|
+ color: #e74c3c; font-size: 15px; font-weight: 600; text-align: center;
|
|
|
|
|
+ text-decoration: none; font-family: inherit;
|
|
|
|
|
+ }
|
|
|
|
|
+ .tabbar {
|
|
|
|
|
+ position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
|
|
|
|
|
+ display: flex; background: #fff; border-top: 1px solid #e5e5e5;
|
|
|
|
|
+ box-shadow: 0 -2px 10px rgba(0,0,0,.05);
|
|
|
|
|
+ padding-bottom: var(--safe-bottom);
|
|
|
|
|
+ }
|
|
|
|
|
+ .tabbar .tabbar-btn {
|
|
|
|
|
+ flex: 1; text-align: center; padding: 10px 4px 12px; color: #666;
|
|
|
|
|
+ font-size: 14px; line-height: 1.25; border: none; border-top: 3px solid transparent;
|
|
|
|
|
+ margin-top: -1px; background: #fff; cursor: pointer; font-family: inherit;
|
|
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
+ .tabbar .tabbar-btn.active { color: #3c8dbc; font-weight: 600; border-top-color: #3c8dbc; background: #f8fbfd; }
|
|
|
|
|
+ .confirm-mask {
|
|
|
|
|
+ display: none; position: fixed; inset: 0; z-index: 2000;
|
|
|
|
|
+ background: rgba(0,0,0,.45); align-items: center; justify-content: center;
|
|
|
|
|
+ padding: 24px 28px;
|
|
|
|
|
+ padding-bottom: calc(24px + var(--safe-bottom));
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-mask.show { display: flex; }
|
|
|
|
|
+ .confirm-box {
|
|
|
|
|
+ width: 100%; max-width: 340px; background: #fff;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ box-shadow: 0 8px 28px rgba(0,0,0,.18);
|
|
|
|
|
+ max-height: min(90vh, 720px);
|
|
|
|
|
+ display: flex; flex-direction: column;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box-body {
|
|
|
|
|
+ flex: 1 1 auto;
|
|
|
|
|
+ min-height: 0;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ -webkit-overflow-scrolling: touch;
|
|
|
|
|
+ padding: 18px 16px 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box .confirm-ord {
|
|
|
|
|
+ font-size: 15px; font-weight: 700; color: #222; line-height: 1.45;
|
|
|
|
|
+ word-break: break-all; margin: 0 0 8px; text-align: left;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box .confirm-meta {
|
|
|
|
|
+ font-size: 13px; color: #555; line-height: 1.55; margin: 0 0 12px; text-align: left;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box .confirm-meta b { color: #333; font-weight: 600; }
|
|
|
|
|
+ .score-field {
|
|
|
|
|
+ margin: 0 0 12px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-field .label {
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+ min-width: 7.2em;
|
|
|
|
|
+ font-size: 13px; font-weight: 600; color: #333;
|
|
|
|
|
+ margin: 0; line-height: 1.35;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-field .label .req { color: #e74c3c; margin-left: 2px; }
|
|
|
|
|
+ .score-opts {
|
|
|
|
|
+ flex: 1 1 auto;
|
|
|
|
|
+ display: flex; gap: 8px;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-opt {
|
|
|
|
|
+ flex: 1; position: relative;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-opt input {
|
|
|
|
|
+ position: absolute; opacity: 0; pointer-events: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-opt span {
|
|
|
|
|
+ display: block; text-align: center; padding: 8px 6px; border-radius: 8px;
|
|
|
|
|
+ border: 1px solid #d9d9d9; background: #fafafa; font-size: 13px; font-weight: 600;
|
|
|
|
|
+ color: #555;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-opt input:checked + span {
|
|
|
|
|
+ border-color: #3c8dbc; background: #eaf5fb; color: #3c8dbc;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-opt.pass input:checked + span { border-color: #27ae60; background: #eafaf1; color: #27ae60; }
|
|
|
|
|
+ .score-opt.fail input:checked + span { border-color: #e74c3c; background: #fdecea; color: #e74c3c; }
|
|
|
|
|
+ .score-field-remark {
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: stretch;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-field-remark .label {
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-remark {
|
|
|
|
|
+ width: 100%; min-height: 72px; padding: 10px 12px; border: 1px solid #d9d9d9;
|
|
|
|
|
+ border-radius: 8px; font-size: 14px; line-height: 1.5; resize: vertical;
|
|
|
|
|
+ font-family: inherit; background: #fff; color: #333;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-remark:focus { outline: none; border-color: #3c8dbc; }
|
|
|
|
|
+ .score-date-wrap {
|
|
|
|
|
+ flex: 1 1 auto; min-width: 0; position: relative;
|
|
|
|
|
+ border: 1px solid #d9d9d9; border-radius: 8px; background: #fff;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-date-wrap:focus-within { border-color: #3c8dbc; }
|
|
|
|
|
+ .score-date {
|
|
|
|
|
+ display: block; width: 100%; min-height: 40px; padding: 8px 10px;
|
|
|
|
|
+ border: none; border-radius: 8px; font-size: 14px; line-height: 1.4;
|
|
|
|
|
+ font-family: inherit; background: transparent; color: #333;
|
|
|
|
|
+ -webkit-appearance: none; appearance: none; cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .score-date:focus { outline: none; }
|
|
|
|
|
+ .score-date::-webkit-calendar-picker-indicator {
|
|
|
|
|
+ position: absolute; left: 0; top: 0; width: 100%; height: 100%;
|
|
|
|
|
+ margin: 0; padding: 0; opacity: 0; cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box .confirm-acts {
|
|
|
|
|
+ flex: 0 0 auto;
|
|
|
|
|
+ display: flex; gap: 10px;
|
|
|
|
|
+ padding: 12px 16px;
|
|
|
|
|
+ border-top: 1px solid #eee;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-box .confirm-acts button {
|
|
|
|
|
+ flex: 1; padding: 12px 8px; border: none; border-radius: 8px;
|
|
|
|
|
+ font-size: 15px; font-weight: 600; font-family: inherit;
|
|
|
|
|
+ }
|
|
|
|
|
+ .confirm-cancel { background: #f0f0f0; color: #555; }
|
|
|
|
|
+ .confirm-ok { background: #3c8dbc; color: #fff; }
|
|
|
|
|
+ .confirm-ok:disabled { opacity: .55; }
|
|
|
|
|
+ .empty { text-align: center; color: #999; padding: 48px 16px; font-size: 14px; }
|
|
|
|
|
+ .toast {
|
|
|
|
|
+ position: fixed; left: 50%; bottom: 90px; transform: translateX(-50%);
|
|
|
|
|
+ max-width: 86vw; padding: 10px 16px; border-radius: 8px;
|
|
|
|
|
+ background: rgba(0,0,0,.78); color: #fff; font-size: 14px;
|
|
|
|
|
+ z-index: 1000; opacity: 0; pointer-events: none; transition: opacity .2s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .toast.show { opacity: 1; }
|
|
|
|
|
+ .toast.ok { background: #27ae60; }
|
|
|
|
|
+ .toast.err { background: #c0392b; }
|
|
|
|
|
+ </style>
|
|
|
|
|
+</head>
|
|
|
|
|
+<body class="layout-orders">
|
|
|
|
|
+<div class="bar">
|
|
|
|
|
+ <h1 id="barTitle">交货情况</h1>
|
|
|
|
|
+ <a href="{:url('index/index/logout')}" class="bar-logout" id="barLogout">退出</a>
|
|
|
|
|
+</div>
|
|
|
|
|
+
|
|
|
|
|
+<div id="pane-orders">
|
|
|
|
|
+ <div class="search-wrap">
|
|
|
|
|
+ <form class="search-form" id="searchForm" action="javascript:;" onsubmit="return false;">
|
|
|
|
|
+ <input type="search" id="qInput" name="q" placeholder="请输入搜索内容" value="{$mprocSearchQ|default=''|htmlentities}" maxlength="120" enterkeyhint="search" autocomplete="off">
|
|
|
|
|
+ <button type="submit">搜索</button>
|
|
|
|
|
+ </form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="body-wrap">
|
|
|
|
|
+ <div class="side" id="listCats">
|
|
|
|
|
+ <button type="button" class="cat active" data-list-tab="pending">待确认</button>
|
|
|
|
|
+ <button type="button" class="cat" data-list-tab="scored">已确认</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="main" id="listMain">
|
|
|
|
|
+ {if $rows}
|
|
|
|
|
+ {volist name="rows" id="row"}
|
|
|
|
|
+ <div class="card" data-ccydh="{$row.CCYDH|htmlentities}">
|
|
|
|
|
+ <div class="ord">{$row.CCYDH|default=''|htmlentities}{if $row.CYJMC} {$row.CYJMC|htmlentities}{/if}</div>
|
|
|
|
|
+ <div class="meta">
|
|
|
|
|
+ <div><b>供应商:</b>{$row.pick_company_name|default='—'|htmlentities}</div>
|
|
|
|
|
+ <div><b>工序:</b>{$row.CGYMC|default='—'|htmlentities}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="actions">
|
|
|
|
|
+ <button type="button" class="btn-score">确认交货</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ {/volist}
|
|
|
|
|
+ {else/}
|
|
|
|
|
+ <div class="empty" id="emptyTip">暂无待确认订单</div>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|
|
|
|
|
+
|
|
|
|
|
+<div id="pane-me" class="me-panel">
|
|
|
|
|
+ <div class="me-card">
|
|
|
|
|
+ <div class="me-row"><span>账号</span>{$mprocProfile.account|default=''|htmlentities}</div>
|
|
|
|
|
+ <div class="me-row"><span>姓名</span>{$mprocProfile.contact_name|default=''|htmlentities}</div>
|
|
|
|
|
+ <div class="me-row"><span>部门</span>{$mprocProfile.department|default=''|htmlentities}</div>
|
|
|
|
|
+ <div class="me-row"><span>手机号</span>{$mprocProfile.phone|default=''|htmlentities}</div>
|
|
|
|
|
+ <div class="me-row"><span>邮箱</span>{$mprocProfile.email|default=''|htmlentities}</div>
|
|
|
|
|
+ <a class="btn-me-logout" href="{:url('index/index/logout')}">退出登录</a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|
|
|
|
|
+
|
|
|
|
|
+<nav class="tabbar" id="tabbar" aria-label="主导航">
|
|
|
|
|
+ <button type="button" class="tabbar-btn active" data-main-tab="orders">首页</button>
|
|
|
|
|
+ <button type="button" class="tabbar-btn" data-main-tab="me">我的</button>
|
|
|
|
|
+</nav>
|
|
|
|
|
+
|
|
|
|
|
+<div class="toast" id="toast"></div>
|
|
|
|
|
+<div class="confirm-mask" id="scoreMask">
|
|
|
|
|
+ <div class="confirm-box">
|
|
|
|
|
+ <div class="confirm-box-body">
|
|
|
|
|
+ <div class="confirm-ord" id="scoreOrd"></div>
|
|
|
|
|
+ <div class="confirm-meta" id="scoreMeta"></div>
|
|
|
|
|
+ <div class="score-field">
|
|
|
|
|
+ <span class="label">交货情况<span class="req">*</span></span>
|
|
|
|
|
+ <div class="score-opts">
|
|
|
|
|
+ <label class="score-opt pass">
|
|
|
|
|
+ <input type="radio" name="delivery_status" value="准时">
|
|
|
|
|
+ <span>准时</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ <label class="score-opt fail">
|
|
|
|
|
+ <input type="radio" name="delivery_status" value="滞后">
|
|
|
|
|
+ <span>滞后</span>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="score-field">
|
|
|
|
|
+ <span class="label">交货日期<span class="req">*</span></span>
|
|
|
|
|
+ <div class="score-date-wrap" id="deliveryDateWrap">
|
|
|
|
|
+ <input type="date" class="score-date" id="deliveryDate">
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="confirm-acts">
|
|
|
|
|
+ <button type="button" class="confirm-cancel" id="scoreCancel">取消</button>
|
|
|
|
|
+ <button type="button" class="confirm-ok" id="scoreOk">提交</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</div>
|
|
|
|
|
+<script>
|
|
|
|
|
+(function () {
|
|
|
|
|
+ var listUrl = "{:url('index/index/deliveryscorelist')}";
|
|
|
|
|
+ var saveUrl = "{:url('index/index/deliveryscoresave')}";
|
|
|
|
|
+ var loginUrl = "{:url('index/index/login')}";
|
|
|
|
|
+ var token = {:json_encode(isset($mprocBootstrapToken) ? $mprocBootstrapToken : '', JSON_UNESCAPED_UNICODE)};
|
|
|
|
|
+ var keepHours = {$mprocBootstrapKeepHours|default=72};
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (token) {
|
|
|
|
|
+ localStorage.setItem('mproc_token', token);
|
|
|
|
|
+ localStorage.setItem('mproc_token_exp', String(Date.now() + keepHours * 3600 * 1000));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+
|
|
|
|
|
+ function clearLocalLoginToken() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ localStorage.removeItem('mproc_token');
|
|
|
|
|
+ localStorage.removeItem('mproc_token_exp');
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document.querySelectorAll('a.btn-me-logout, a.bar-logout').forEach(function (a) {
|
|
|
|
|
+ a.addEventListener('click', function () {
|
|
|
|
|
+ clearLocalLoginToken();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ function showToast(msg, type) {
|
|
|
|
|
+ var el = document.getElementById('toast');
|
|
|
|
|
+ if (!el) return;
|
|
|
|
|
+ el.textContent = msg || '';
|
|
|
|
|
+ el.className = 'toast show' + (type === 'ok' ? ' ok' : (type === 'err' ? ' err' : ''));
|
|
|
|
|
+ clearTimeout(showToast._t);
|
|
|
|
|
+ showToast._t = setTimeout(function () { el.className = 'toast'; }, 2800);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function esc(s) {
|
|
|
|
|
+ return String(s == null ? '' : s)
|
|
|
|
|
+ .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
|
|
|
+ .replace(/"/g, '"');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function titleText(row) {
|
|
|
|
|
+ var no = String(row.CCYDH || '').trim();
|
|
|
|
|
+ var name = String(row.CYJMC || '').trim();
|
|
|
|
|
+ if (no && name) return no + ' ' + name;
|
|
|
|
|
+ return no || name || '—';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var currentTab = 'pending';
|
|
|
|
|
+
|
|
|
|
|
+ function emptyText(tab) {
|
|
|
|
|
+ if (tab === 'scored') return '暂无已确认订单';
|
|
|
|
|
+ return '暂无待确认订单';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function renderRows(rows) {
|
|
|
|
|
+ var main = document.getElementById('listMain');
|
|
|
|
|
+ if (!main) return;
|
|
|
|
|
+ if (!rows || !rows.length) {
|
|
|
|
|
+ main.innerHTML = '<div class="empty">' + emptyText(currentTab) + '</div>';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ var html = '';
|
|
|
|
|
+ var pending = currentTab === 'pending';
|
|
|
|
|
+ rows.forEach(function (row) {
|
|
|
|
|
+ html += '<div class="card" data-ccydh="' + esc(row.CCYDH || '') + '">';
|
|
|
|
|
+ html += '<div class="ord">' + esc(titleText(row)) + '</div>';
|
|
|
|
|
+ html += '<div class="meta">';
|
|
|
|
|
+ html += '<div><b>供应商:</b>' + esc(row.pick_company_name || '—') + '</div>';
|
|
|
|
|
+ html += '<div><b>工序:</b>' + esc(row.CGYMC || '—') + '</div>';
|
|
|
|
|
+ html += '</div>';
|
|
|
|
|
+ if (pending) {
|
|
|
|
|
+ html += '<div class="actions"><button type="button" class="btn-score">确认交货</button></div>';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ var ds = String(row.delivery_status || '');
|
|
|
|
|
+ var dd = String(row.delivery_date || '');
|
|
|
|
|
+ html += '<div class="score-summary"'
|
|
|
|
|
+ + ' data-delivery-status="' + esc(ds) + '"'
|
|
|
|
|
+ + ' data-delivery-date="' + esc(dd) + '">'
|
|
|
|
|
+ + '<span class="res' + (ds === '滞后' ? ' is-fail' : '') + '">' + esc(ds || '—') + '</span>'
|
|
|
|
|
+ + (dd ? '<span>交货日期:' + esc(dd) + '</span>' : '')
|
|
|
|
|
+ + '</div>';
|
|
|
|
|
+ if (row.score_time) {
|
|
|
|
|
+ html += '<div class="score-time">操作时间:' + esc(row.score_time) + '</div>';
|
|
|
|
|
+ }
|
|
|
|
|
+ html += '<div class="actions"><button type="button" class="btn-score">确认交货</button></div>';
|
|
|
|
|
+ }
|
|
|
|
|
+ html += '</div>';
|
|
|
|
|
+ });
|
|
|
|
|
+ main.innerHTML = html;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function postForm(url, data) {
|
|
|
|
|
+ var body = Object.keys(data).map(function (k) {
|
|
|
|
|
+ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k] == null ? '' : data[k]);
|
|
|
|
|
+ }).join('&');
|
|
|
|
|
+ var headers = {
|
|
|
|
|
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
|
|
|
+ 'X-Requested-With': 'XMLHttpRequest'
|
|
|
|
|
+ };
|
|
|
|
|
+ try {
|
|
|
|
|
+ var tok = localStorage.getItem('mproc_token') || token || '';
|
|
|
|
|
+ if (tok) headers['X-Mproc-Token'] = tok;
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ return fetch(url, { method: 'POST', credentials: 'same-origin', headers: headers, body: body })
|
|
|
|
|
+ .then(function (r) { return r.json(); });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var searchTimer = null;
|
|
|
|
|
+ function loadList() {
|
|
|
|
|
+ var q = (document.getElementById('qInput') || {}).value || '';
|
|
|
|
|
+ postForm(listUrl, { tab: currentTab, q: q }).then(function (ret) {
|
|
|
|
|
+ if (!ret || (ret.code !== 1 && ret.code !== '1')) {
|
|
|
|
|
+ if (ret && /登录/.test(String(ret.msg || ''))) {
|
|
|
|
|
+ location.href = loginUrl;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ showToast(ret && ret.msg ? ret.msg : '加载失败', 'err');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ var d = ret.data || {};
|
|
|
|
|
+ renderRows(d.rows || []);
|
|
|
|
|
+ }).catch(function () {
|
|
|
|
|
+ showToast('网络错误', 'err');
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document.getElementById('listCats').addEventListener('click', function (e) {
|
|
|
|
|
+ var btn = e.target.closest('.cat[data-list-tab]');
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ var tab = btn.getAttribute('data-list-tab');
|
|
|
|
|
+ if (!tab || tab === currentTab) return;
|
|
|
|
|
+ currentTab = tab;
|
|
|
|
|
+ var cats = document.querySelectorAll('#listCats .cat');
|
|
|
|
|
+ cats.forEach(function (c) { c.classList.toggle('active', c === btn); });
|
|
|
|
|
+ loadList();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ var $qInput = document.getElementById('qInput');
|
|
|
|
|
+ if ($qInput) {
|
|
|
|
|
+ $qInput.addEventListener('input', function () {
|
|
|
|
|
+ clearTimeout(searchTimer);
|
|
|
|
|
+ searchTimer = setTimeout(loadList, 280);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ document.getElementById('searchForm').addEventListener('submit', function (e) {
|
|
|
|
|
+ e.preventDefault();
|
|
|
|
|
+ clearTimeout(searchTimer);
|
|
|
|
|
+ loadList();
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ var paneOrders = document.getElementById('pane-orders');
|
|
|
|
|
+ var paneMe = document.getElementById('pane-me');
|
|
|
|
|
+ var barTitle = document.getElementById('barTitle');
|
|
|
|
|
+ document.getElementById('tabbar').addEventListener('click', function (e) {
|
|
|
|
|
+ var btn = e.target.closest('.tabbar-btn');
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ var tab = btn.getAttribute('data-main-tab');
|
|
|
|
|
+ var btns = document.querySelectorAll('#tabbar .tabbar-btn');
|
|
|
|
|
+ btns.forEach(function (b) { b.classList.toggle('active', b === btn); });
|
|
|
|
|
+ if (tab === 'me') {
|
|
|
|
|
+ document.body.className = 'layout-me';
|
|
|
|
|
+ paneOrders.style.display = 'none';
|
|
|
|
|
+ paneMe.style.display = 'block';
|
|
|
|
|
+ if (barTitle) barTitle.textContent = '我的';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ document.body.className = 'layout-orders';
|
|
|
|
|
+ paneOrders.style.display = 'flex';
|
|
|
|
|
+ paneMe.style.display = 'none';
|
|
|
|
|
+ if (barTitle) barTitle.textContent = '交货情况';
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ var scoreMask = document.getElementById('scoreMask');
|
|
|
|
|
+ var scoreOrd = document.getElementById('scoreOrd');
|
|
|
|
|
+ var scoreMeta = document.getElementById('scoreMeta');
|
|
|
|
|
+ var scorePendingCard = null;
|
|
|
|
|
+
|
|
|
|
|
+ function textOf(el) {
|
|
|
|
|
+ return el ? String(el.textContent || '').replace(/\s+/g, ' ').trim() : '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function checkedVal(name) {
|
|
|
|
|
+ var el = document.querySelector('input[name="' + name + '"]:checked');
|
|
|
|
|
+ return el ? String(el.value || '') : '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function fillScoreForm(status, date) {
|
|
|
|
|
+ var deliveryRadios = document.querySelectorAll('input[name="delivery_status"]');
|
|
|
|
|
+ deliveryRadios.forEach(function (r) {
|
|
|
|
|
+ r.checked = String(r.value) === String(status || '');
|
|
|
|
|
+ });
|
|
|
|
|
+ var dateEl = document.getElementById('deliveryDate');
|
|
|
|
|
+ if (dateEl) {
|
|
|
|
|
+ dateEl.value = /^\d{4}-\d{2}-\d{2}$/.test(String(date || '')) ? String(date) : '';
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function resetScoreForm() {
|
|
|
|
|
+ fillScoreForm('', '');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function openDatePicker() {
|
|
|
|
|
+ var dateEl = document.getElementById('deliveryDate');
|
|
|
|
|
+ if (!dateEl) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (typeof dateEl.showPicker === 'function') {
|
|
|
|
|
+ dateEl.showPicker();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ dateEl.focus();
|
|
|
|
|
+ try { dateEl.click(); } catch (e2) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function openScoreForm(card) {
|
|
|
|
|
+ scorePendingCard = card || null;
|
|
|
|
|
+ var ord = textOf(card.querySelector('.ord')) || '—';
|
|
|
|
|
+ var metaLines = card.querySelectorAll('.meta > div');
|
|
|
|
|
+ var gymc = '—';
|
|
|
|
|
+ var company = '—';
|
|
|
|
|
+ for (var i = 0; i < metaLines.length; i++) {
|
|
|
|
|
+ var t = textOf(metaLines[i]);
|
|
|
|
|
+ if (t.indexOf('工序:') === 0) gymc = t.slice(3).trim() || '—';
|
|
|
|
|
+ if (t.indexOf('供应商:') === 0) company = t.slice(4).trim() || '—';
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scoreOrd) scoreOrd.textContent = ord;
|
|
|
|
|
+ if (scoreMeta) {
|
|
|
|
|
+ scoreMeta.innerHTML = '<div><b>供应商:</b>' + esc(company) + '</div>'
|
|
|
|
|
+ + '<div><b>工序:</b>' + esc(gymc) + '</div>';
|
|
|
|
|
+ }
|
|
|
|
|
+ var summary = card.querySelector('.score-summary');
|
|
|
|
|
+ if (summary) {
|
|
|
|
|
+ fillScoreForm(
|
|
|
|
|
+ summary.getAttribute('data-delivery-status') || '',
|
|
|
|
|
+ summary.getAttribute('data-delivery-date') || ''
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ resetScoreForm();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scoreMask) scoreMask.classList.add('show');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function closeScoreForm() {
|
|
|
|
|
+ scorePendingCard = null;
|
|
|
|
|
+ if (scoreMask) scoreMask.classList.remove('show');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document.getElementById('scoreCancel').addEventListener('click', closeScoreForm);
|
|
|
|
|
+ scoreMask.addEventListener('click', function (e) {
|
|
|
|
|
+ if (e.target === scoreMask) closeScoreForm();
|
|
|
|
|
+ });
|
|
|
|
|
+ var deliveryDateWrap = document.getElementById('deliveryDateWrap');
|
|
|
|
|
+ if (deliveryDateWrap) {
|
|
|
|
|
+ deliveryDateWrap.addEventListener('click', function (e) {
|
|
|
|
|
+ if (e.target && e.target.id === 'deliveryDate') return;
|
|
|
|
|
+ openDatePicker();
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ var deliveryDateEl = document.getElementById('deliveryDate');
|
|
|
|
|
+ if (deliveryDateEl) {
|
|
|
|
|
+ deliveryDateEl.addEventListener('click', function () {
|
|
|
|
|
+ openDatePicker();
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function submitScore(card, payload) {
|
|
|
|
|
+ var ccydh = card.getAttribute('data-ccydh');
|
|
|
|
|
+ if (!ccydh || !payload || !payload.delivery_status) return;
|
|
|
|
|
+ var buttons = card.querySelectorAll('button');
|
|
|
|
|
+ buttons.forEach(function (b) { b.disabled = true; });
|
|
|
|
|
+ var okBtn = document.getElementById('scoreOk');
|
|
|
|
|
+ if (okBtn) okBtn.disabled = true;
|
|
|
|
|
+ postForm(saveUrl, {
|
|
|
|
|
+ ccydh: ccydh,
|
|
|
|
|
+ delivery_status: payload.delivery_status,
|
|
|
|
|
+ delivery_date: payload.delivery_date || ''
|
|
|
|
|
+ }).then(function (ret) {
|
|
|
|
|
+ if (okBtn) okBtn.disabled = false;
|
|
|
|
|
+ if (!ret || (ret.code !== 1 && ret.code !== '1')) {
|
|
|
|
|
+ buttons.forEach(function (b) { b.disabled = false; });
|
|
|
|
|
+ if (ret && /登录/.test(String(ret.msg || ''))) {
|
|
|
|
|
+ location.href = loginUrl;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ showToast(ret && ret.msg ? ret.msg : '保存失败', 'err');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ closeScoreForm();
|
|
|
|
|
+ showToast(ret.msg || '已保存', 'ok');
|
|
|
|
|
+ if (currentTab === 'scored') {
|
|
|
|
|
+ loadList();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ card.parentNode && card.parentNode.removeChild(card);
|
|
|
|
|
+ if (!document.querySelector('#listMain .card')) {
|
|
|
|
|
+ document.getElementById('listMain').innerHTML = '<div class="empty">暂无待确认订单</div>';
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function () {
|
|
|
|
|
+ if (okBtn) okBtn.disabled = false;
|
|
|
|
|
+ buttons.forEach(function (b) { b.disabled = false; });
|
|
|
|
|
+ showToast('网络错误', 'err');
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document.getElementById('scoreOk').addEventListener('click', function () {
|
|
|
|
|
+ var card = scorePendingCard;
|
|
|
|
|
+ if (!card) return;
|
|
|
|
|
+ var deliveryStatus = checkedVal('delivery_status');
|
|
|
|
|
+ if (deliveryStatus !== '准时' && deliveryStatus !== '滞后') {
|
|
|
|
|
+ showToast('请选择交货情况', 'err');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ var deliveryDate = ((document.getElementById('deliveryDate') || {}).value || '').trim();
|
|
|
|
|
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(deliveryDate)) {
|
|
|
|
|
+ showToast('请选择交货日期', 'err');
|
|
|
|
|
+ var dateEl = document.getElementById('deliveryDate');
|
|
|
|
|
+ if (dateEl) dateEl.focus();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ submitScore(card, { delivery_status: deliveryStatus, delivery_date: deliveryDate });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ document.getElementById('listMain').addEventListener('click', function (e) {
|
|
|
|
|
+ var btn = e.target.closest('button.btn-score');
|
|
|
|
|
+ if (!btn) return;
|
|
|
|
|
+ var card = btn.closest('.card');
|
|
|
|
|
+ if (!card) return;
|
|
|
|
|
+ openScoreForm(card);
|
|
|
|
|
+ });
|
|
|
|
|
+})();
|
|
|
|
|
+</script>
|
|
|
|
|
+</body>
|
|
|
|
|
+</html>
|