liuhairui 2 weeks ago
parent
commit
6b546000b7

File diff suppressed because it is too large
+ 676 - 96
application/admin/controller/Procuremen.php


+ 2 - 2
application/admin/view/customer/add.html

@@ -41,14 +41,14 @@
         <div class="col-xs-12 col-sm-8">
             <input type="hidden" name="row[company_type]" id="c-company_type" value="">
             <div class="input-group company-type-onebox">
-                <select id="c-company_type_select" class="form-control selectpicker" multiple data-live-search="true" data-width="100%" data-selected-text-format="static" data-live-search-placeholder="无匹配时按回车添加" title="请选择">
+                <select id="c-company_type_select" class="form-control selectpicker" multiple data-live-search="true" data-width="100%" data-selected-text-format="static" data-live-search-placeholder="输入搜索或添加新分类" title="请选择">
                     {volist name="companyTypeOptions" id="vo"}
                     <option value="{$vo|htmlentities}">{$vo|htmlentities}</option>
                     {/volist}
                 </select>
                 <span class="input-group-addon" id="c-company_type_count" style="min-width:6.5em;text-align:center;">已选 0</span>
             </div>
-            <p class="help-block" style="margin-top:6px;">列表显示「无匹配」时,可将当前分类添加为新分类。</p>
+            <p class="help-block" style="margin-top:6px;">无匹配时列表会出现您输入的分类,点击即可选中;也可按回车添加。</p>
         </div>
     </div>
     <div class="form-group">

+ 2 - 2
application/admin/view/customer/edit.html

@@ -41,14 +41,14 @@
         <div class="col-xs-12 col-sm-8">
             <input type="hidden" name="row[company_type]" id="c-company_type" value="{$row.company_type|htmlentities}">
             <div class="input-group company-type-onebox">
-                <select id="c-company_type_select" class="form-control selectpicker" multiple data-live-search="true" data-width="100%" data-selected-text-format="static" data-live-search-placeholder="无匹配时按回车添加" title="请选择">
+                <select id="c-company_type_select" class="form-control selectpicker" multiple data-live-search="true" data-width="100%" data-selected-text-format="static" data-live-search-placeholder="输入搜索或添加新分类" title="请选择">
                     {volist name="companyTypeOptions" id="vo"}
                     <option value="{$vo|htmlentities}">{$vo|htmlentities}</option>
                     {/volist}
                 </select>
                 <span class="input-group-addon" id="c-company_type_count" style="min-width:6.5em;text-align:center;">已选 0</span>
             </div>
-            <p class="help-block" style="margin-top:6px;">列表显示「无匹配」时,可将当前分类添加为新分类。</p>
+            <p class="help-block" style="margin-top:6px;">无匹配时列表会出现您输入的分类,点击即可选中;也可按回车添加。</p>
         </div>
     </div>
     <div class="form-group">

+ 61 - 35
application/admin/view/procuremen/audit_issue.html

@@ -62,44 +62,57 @@
         vertical-align: middle;
         word-wrap: break-word;
     }
-    .audit-issue-wrap .audit-notify-pick-table td label {
+    .audit-issue-wrap .audit-quote-pick-table tbody tr {
+        cursor: pointer;
+    }
+    .audit-issue-wrap .audit-quote-pick-table td label {
         margin: 0;
         font-weight: normal;
         cursor: pointer;
     }
-    .audit-issue-wrap .audit-notify-pick-table tbody tr {
-        cursor: pointer;
+    .audit-issue-wrap .audit-quote-item {
+        margin-bottom: 6px;
+        font-size: 12px;
+        line-height: 1.5;
+    }
+    .audit-issue-wrap .audit-quote-item:last-child {
+        margin-bottom: 0;
     }
     .audit-issue-wrap .audit-deadline-row {
         display: flex;
-        align-items: center;
+        align-items: flex-start;
         flex-wrap: wrap;
         gap: 8px 12px;
         margin: 0 0 12px;
         font-size: 13px;
+        position: relative;
+        z-index: 61;
+        overflow: visible;
     }
     .audit-issue-wrap .audit-deadline-row .audit-field-label {
         font-weight: 600;
         color: #333;
         white-space: nowrap;
+        flex-shrink: 0;
+        margin: 7px 0 0;
     }
     .audit-issue-wrap .audit-deadline-input-wrap {
-        flex: 1 1 220px;
-        max-width: 300px;
+        position: relative;
+        flex: 0 0 auto;
+        z-index: 62;
     }
-    .audit-issue-wrap .audit-deadline-input-wrap .input-group-addon {
-        cursor: pointer;
-        background: #f9f9f9;
+    .audit-issue-wrap .audit-sys-rq-input {
+        width: 240px;
+        max-width: 240px;
+        min-width: 180px;
     }
-    .audit-issue-wrap .audit-deadline-input-wrap .form-control {
-        height: 32px;
-        font-size: 13px;
-        cursor: pointer;
-        background-color: #fff;
+    .audit-issue-wrap .audit-op-cell {
+        white-space: nowrap;
     }
-    body.is-dialog .bootstrap-datetimepicker-widget.dropdown-menu {
-        z-index: 19999999 !important;
-        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
+    .audit-issue-wrap .audit-op-cell .btn {
+        padding: 2px 7px;
+        font-size: 12px;
+        margin: 0 2px 2px 0;
     }
 </style>
 <div class="audit-issue-wrap">
@@ -140,48 +153,61 @@
     <form id="audit-issue-form" class="form-horizontal" role="form" style="margin-bottom:0;">
         {:token()}
         <input type="hidden" name="scydgy_id" value="{$scydgyId|htmlentities}"/>
-        <input type="hidden" id="audit-notify-groups-json" value="{$notifyGroupsJson|htmlentities}"/>
+        <input type="hidden" id="audit-quote-groups-json" value="{$quoteGroupsJson|htmlentities}"/>
         <div class="audit-deadline-row">
             <span class="audit-field-label">截止时间:<span class="text-danger">*</span></span>
-            <div class="audit-deadline-input-wrap input-group">
-                <input type="text" id="audit-sys-rq" name="sys_rq" class="form-control"
+            <div class="audit-deadline-input-wrap">
+                <input type="text" id="audit-sys-rq" name="sys_rq" class="form-control datetimepicker audit-sys-rq-input"
                        value="{$sysRq|default=''|htmlentities}"
                        data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true"
-                       placeholder="请选择年月日时分" autocomplete="off" required="required"/>
-                <span class="input-group-addon procuremen-sys-rq-addon" title="选择截止时间"><i class="fa fa-calendar"></i></span>
+                       placeholder="请选择年月日时分" autocomplete="off"/>
             </div>
         </div>
     </form>
     <p class="audit-notify-tip">
-        请勾选需要通知的供应商,点击「确认通知」后仅向已勾选项发送短信与邮件。本步骤发送后无法撤回,请仔细核对后再提交。
+        <i class="fa fa-exclamation-triangle"></i>
+        <strong>重要提示:</strong>请查看各供应商报价,<strong>选定唯一一家</strong>后点击「确认供应商」进入采购终审(本步<strong>任何发送短信通知</strong>)。
+        需再次提醒报价时,请在右侧<strong>操作</strong>列点击「发邮件」或「发短信」。
     </p>
     <div class="audit-table-wrap">
-        <table class="table table-bordered table-condensed audit-table audit-notify-pick-table">
+        <table class="table table-bordered table-condensed audit-table audit-quote-pick-table">
             <thead>
             <tr>
-                <th class="text-center" style="width:42px;">
-                    <input type="checkbox" id="audit-notify-check-all" title="全选/取消"/>
-                </th>
+                <th class="text-center" style="width:42px;">选定</th>
                 <th>公司名称</th>
                 <th style="width:88px;">联系人</th>
                 <th style="min-width:160px;">邮箱</th>
                 <th style="width:120px;">手机号</th>
-                <th style="min-width:200px;">通知工序</th>
+                <th style="min-width:200px;">报价工序</th>
+                <th class="text-center" style="width:120px;">操作</th>
             </tr>
             </thead>
-            <tbody id="audit-notify-tbody">
-            {volist name="notifyGroups" id="co" key="k"}
+            <tbody id="audit-quote-tbody">
+            {volist name="quoteGroups" id="co" key="k"}
             <tr>
                 <td class="text-center">
                     <label>
-                        <input type="checkbox" class="audit-notify-pick" name="audit_notify_pick[]" value="{$k-1}"/>
+                        <input type="radio" class="audit-quote-pick" name="audit_quote_pick" value="{$co.name|default=''|htmlentities}"
+                            {if condition="$pickedCompanyName neq '' && $pickedCompanyName eq $co.name"} checked="checked"{/if}/>
                     </label>
                 </td>
                 <td>{$co.name|default=''|htmlentities}</td>
                 <td>{$co.username|default=''|htmlentities}</td>
                 <td>{$co.email|default=''|htmlentities}</td>
                 <td>{$co.phone|default=''|htmlentities}</td>
-                <td>{$co.process_text|default=''|htmlentities}</td>
+                <td>
+                    {volist name="co.lines" id="ln"}
+                    <div class="audit-quote-item">
+                        <div>工序:{$ln.cgymc|default=''|htmlentities}</div>
+                        <div>单价:{if condition="$ln.amount_filled"}{$ln.amount_show|htmlentities}{else /}未填写{/if}</div>
+                        <div>交货日期:{if condition="$ln.delivery_filled"}{$ln.delivery_show|htmlentities}{else /}未填写{/if}</div>
+                    </div>
+                    {/volist}
+                </td>
+                <td class="text-center audit-op-cell">
+                    <button type="button" class="btn btn-default btn-xs audit-row-send-email" data-company="{$co.name|default=''|htmlentities}">发邮件</button>
+                    <button type="button" class="btn btn-default btn-xs audit-row-send-sms" data-company="{$co.name|default=''|htmlentities}">发短信</button>
+                </td>
             </tr>
             {/volist}
             </tbody>
@@ -190,10 +216,10 @@
     <div class="form-group layer-footer">
         <div class="row procuremen-audit-issue-footer-row">
             <div class="col-xs-12 procuremen-audit-issue-footer-btns">
-                <button type="button" style="margin-right: 20px" class="btn btn-primary btn-embossed" id="btn-audit-issue-submit">
-                    <i class="fa fa-paper-plane"></i> 确认通知
+                <button type="button" style="margin-right: 12px" class="btn btn-primary btn-embossed" id="btn-audit-issue-submit">
+                    <i class="fa fa-check"></i> 确认供应商
                 </button>
-                <button type="button" style="margin-right: 20px" class="btn btn-default btn-embossed" id="btn-audit-issue-close">
+                <button type="button" class="btn btn-default btn-embossed" id="btn-audit-issue-close">
                     <i class="fa fa-times"></i> 关闭
                 </button>
             </div>

+ 48 - 7
application/admin/view/procuremen/details_fragment.html

@@ -352,21 +352,61 @@
             <thead>
             <tr>
                 <th>公司名称</th>
-                <th>单价</th>
-                <th>交货日期</th>
-                <th>采购确认</th>
+                <th>工序名称</th>
+                <th class="text-center">单价</th>
+                <th class="text-center">交货日期</th>
+                <th class="text-center">小计</th>
+                <th class="text-center">采购确认</th>
                 <th>操作时间</th>
             </tr>
             </thead>
             <tbody>
+            {notempty name="supplierQuoteGroups"}
+            {volist name="supplierQuoteGroups" id="sg"}
+            {volist name="sg.lines" id="ln" key="lk"}
+            <tr{if !empty($sg.is_void)} class="text-muted"{/if}>
+                {if $lk == 1}
+                <td rowspan="{$sg.line_count|default='1'}" style="vertical-align:middle;">
+                    {$sg.company_name|default=''|htmlentities}
+                </td>
+                {/if}
+                <td>{$ln.cgymc|default=''|htmlentities}</td>
+                <td class="text-center">{$ln.unit_price_text|default=''|htmlentities}</td>
+                <td class="text-center">{$ln.delivery_ymd|default=''|htmlentities}</td>
+                <td class="text-center">{$ln.subtotal_text|default=''|htmlentities}</td>
+                <td class="text-center">
+                    {if !empty($ln.is_void)}
+                    <span class="label label-default">历史</span>
+                    {elseif $ln.status == 1 /}
+                    <span class="label label-success">已选</span>
+                    {else /}
+                    <span class="text-muted"> </span>
+                    {/if}
+                </td>
+                <td>{$ln.createtime_text|default=''|htmlentities}</td>
+            </tr>
+            {/volist}
+            {if !empty($sg.has_total)}
+            <tr class="active">
+                <td colspan="4" class="text-right"><strong>总计</strong></td>
+                <td class="text-center"><strong>{$sg.total_text|default=''|htmlentities}</strong></td>
+                <td colspan="2"></td>
+            </tr>
+            {/if}
+            {/volist}
+            {else /}
             {notempty name="detailRows"}
             {volist name="detailRows" id="dr"}
             <tr>
                 <td>{$dr.company_name|default=''|htmlentities}</td>
-                <td>{$dr.amount|default=''|htmlentities}</td>
-                <td>{$dr.delivery_ymd|default=''|htmlentities}</td>
+                <td></td>
+                <td class="text-center">{$dr.amount|default=''|htmlentities}</td>
+                <td class="text-center">{$dr.delivery_ymd|default=''|htmlentities}</td>
+                <td class="text-center"></td>
                 <td class="text-center">
-                    {if $dr.status == 1}
+                    {if isset($dr.is_void) && $dr.is_void}
+                    <span class="label label-default">历史下发</span>
+                    {elseif $dr.status == 1 /}
                     <span class="label label-success">已选</span>
                     {else /}
                     <span class="text-muted"> </span>
@@ -377,9 +417,10 @@
             {/volist}
             {else /}
             <tr>
-                <td colspan="6" class="text-center text-muted">暂无下发明细</td>
+                <td colspan="7" class="text-center text-muted">暂无下发明细</td>
             </tr>
             {/notempty}
+            {/notempty}
             </tbody>
         </table>
     </div>

+ 1 - 0
application/admin/view/procuremen/index.html

@@ -344,6 +344,7 @@
                             <div class="procuremen-table-area">
                                 <div id="toolbar" class="toolbar">
                                     <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" >刷新 <i class="fa fa-refresh"></i> </a>
+                                    <a href="javascript:;" class="btn btn-danger" id="btn-procuremen-audit-abandon" title="勾选一条或多条订单退回外发初选重新下发(历史记录保留)" style="display:none;"><i class="fa fa-repeat"></i> 重新下发</a>
                                     <a href="javascript:;" class="btn btn-info" id="btn-procuremen-pick-review" title="勾选一条或多条工序进行下发(多条须同一订单号)" style="display:none;"><i class="fa fa-paper-plane"></i> 下发</a>
                                     <a href="javascript:;" class="btn btn-warning" id="btn-procuremen-batch-finish" title="勾选一条或多条工序标记为已完结" style="display:none;"><i class="fa fa-flag-checkered"></i> 完结</a>
                                     <a href="javascript:;" class="btn btn-danger" id="btn-procuremen-pick-delete" title="勾选一条或多条工序从初选列表移除" style="display:none;"><i class="fa fa-trash"></i> 删除</a>

+ 5 - 3
application/admin/view/procuremen/outward_detail.html

@@ -176,7 +176,7 @@
     {/if}
 
     <p class="audit-notify-tip">
-        提示:本步骤发送后无法撤回,请仔细核对后再提交
+        审批通过将向中标供应商发送「已通过」短信、向未中标供应商发送「未通过」短信;审批驳回将退回「外发审批下发」并通知供应商
     </p>
     <p class="outward-confirm-block-title">供应商({$confirmPickCount|default=0} 家)</p>
     <div class="outward-confirm-company-wrap">
@@ -197,7 +197,8 @@
                 <td class="text-center">
                     <label>
                         <input type="checkbox" class="pod-company-pick-cb" name="pod_company_pick[]" value="{$k-1}"
-                               data-detail-picks="{$co.detail_picks_json|htmlentities}"/>
+                               data-detail-picks="{$co.detail_picks_json|htmlentities}"
+                               {if condition="$pickedCompanyName neq '' && $pickedCompanyName eq $co.name"} checked="checked"{/if}/>
                     </label>
                 </td>
                 <td>{$co.name|default=''|htmlentities}</td>
@@ -227,7 +228,8 @@
     <div class="form-group layer-footer">
         <div class="row procuremen-outward-confirm-footer-row">
             <div class="col-xs-12 procuremen-outward-confirm-footer-btns">
-                <button type="button" style="margin-right: 20px" class="btn procuremen-btn-slate btn-embossed" id="btn-pod-purchase-confirm"><i class="fa fa-check"></i> 确认</button>
+                <button type="button" style="margin-right: 20px" class="btn procuremen-btn-slate btn-embossed" id="btn-pod-purchase-confirm"><i class="fa fa-check"></i> 审批通过</button>
+                <button type="button" style="margin-right: 20px" class="btn btn-warning btn-embossed" id="btn-pod-purchase-reject"><i class="fa fa-undo"></i> 审批驳回</button>
                 <button type="button" style="margin-right: 20px" class="btn btn-default btn-embossed" id="btn-pod-purchase-close"><i class="fa fa-times"></i> 关闭</button>
             </div>
         </div>

+ 1 - 1
application/admin/view/procuremen/review.html

@@ -529,7 +529,7 @@
                 </div>
                 <p class="review-selected-tip procuremen-review-submit-tip" role="note">
                     <i class="fa fa-exclamation-triangle"></i>
-                    <strong>重要提示:</strong>本步骤仅保存下发并勾选供应商,<strong>不发送短信或邮件</strong>
+                    <strong>重要提示:</strong>确认后将向所选供应商<strong>发送短信与邮件</strong>,请仔细核对后再提交
                 </p>
             </div>
             <p class="review-selected-empty" id="review-selected-empty">暂未选择供应商</p>

+ 5 - 5
application/api/controller/Index.php

@@ -856,7 +856,7 @@ class Index extends Api{
             ->union(function ($query) {
                 $query->table('ql_report_feedback_day')->alias('a')->field('b.dOnduty,a.nsl ')
                     ->join(['scdayrpt_teams' => 'b'], 'b.ID=a.ID_Teams')
-                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','BB机05号','如钰01号机',
+                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','BB机05号','如钰01号机','如钰02号机',
                         'BB机06号','海德堡SM1号','海德堡SM2号']);
             }, true)->buildSql();
 
@@ -999,7 +999,7 @@ class Index extends Api{
             ->union(function ($query) {
                 $query->table('ql_report_feedback_day')->alias('a')->field('b.dOnduty,a.nzl ')
                     ->join(['scdayrpt_teams' => 'b'], 'b.ID=a.ID_Teams')
-                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','如钰01号机',
+                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','如钰01号机','如钰02号机',
                         'BB机05号','BB机06号','海德堡SM1号','海德堡SM2号']);
             }, true)->buildSql();
         $subQuery3_child = Db::table('bzysdayrpt')->field('drptrq AS rq,fsjls')
@@ -9348,7 +9348,7 @@ class Index extends Api{
          GROUP BY `rq` )) as B ON `A`.`RQ`=`B`.`rq` LEFT JOIN (( SELECT rq,SUM( iSjys ) nBBTotal,COUNT( 1 ) nBBPZ,SUM( fsjsl ) nBBSL
          FROM ( SELECT drptrq AS rq,`iSjys`,`fsjsl` FROM `bzysdayrpt` WHERE  `cbzmc` IN ('BB机1号(甲班)','BB机1号(乙班)','BB机2号(甲班)','BB机2号(乙班)','BB机3号(甲班)','BB机3号(乙班)','BB机4号(甲班)','BB机4号(乙班)','BB机5号(甲班)','BB机5号(乙班)','BB机6号(甲班)','BB机6号(乙班)','05机1号(甲班)','05机1号(乙班)','海德堡SM1号机(甲班)','海德堡SM1号机(乙班)','海德堡SM2号机(甲班)','海德堡SM2号机(乙班)')
          UNION ALL ( SELECT `b`.`dOnduty`,`a`.`nAmount`,`a`.`nsl` FROM `ql_report_feedback_day` `a` INNER JOIN `scdayrpt_teams` `b` ON `b`.`ID`=`a`.`ID_Teams`
-         WHERE  `cMachineName` IN ('如钰01号机','BB机01号','BB机02号','BB机04号','BB机05号','BB机06号','海德堡SM1号','海德堡SM2号') ) )T
+         WHERE  `cMachineName` IN ('如钰01号机','如钰02号机','BB机01号','BB机02号','BB机04号','BB机05号','BB机06号','海德堡SM1号','海德堡SM2号') ) )T
          GROUP BY `rq` )) as h ON `A`.`RQ`=`h`.`rq` LEFT JOIN (( SELECT rq,SUM( iSjys ) nRotationTotal,COUNT( 1 ) nRotationPZ,SUM( fsjsl ) nnRotationSL
          FROM ( SELECT drptrq AS rq,`iSjys`,`fsjsl` FROM `bzysdayrpt` WHERE  `cbzmc` IN ('小森LW-35(甲班)','小森LW-35(乙班)','小森2号机(甲班)','小森2号机(乙班)','大规小森3号机(甲班)','大规小森3号机(乙班)','三菱商轮(甲班)','三菱商轮(乙班)','三菱商轮2号(甲班)','三菱商轮2号(乙班)','204胶轮(甲班)','204胶轮(乙班)','V30(甲班)','V30(乙班)','报刊轮转(甲班)','报刊轮转(乙班)')
          UNION ALL ( SELECT `b`.`dOnduty`,`a`.`nAmount`,`a`.`nsl` FROM `ql_report_feedback_day` `a` INNER JOIN `scdayrpt_teams` `b` ON `b`.`ID`=`a`.`ID_Teams`
@@ -9901,7 +9901,7 @@ class Index extends Api{
             ->union(function ($query) {
                 $query->table('ql_report_feedback_day')->alias('a')->field('b.dOnduty,a.nAmount,a.nzl ')
                     ->join(['scdayrpt_teams' => 'b'], 'b.ID=a.ID_Teams')
-                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','如钰01号机',
+                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','如钰01号机','如钰02号机',
                         'BB机05号','BB机06号','海德堡SM1号','海德堡SM2号']);
             }, true)->buildSql();
 
@@ -10195,7 +10195,7 @@ class Index extends Api{
             ->union(function ($query) {
                 $query->table('ql_report_feedback_day')->alias('a')->field('b.dOnduty,a.nsl ')
                     ->join(['scdayrpt_teams' => 'b'], 'b.ID=a.ID_Teams')
-                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','BB机05号','如钰01号机',
+                    ->whereIn('cMachineName', ['BB机01号','BB机02号','BB机04号','BB机05号','如钰01号机','如钰02号机',
                         'BB机06号','海德堡SM1号','海德堡SM2号']);
             }, true)->buildSql();
 

+ 3 - 1
application/api/controller/Monthachines.php

@@ -736,7 +736,7 @@ WHERE  DATE_FORMAT(
                WHEN DATE_FORMAT(b.dOnDuty, '%H:%i') < '06:30' THEN DATE_SUB(b.dOnDuty, INTERVAL 1 DAY)
                ELSE b.dOnDuty 
            END, '%Y-%m-%d') BETWEEN '{$one}' AND '{$data}'
-       AND a.cMachineName IN ( 'BB机02号','BB机04号','BB机05号','海德堡SM1号','海德堡SM2号','如钰01号机') 
+       AND a.cMachineName IN ( 'BB机02号','BB机04号','BB机05号','海德堡SM1号','海德堡SM2号','如钰01号机','如钰02号机') 
 GROUP BY DATE_FORMAT(
             CASE 
                 WHEN DATE_FORMAT(b.dOnDuty, '%H:%i') < '06:30' THEN DATE_SUB(b.dOnDuty, INTERVAL 1 DAY)
@@ -769,6 +769,8 @@ ORDER BY DATE_FORMAT(
 
             '如钰01号机(乙班)' => '如钰1乙',
             '如钰01号机(甲班)' => '如钰1甲',
+            '如钰02号机(乙班)' => '如钰2乙',
+            '如钰02号机(甲班)' => '如钰2甲',
 
             '海德堡SM1号(乙班)' => 'SM1号乙',
             '海德堡SM1号(甲班)' => 'SM1号甲',

+ 1 - 0
application/api/controller/Third.php

@@ -1870,6 +1870,7 @@ WHERE   (iStop = 0)
     public function ys_schedule(){
         $redis = redis();
         $list = json_decode($redis->get(md5('ys_schedule_redis')), true);
+
         // 按排序顺序排序
         usort($list, function($a, $b) {
             return $a['排序'] - $b['排序'];

+ 2 - 2
application/database.php

@@ -15,13 +15,13 @@ use think\Env;
 return [
     // 数据库类型
     // 服务器地址
-    'hostname'        => Env::get('database.hostname', '121.40.91.170'),
+    'hostname'        => Env::get('database.hostname', 'rm-bp10xvfpe5c9kz119eo.mysql.rds.aliyuncs.com'),
     // 数据库名
     'database'        => Env::get('database.database', 'xinhua_erp'),
     // 用户名
     'username'        => Env::get('database.username', 'xinhua_erp'),
     // 密码
-    'password'        => Env::get('database.password', 'YiDxNKHBiAkTnRtb'),
+    'password'        => Env::get('database.password', 'D3#xJ9!sQ4%vU8'),
     // 端口
     'hostport'        => Env::get('database.hostport', ''),
     // 连接dsn

+ 0 - 28
application/extra/procuremen_workflow_patch.sql

@@ -1,28 +0,0 @@
--- 外发流程字段补丁(可重复执行思路:逐条执行,若报 Duplicate column 说明该列已有,跳过即可)
--- 先查看已有列:SHOW COLUMNS FROM `purchase_order` LIKE 'wflow%';
---              SHOW COLUMNS FROM `purchase_order` LIKE 'pick%';
---              SHOW COLUMNS FROM `purchase_order` LIKE 'audit%';
-
--- 以下每条单独选中执行;1060 Duplicate column = 已存在,换下一行
-
--- ALTER TABLE `purchase_order` ADD COLUMN `wflow_status` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT '0待初选1待审核2已下发' AFTER `status`;
--- ALTER TABLE `purchase_order` ADD COLUMN `pick_company_name` varchar(200) DEFAULT '' COMMENT '初选供应商' AFTER `wflow_status`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_contact_name` varchar(64) DEFAULT '' COMMENT '初选联系人' AFTER `pick_company_name`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_email` varchar(128) DEFAULT '' AFTER `pick_contact_name`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_phone` varchar(32) DEFAULT '' AFTER `pick_email`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_admin_id` int(10) unsigned NOT NULL DEFAULT 0 AFTER `pick_phone`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_admin_name` varchar(64) DEFAULT '' AFTER `pick_admin_id`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_time` datetime DEFAULT NULL AFTER `pick_admin_name`;
-ALTER TABLE `purchase_order` ADD COLUMN `audit_admin_id` int(10) unsigned NOT NULL DEFAULT 0 AFTER `pick_time`;
-ALTER TABLE `purchase_order` ADD COLUMN `audit_admin_name` varchar(64) DEFAULT '' AFTER `audit_admin_id`;
-ALTER TABLE `purchase_order` ADD COLUMN `audit_time` datetime DEFAULT NULL AFTER `audit_admin_name`;
-ALTER TABLE `purchase_order` ADD COLUMN `pick_companies_json` mediumtext COMMENT '初选候选供应商JSON' AFTER `pick_time`;
-
--- 已存在该列但类型过小(报 Data too long for column pick_companies_json)时执行:
-ALTER TABLE `purchase_order` MODIFY COLUMN `pick_companies_json` MEDIUMTEXT COMMENT '初选候选供应商JSON';
-
--- 历史数据迁移(只需执行一次;若已跑过可跳过)
--- UPDATE `purchase_order` po SET po.`wflow_status` = 2
--- WHERE po.`status` = 0 AND po.`wflow_status` = 0
---   AND EXISTS (SELECT 1 FROM `purchase_order_detail` d WHERE d.`scydgy_id` = po.`scydgy_id` LIMIT 1);
--- UPDATE `purchase_order` SET `wflow_status` = 2 WHERE `status` = 1 AND `wflow_status` = 0;

+ 4 - 10
application/index/controller/Index.php

@@ -856,13 +856,7 @@ class Index extends Frontend
     protected function mprocFetchProcuremenList(array $user, $tab, $q, $statusNameCol)
     {
         $query = Db::table('purchase_order_detail')->order('id', 'desc');
-        // 初选下发(wflow_status=1)仅落明细、尚未通知供应商,手机端不可见;audit 通知后 wflow_status>=2 才展示
-        try {
-            $query->whereRaw(
-                'NOT EXISTS (SELECT 1 FROM purchase_order po WHERE po.scydgy_id = purchase_order_detail.scydgy_id AND po.wflow_status = 1 LIMIT 1)'
-            );
-        } catch (\Throwable $e) {
-        }
+        // 初选下发已向供应商发送通知后,手机端可见 wflow_status>=1 的明细
         $userWhere = $this->mprocListWhereForLoginUser($user);
         if ($userWhere !== []) {
             $query->where($userWhere);
@@ -1385,7 +1379,7 @@ class Index extends Frontend
         }
         if (!$this->mprocCanEditRow($user, $row)) {
             if (!empty($user['is_admin'])) {
-                $this->error('当前账号仅可查看,不能修改金额与交货日期');
+                $this->error('当前账号仅可查看,不能修改单价与交货日期');
             }
             $this->error('无权修改该记录');
         }
@@ -1398,11 +1392,11 @@ class Index extends Frontend
             $data['amount'] = null;
         } else {
             if (!preg_match('/^-?\d+(\.\d{1,5})?$/', $amountRaw)) {
-                $this->error('金额格式不正确,最多五位小数');
+                $this->error('单价格式不正确,最多五位小数');
             }
             $ceilingLimit = $this->mprocResolveCeilingPriceForDetailRow($row);
             if ($ceilingLimit !== null && (float)$amountRaw > $ceilingLimit) {
-                $this->error('金额不能超过最高限价 ' . $this->mprocFormatCeilingPriceDisplay($ceilingLimit));
+                $this->error('单价不能超过最高限价 ' . $this->mprocFormatCeilingPriceDisplay($ceilingLimit));
             }
             $data['amount'] = $amountRaw;
         }

+ 7 - 7
application/index/view/index/index.html

@@ -263,11 +263,11 @@
         <div class="kv"><span>工序名称</span>{$r.CGYMC|default=''|htmlentities}</div>
         <div class="kv"><span>本次数量</span>{$r.mproc_this_quantity_display|default=''|htmlentities}</div>
         <div class="kv"><span>最高限价</span>{$r.ceilingPrice|default=''|htmlentities}</div>
-        <div class="kv"><span>金额</span>{if $r.amount_missing}<span class="kv-miss">未填写</span>{else /}{$r.amount_display|htmlentities}{/if}</div>
+        <div class="kv"><span>单价</span>{if $r.amount_missing}<span class="kv-miss">未填写</span>{else /}{$r.amount_display|htmlentities}{/if}</div>
         <div class="kv"><span>交货日期</span>{if $r.delivery_missing}<span class="kv-miss">未填写</span>{else /}{$r.delivery_display|htmlentities}{/if}</div>
         <div class="card-foot">
             {if $r.mproc_can_edit}
-            <button type="button" class="btn-edit js-open-edit" data-stop="1">填写金额 / 交货日期</button>
+            <button type="button" class="btn-edit js-open-edit" data-stop="1">填写单价 / 交货日期</button>
             {/if}
         </div>
     </div>
@@ -321,7 +321,7 @@
     <div class="modal-sheet" id="edit-sheet">
         <p class="modal-head" id="edit-sheet-title">编辑</p>
         <div class="modal-field">
-            <label for="inp-amount">金额</label>
+            <label for="inp-amount">单价</label>
             <input type="text" id="inp-amount" inputmode="decimal" autocomplete="off" maxlength="24">
             <p class="modal-ceil-hint" id="edit-ceil-hint" style="display:none;"></p>
         </div>
@@ -495,7 +495,7 @@
             return '';
         }
         if (amt > ceil) {
-            return '金额不能超过最高限价 ' + String(ceilingStr).trim();
+            return '单价不能超过最高限价 ' + String(ceilingStr).trim();
         }
         return '';
     }
@@ -540,10 +540,10 @@
                 + '<div class="kv"><span>工序名称</span>' + mprocEsc(pick(r, ['CGYMC', 'cgymc'])) + '</div>'
                 + '<div class="kv"><span>本次数量</span>' + mprocEsc(thisQty) + '</div>'
                 + '<div class="kv"><span>最高限价</span>' + mprocEsc(ceilP) + '</div>'
-                + '<div class="kv"><span>金额</span>' + mprocAmountLineHtml(r) + '</div>'
+                + '<div class="kv"><span>单价</span>' + mprocAmountLineHtml(r) + '</div>'
                 + '<div class="kv"><span>交货日期</span>' + mprocDeliveryLineHtml(r) + '</div>'
                 + (function () {
-                    var btn = canEdit ? '<button type="button" class="btn-edit js-open-edit" data-stop="1">填写金额 / 交货日期</button>' : '';
+                    var btn = canEdit ? '<button type="button" class="btn-edit js-open-edit" data-stop="1">填写单价 / 交货日期</button>' : '';
                     return '<div class="card-foot">' + btn + '</div>';
                 })()
                 + '</div>';
@@ -712,7 +712,7 @@
         }
         var ceilN = mprocParseCeilingPrice(currentCeilingPrice);
         if (ceilN !== null) {
-            mprocShowCeilHint('最高限价 ' + currentCeilingPrice + ',金额不可超过该限价', false);
+            mprocShowCeilHint('最高限价 ' + currentCeilingPrice + ',单价不可超过该限价', false);
         } else {
             mprocShowCeilHint('', false);
         }

+ 125 - 35
public/assets/js/backend/customer.js

@@ -23,6 +23,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             '.company-type-onebox > .input-group-addon{flex:0 0 auto;display:flex;align-items:center;}' +
             '.company-type-onebox .bootstrap-select.open{z-index:1065;}' +
             '.company-type-onebox .bootstrap-select .dropdown-menu{margin-top:0 !important;}' +
+            '.company-type-onebox .bootstrap-select li.company-type-add-li a{cursor:pointer;}' +
+            '.company-type-onebox .bootstrap-select li.company-type-add-li a .text{color:#337ab7;}' +
             '</style>'
         );
     }
@@ -191,52 +193,140 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         if (!sp || !sp.$searchbox || !sp.$searchbox.length) {
                             return;
                         }
-                        sp.$searchbox.off('keydown.companyct').on('keydown.companyct', function (e) {
-                            if (e.which !== 13) {
+
+                        function getSearchQuery() {
+                            return $.trim(sp.$searchbox.val());
+                        }
+
+                        function hasExactOption(q) {
+                            return $sel.find('option').filter(function () {
+                                return $(this).val() === q;
+                            }).length > 0;
+                        }
+
+                        function optionTextMatches(text, q) {
+                            text = String(text || '').toLowerCase();
+                            q = String(q || '').toLowerCase();
+                            return q !== '' && text.indexOf(q) !== -1;
+                        }
+
+                        function hasMatchingOption(q) {
+                            var matched = false;
+                            $sel.find('option').each(function () {
+                                var $opt = $(this);
+                                var val = String($opt.val() || '');
+                                var txt = String($opt.text() || '');
+                                if (optionTextMatches(txt, q) || optionTextMatches(val, q)) {
+                                    matched = true;
+                                    return false;
+                                }
+                            });
+                            return matched;
+                        }
+
+                        function getMenuInner() {
+                            if (!sp.$menu || !sp.$menu.length) {
+                                return $();
+                            }
+                            var $inner = sp.$menu.find('ul.dropdown-menu.inner');
+                            if (!$inner.length) {
+                                $inner = sp.$menu.find('.inner');
+                            }
+                            return $inner;
+                        }
+
+                        function getMenuItems() {
+                            return sp.$menu ? sp.$menu.find('li:not(.divider):not(.dropdown-header)') : $();
+                        }
+
+                        function selectCompanyTypeValue(q) {
+                            if (!q) {
                                 return;
                             }
-                            var $box = $(this);
-                            var q = $.trim($box.val());
+                            if (!hasExactOption(q)) {
+                                $sel.append($('<option>').attr('value', q).text(q));
+                                $sel.selectpicker('refresh');
+                            }
+                            var cur = $sel.selectpicker('val') || [];
+                            if (!$.isArray(cur)) {
+                                cur = cur ? [cur] : [];
+                            }
+                            if ($.inArray(q, cur) === -1) {
+                                cur.push(q);
+                                $sel.selectpicker('val', cur);
+                            }
+                            syncHidden();
+                            updateCount();
+                        }
+
+                        function syncCompanyTypeSearchMenu() {
+                            var q = getSearchQuery();
+                            var $inner = getMenuInner();
+                            sp.$menu.find('li.company-type-add-li').remove();
+
                             if (!q) {
+                                getMenuItems().show();
+                                sp.$menu.find('li.no-results').hide();
                                 return;
                             }
-                            var hasOption = $sel.find('option').filter(function () {
-                                return $(this).val() === q;
-                            }).length > 0;
-                            var noResultsVisible = sp.$menu && sp.$menu.find('li.no-results').is(':visible');
 
-                            if (hasOption) {
-                                e.preventDefault();
-                                var cur = $sel.selectpicker('val');
-                                if (!$.isArray(cur)) {
-                                    cur = cur ? [cur] : [];
-                                }
-                                if ($.inArray(q, cur) === -1) {
-                                    cur.push(q);
-                                    $sel.selectpicker('val', cur);
-                                    syncHidden();
-                                    updateCount();
-                                }
-                                $box.val('').trigger('input');
+                            if (hasMatchingOption(q)) {
+                                getMenuItems().each(function () {
+                                    var $li = $(this);
+                                    if ($li.hasClass('no-results')) {
+                                        return;
+                                    }
+                                    var txt = $li.find('span.text').first().text();
+                                    $li.toggle(optionTextMatches(txt, q));
+                                });
+                                sp.$menu.find('li.no-results').toggle(getMenuItems().filter(':visible:not(.no-results)').length === 0);
                                 return;
                             }
-                            if (noResultsVisible) {
+
+                            getMenuItems().hide();
+                            var $li = $('<li class="company-type-add-li"><a role="option" tabindex="0" class="opt"><span class="text"></span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>');
+                            $li.find('span.text').text(q);
+                            $li.on('mousedown.companyct', function (e) {
                                 e.preventDefault();
-                                $sel.append($('<option>').val(q).text(q));
-                                $sel.selectpicker('refresh');
-                                var cur2 = $sel.selectpicker('val') || [];
-                                if (!$.isArray(cur2)) {
-                                    cur2 = cur2 ? [cur2] : [];
-                                }
-                                if ($.inArray(q, cur2) === -1) {
-                                    cur2.push(q);
-                                }
-                                $sel.selectpicker('val', cur2);
-                                syncHidden();
-                                updateCount();
-                                $box.val('').trigger('input');
+                                e.stopPropagation();
+                            });
+                            $li.on('click.companyct', function (e) {
+                                e.preventDefault();
+                                e.stopPropagation();
+                                selectCompanyTypeValue(q);
+                                sp.$searchbox.val('');
+                                syncCompanyTypeSearchMenu();
+                            });
+                            $inner.append($li);
+                        }
+
+                        sp.$searchbox.off('input.companyct keyup.companyct').on('input.companyct keyup.companyct', function () {
+                            setTimeout(syncCompanyTypeSearchMenu, 0);
+                        });
+
+                        sp.$searchbox.off('keydown.companyct').on('keydown.companyct', function (e) {
+                            if (e.which !== 13) {
+                                return;
+                            }
+                            var q = getSearchQuery();
+                            if (!q) {
+                                return;
+                            }
+                            e.preventDefault();
+                            if (hasMatchingOption(q) && hasExactOption(q)) {
+                                selectCompanyTypeValue(q);
+                                sp.$searchbox.val('');
+                                syncCompanyTypeSearchMenu();
+                                return;
+                            }
+                            if (!hasMatchingOption(q)) {
+                                selectCompanyTypeValue(q);
+                                sp.$searchbox.val('');
+                                syncCompanyTypeSearchMenu();
                             }
                         });
+
+                        syncCompanyTypeSearchMenu();
                     });
 
                     $('form[role=form]').off('submit.companyct').on('submit.companyct', function () {

+ 411 - 213
public/assets/js/backend/procuremen.js

@@ -229,12 +229,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 }
             });
             try {
-                table.bootstrapTable(stagePick ? 'showColumn' : 'hideColumn', 'state');
+                table.bootstrapTable((stagePick || stageAudit) ? 'showColumn' : 'hideColumn', 'state');
             } catch (ignore) {
             }
             $('#btn-procuremen-pick-review').toggle(stagePick);
             $('#btn-procuremen-pick-delete').toggle(stagePick);
             $('#btn-procuremen-batch-finish').toggle(stagePick);
+            $('#btn-procuremen-audit-abandon').toggle(stageAudit);
 
             $(document).off('click.procuremenYm', '.procuremen-ym-item').on('click.procuremenYm', '.procuremen-ym-item', function () {
                 var ym = $(this).data('ym');
@@ -314,7 +315,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
 
             var indexInitWffTab = Controller.wffTab;
-            var indexShowall = indexInitWffTab === 'pick';
+            var indexShowall = indexInitWffTab === 'pick' || indexInitWffTab === 'audit';
             var indexShowIssued = indexInitWffTab === 'audit' || indexInitWffTab === 'confirm';
             var indexShowPendingOnly = indexInitWffTab === 'confirm';
             var indexShowPickedOnly = indexInitWffTab === 'confirm';
@@ -325,6 +326,27 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     .replace(/"/g, '&quot;')
                     .replace(/'/g, '&#39;');
             }
+            function procuremenEscHtml(s) {
+                return String(s == null ? '' : s)
+                    .replace(/&/g, '&amp;')
+                    .replace(/</g, '&lt;')
+                    .replace(/>/g, '&gt;')
+                    .replace(/"/g, '&quot;');
+            }
+            function procuremenAutocontentCell(value, colWidth) {
+                if (value == null || value === '') {
+                    return '';
+                }
+                var text = String(value).replace(/\r\n/g, '\n').replace(/\n+/g, ';').trim();
+                if (text === '') {
+                    return '';
+                }
+                var width = colWidth != null && colWidth !== '' ? String(colWidth) : '250';
+                if (/^\d+$/.test(width)) {
+                    width = width + 'px';
+                }
+                return "<div class='autocontent-item' style='white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:" + width + ";'>" + procuremenEscHtml(text) + '</div>';
+            }
             var indexTableColumns = [
                 {checkbox: true, field: 'state', visible: indexShowall, align: 'center', width: 42, class: 'procuremen-col-checkbox'},
                 // {field: 'ID', title: __('ID'), operate: 'LIKE', table: 'a', width: 100, align: 'center',
@@ -348,7 +370,22 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     }
                 },
                 {field: 'CDW', title: __('单位'), operate: 'LIKE', table: 'a', width: 50, align: 'center'},
-                {field: 'NGZL', title: __('工作量'), operate: 'LIKE', table: 'a', width: 80, align: 'center'},
+                {field: 'NGZL', title: __('工作量'), operate: 'LIKE', table: 'a', width: 80, align: 'center',
+                    formatter: function (v) {
+                        if (v == null || v === '') {
+                            return '';
+                        }
+                        var s = String(v).trim();
+                        if (s === '') {
+                            return '';
+                        }
+                        var n = parseFloat(s);
+                        if (!isNaN(n) && n === 0) {
+                            return '';
+                        }
+                        return s;
+                    }
+                },
                 {field: 'This_quantity', title: '本次数量', operate: 'LIKE', table: 'a', width: 96, align: 'center',
                     visible: true,
                     formatter: function (v, row, index) {
@@ -386,10 +423,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     visible: indexShowAuditSuppliers,
                     class: 'autocontent',
                     formatter: function (v) {
-                        if (v == null || v === '') {
-                            return '';
-                        }
-                        return procuremenEscAttr(String(v));
+                        return procuremenAutocontentCell(v, this.width || 240);
                     }
                 },
                 {field: 'po_detail_count',title: '已下发数量',operate: false,table: 'a',width: 96,align: 'center',
@@ -412,13 +446,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 },
                 {field: 'picked_supplier_name', title: '报价供应商', operate: 'LIKE', table: 'a', width: 260, align: 'left',
                     visible: indexShowPickedOnly,
+                    class: 'autocontent',
                     formatter: function (v) {
-                        if (v == null || v === '') {
-                            return '';
-                        }
-                        return String(v).split('\n').map(function (line) {
-                            return procuremenEscAttr(line);
-                        }).join('<br>');
+                        return procuremenAutocontentCell(v, this.width || 260);
                     }
                 },
                 {field: 'CDF', title: __('订法'), operate: 'LIKE', table: 'a', width: 100, align: 'center'},
@@ -427,7 +457,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 {field: 'cywyxm', title: __('业务员'), operate: 'LIKE', table: 'b', width: 80, align: 'center'},
                 {field: 'dStamp', title: __('操作日期'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false, table: 'a', width: 165, align: 'center'},
                 {field: 'dputrecord', title: __('提交日期'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false, table: 'b', width: 170, align: 'center'},
-                {field: 'operate',title: '操作',width: 200,align: 'center',fixed: 'right', operate: false,
+                {field: 'operate',title: '操作',width: 220,align: 'center',fixed: 'right', operate: false,
                     visible: indexInitWffTab !== 'pick',
                     table: table,
                     formatter: function (value, row, index) {
@@ -446,7 +476,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                             parts.push('<a class="btn btn-xs btn-primary procuremen-op-open procuremen-btn-audit-issue"' + areaAudit + ' href="procuremen/auditissue" data-row-index="' + index + '" title="确认供应商"><i class="fa fa-check"></i> 确认供应商</a>');
                             parts.push('<a class="btn btn-xs btn-info procuremen-op-open procuremen-btn-details"' + areaDetails + ' href="procuremen/details" data-row-index="' + index + '" title="详情"><i class="fa fa-file-text-o"></i> 详情</a>');
                         } else if (tab === 'confirm') {
-                            parts.push('<a class="btn btn-xs btn-success procuremen-op-open procuremen-btn-outward"' + areaConfirmOutward + ' href="procuremen/outward_detail?wff_tab=confirm" data-row-index="' + index + '" title="采购确认"><i class="fa fa-shopping-cart"></i> 采购确认</a>');
+                            parts.push('<a class="btn btn-xs btn-success procuremen-op-open procuremen-btn-outward"' + areaConfirmOutward + ' href="procuremen/outward_detail?wff_tab=confirm" data-row-index="' + index + '" title="审批"><i class="fa fa-gavel"></i> 审批</a>');
                             parts.push('<a class="btn btn-xs btn-info procuremen-op-open procuremen-btn-details"' + areaDetails + ' href="procuremen/details" data-row-index="' + index + '" title="详情"><i class="fa fa-file-text-o"></i> 详情</a>');
                         }
                         return '<div class="btn-group">' + parts.join(' ') + '</div>';
@@ -630,6 +660,59 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 var selPick = procuremenRowsWithPoInputs(table.bootstrapTable('getSelections') || []);
                 procuremenOpenPickReview(selPick);
             });
+            $(document).off('click.procuremenAuditAbandon', '#btn-procuremen-audit-abandon').on('click.procuremenAuditAbandon', '#btn-procuremen-audit-abandon', function (e) {
+                e.preventDefault();
+                if (Controller.wffTab !== 'audit') {
+                    Toastr.warning('重新下发仅在外发审批下发列表可用');
+                    return;
+                }
+                var selAb = table.bootstrapTable('getSelections') || [];
+                if (!selAb.length) {
+                    Toastr.warning('请先勾选至少 1 条订单');
+                    return;
+                }
+                var idSet = {};
+                var rowsHtml = '<table class="table table-bordered table-condensed" style="margin:8px 0 0;font-size:12px;">'
+                    + '<thead><tr><th>订单号</th><th>工序名称</th><th>印件名称</th></tr></thead><tbody>';
+                $.each(selAb, function (ai, ra) {
+                    var sid = ra && (ra.ID != null ? ra.ID : ra.id);
+                    if (sid != null && sid !== '' && String(sid) !== '0') {
+                        idSet[String(sid)] = true;
+                    }
+                    rowsHtml += '<tr><td>' + procuremenEscHtml(String(ra.CCYDH || '').trim() || '—') + '</td>'
+                        + '<td>' + procuremenEscHtml(String(ra.CGYMC || '').trim() || '—') + '</td>'
+                        + '<td>' + procuremenEscHtml(String(ra.CYJMC || '').trim() || '—') + '</td></tr>';
+                });
+                rowsHtml += '</tbody></table>';
+                var idList = Object.keys(idSet);
+                if (!idList.length) {
+                    Toastr.warning('所选行无效,请重新勾选');
+                    return;
+                }
+                var abandonMsg = '<div style="text-align:left;line-height:1.65;font-size:13px;">'
+                    + '<p style="margin:0 0 8px 0;">即将退回外发初选并重新下发以下 <strong>' + idList.length + '</strong> 个订单(历史下发与操作记录会保留):</p>'
+                    + rowsHtml
+                    + '<p style="margin:10px 0 0;color:#a94442;"><strong>提示:</strong>退回后需重新选择供应商下发。</p></div>';
+                Layer.confirm(abandonMsg, {
+                    title: '重新下发确认',
+                    area: ['560px', 'auto'],
+                    icon: 3,
+                    btn: ['确认重新下发', '取消']
+                }, function (idxAb) {
+                    Layer.close(idxAb);
+                    Fast.api.ajax({
+                        url: 'procuremen/auditabandon',
+                        type: 'POST',
+                        data: {
+                            scydgy_ids_json: JSON.stringify(idList),
+                            __token__: $('input[name=\'__token__\']').val() || Config.token
+                        }
+                    }, function (data, ret) {
+                        table.bootstrapTable('refresh');
+                        return false;
+                    });
+                });
+            });
             $(document).off('click.procuremenPickDelete', '#btn-procuremen-pick-delete').on('click.procuremenPickDelete', '#btn-procuremen-pick-delete', function (e) {
                 e.preventDefault();
                 if (Controller.wffTab !== 'pick') {
@@ -874,7 +957,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 procuremenPoPopoverPosition($inp);
             }
             function procuremenSavePoRow(rowIdx) {
-                if (Controller.wffTab !== 'pick') {
+                if (Controller.wffTab !== 'pick' && Controller.wffTab !== 'audit') {
                     return;
                 }
                 var v = procuremenPoRowValues(rowIdx);
@@ -945,7 +1028,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     procuremenSavePoRow(procuremenPoActiveRow);
                 });
             $(document).off('mousedown.procuremenPoPopClose').on('mousedown.procuremenPoPopClose', function (e) {
-                if (Controller.wffTab !== 'pick') {
+                if (Controller.wffTab !== 'pick' && Controller.wffTab !== 'audit') {
                     return;
                 }
                 var $t = $(e.target);
@@ -1136,7 +1219,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
             table.on('post-body.bs.table', function () {
                 $('#procuremen-toolbar-host .btn-refresh .fa').removeClass('fa-spin');
-                if (Controller.wffTab !== 'pick') {
+                if (Controller.wffTab !== 'pick' && Controller.wffTab !== 'audit') {
                     return;
                 }
                 /* FastAdmin 每次 post-body 会重复绑定复选框列拖拽,多次勾选后易错位/缺框 */
@@ -1154,7 +1237,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
             if ($bt.length) {
                 $bt.off('click.procuremenCbTd', 'tbody td.bs-checkbox').on('click.procuremenCbTd', 'tbody td.bs-checkbox', function (e) {
-                    if (Controller.wffTab !== 'pick' || $(e.target).is('input[type="checkbox"]')) {
+                    if ((Controller.wffTab !== 'pick' && Controller.wffTab !== 'audit') || $(e.target).is('input[type="checkbox"]')) {
                         return;
                     }
                     var $inp = $(this).find('input[name="btSelectItem"]:not(:disabled)').first();
@@ -1555,7 +1638,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
 
                 Lr.confirm(confirmHtml, {
                     icon: 3,
-                    title: '采购确认 — 短信通知',
+                    title: '采购终审 — 审批通过',
                     area: ['480px', 'auto'],
                     offset: 'auto',
                     btn: ['确定提交', '取消'],
@@ -1598,6 +1681,51 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     });
                 });
             });
+            $wrap.on('click.procuremenPurchaseConfirm', '#btn-pod-purchase-reject', function () {
+                var rejectPicks = requiredSids.map(function (sid) {
+                    return {scydgy_id: String(sid)};
+                });
+                if (!rejectPicks.length) {
+                    rejectPicks = [{scydgy_id: scydgyId}];
+                }
+                var Lr = procuremenLayerTop();
+                if (!Lr || typeof Lr.confirm !== 'function') {
+                    Toastr.error('弹层组件未就绪,请刷新后重试');
+                    return;
+                }
+                Lr.confirm(
+                    '驳回后本单将退回「外发审批下发」,并向相关供应商发送驳回短信。是否确认驳回?',
+                    {
+                        icon: 0,
+                        title: '采购终审 — 审批驳回',
+                        area: ['460px', 'auto'],
+                        btn: ['确认驳回', '取消'],
+                        zIndex: procuremenLayerNextZIndex()
+                    },
+                    function (idx) {
+                        Lr.close(idx);
+                        FastRef.api.ajax({
+                            url: FastRef.api.fixurl('procuremen/purchaseApprovalReject'),
+                            type: 'POST',
+                            data: {
+                                __token__: $('input[name=\'__token__\']').val() || $wrap.find('input[name=\'__token__\']').val(),
+                                order_picks_json: JSON.stringify(rejectPicks)
+                            }
+                        }, function () {
+                            if (typeof parent !== 'undefined' && parent.Layer) {
+                                var ix = parent.Layer.getFrameIndex(window.name);
+                                if (typeof ix !== 'undefined') {
+                                    parent.Layer.close(ix);
+                                }
+                            }
+                            var p$ = (typeof parent !== 'undefined' && parent.jQuery) ? parent.jQuery : (typeof parent !== 'undefined' ? parent.$ : null);
+                            if (p$ && p$('#table').length) {
+                                p$('#table').bootstrapTable('refresh');
+                            }
+                        });
+                    }
+                );
+            });
             $wrap.on('click.procuremenPurchaseConfirm', '#btn-pod-purchase-close', function () {
                 if (typeof parent !== 'undefined' && parent.Layer) {
                     var ixClose = parent.Layer.getFrameIndex(window.name);
@@ -1618,6 +1746,126 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
 
         review: function () {
             Controller.api.bindevent();
+            procuremenBindSysRqPicker('#review-sys-rq', 'reviewSysRq');
+
+            function procuremenReviewWarn(msg) {
+                if (typeof Toastr !== 'undefined') {
+                    Toastr.warning(msg);
+                } else if (typeof Layer !== 'undefined') {
+                    Layer.msg(msg);
+                }
+            }
+
+            function procuremenReviewIsPickMode() {
+                if (/pickreview/i.test((window.location.pathname || '') + (window.location.search || ''))) {
+                    return true;
+                }
+                var $form = $('#review-form');
+                var pm = $form.attr('data-pick-mode');
+                if (pm === '1') {
+                    return true;
+                }
+                pm = $form.data('pickMode');
+                if (pm === 1 || pm === '1') {
+                    return true;
+                }
+                pm = $form.data('pick-mode');
+                return pm === 1 || pm === '1';
+            }
+
+            function procuremenReviewCollectSelected() {
+                var selected = [];
+                var seen = {};
+                $('#review-company-tbody .review-company-cb:checked').each(function () {
+                    var c = $(this).data('company');
+                    if (!c || typeof c !== 'object') {
+                        return;
+                    }
+                    var k = [String(c.email || ''), String(c.phone || ''), String(c.name || c.company_name || '')].join('\x01');
+                    if (k && seen[k]) {
+                        return;
+                    }
+                    if (k) {
+                        seen[k] = true;
+                    }
+                    selected.push(c);
+                });
+                return selected;
+            }
+
+            $(document).off('click.procuremenReviewSubmit', '#btn-review-submit').on('click.procuremenReviewSubmit', '#btn-review-submit', function (e) {
+                e.preventDefault();
+                e.stopPropagation();
+                var $rq = $('#review-sys-rq');
+                if ($rq.length && $rq.data('DateTimePicker')) {
+                    try {
+                        $rq.data('DateTimePicker').hide();
+                    } catch (ignoreHidePicker) {
+                    }
+                }
+                var isPickMode = procuremenReviewIsPickMode();
+                var selected = procuremenReviewCollectSelected();
+                if (!selected.length) {
+                    procuremenReviewWarn(isPickMode ? '请至少选择一家合作供应商' : '请至少选择一个下发单位');
+                    return;
+                }
+                var sysRq = ($rq.val() || '').trim();
+                if (!sysRq) {
+                    procuremenReviewWarn('请选择截止时间');
+                    $rq.focus();
+                    return;
+                }
+                var cons;
+                try {
+                    cons = JSON.parse($('#c-row-json').val() || '{}');
+                } catch (ignoreParseRow) {
+                    cons = {};
+                }
+                var mergePayload = ($('#c-merge-rows-json').val() || '').trim();
+                if (!mergePayload) {
+                    mergePayload = JSON.stringify([cons]);
+                }
+                var $submitBtn = $('#btn-review-submit');
+                if ($submitBtn.prop('disabled')) {
+                    return;
+                }
+                var submitBtnHtml = $submitBtn.html();
+                $submitBtn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 提交中…');
+                Fast.api.ajax({
+                    url: Fast.api.fixurl(isPickMode ? 'procuremen/picksubmit' : 'procuremen/review'),
+                    type: 'POST',
+                    data: {
+                        __token__: $('input[name=\'__token__\']').val(),
+                        row_json: JSON.stringify(cons),
+                        merge_rows_json: mergePayload,
+                        companies_json: JSON.stringify(selected),
+                        sys_rq: sysRq
+                    }
+                }, function (data, ret) {
+                    var msg = (ret && ret.msg) ? ret.msg : '操作成功';
+                    try {
+                        sessionStorage.removeItem('procuremen_merge_rows');
+                    } catch (ignoreClr) {
+                    }
+                    var index = parent.Layer.getFrameIndex(window.name);
+                    if (typeof parent !== 'undefined' && parent.Layer && index) {
+                        parent.Layer.close(index);
+                    }
+                    if (typeof parent !== 'undefined' && parent.Toastr) {
+                        parent.Toastr.success(msg);
+                    } else if (typeof Toastr !== 'undefined') {
+                        Toastr.success(msg);
+                    }
+                    if (parent && parent.$ && parent.$('#table').length) {
+                        parent.$('#table').bootstrapTable('refresh', {silent: true});
+                    }
+                    return false;
+                }, function () {
+                    $submitBtn.prop('disabled', false).html(submitBtnHtml);
+                    return false;
+                });
+            });
+
             function procuremenReviewCloseLayer() {
                 try {
                     if (typeof parent !== 'undefined' && parent.Layer) {
@@ -1653,82 +1901,35 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 e.preventDefault();
                 procuremenReviewCloseLayer();
             });
-            require(['bootstrap-datetimepicker'], function () {
-                var $el = $('#review-sys-rq');
-                if (!$el.length) {
-                    return;
-                }
-                var placePickerBesideInput = function () {
-                    var picker = $el.data('DateTimePicker');
-                    if (!picker || !picker.widget) {
-                        return;
-                    }
-                    var $w = picker.widget;
-                    var rect = $el[0].getBoundingClientRect();
-                    var gap = 12;
-                    var top = rect.top;
-                    var left = rect.right + gap;
-                    var widgetW = $w.outerWidth() || 300;
-                    var widgetH = $w.outerHeight() || 320;
-                    var vw = window.innerWidth || document.documentElement.clientWidth;
-                    var vh = window.innerHeight || document.documentElement.clientHeight;
-                    if (left + widgetW > vw - 8) {
-                        left = Math.max(8, rect.left);
-                        top = rect.bottom + 6;
-                    }
-                    if (top + widgetH > vh - 8) {
-                        top = Math.max(8, rect.top - widgetH - 6);
-                    }
-                    $w.appendTo(document.body).css({
-                        position: 'fixed',
-                        top: top + 'px',
-                        left: left + 'px',
-                        right: 'auto',
-                        bottom: 'auto',
-                        display: 'block',
-                        margin: 0
-                    });
-                };
-                var bindPickerFloat = function (attempt) {
-                    if ($el.data('DateTimePicker')) {
-                        $el.off('dp.show.reviewSysRq dp.update.reviewSysRq focus.reviewSysRq click.reviewSysRq')
-                            .on('dp.show.reviewSysRq dp.update.reviewSysRq', function () {
-                                setTimeout(placePickerBesideInput, 0);
-                            })
-                            .on('focus.reviewSysRq click.reviewSysRq', function () {
-                                var picker = $el.data('DateTimePicker');
-                                if (picker) {
-                                    picker.show();
-                                }
-                            });
-                        return;
-                    }
-                    if (attempt < 30) {
-                        setTimeout(function () {
-                            bindPickerFloat(attempt + 1);
-                        }, 50);
-                    }
-                };
-                bindPickerFloat(0);
-            });
+            var isPickReviewEntry = /pickreview/i.test((window.location.pathname || '') + (window.location.search || ''));
             var ids = window.Fast && Fast.api ? Fast.api.query('ids') : null;
             if (ids === null || ids === '') {
                 Toastr.error('请刷新页面后重试');
                 return;
             }
-            var $ptable = parent.$('#table');
-            if (!$ptable.length) {
+            var $ptable = $();
+            try {
+                if (typeof parent !== 'undefined' && parent.$) {
+                    $ptable = parent.$('#table');
+                }
+            } catch (ignoreParentTable) {
+                $ptable = $();
+            }
+            if (!$ptable.length && !isPickReviewEntry) {
                 Toastr.error('请刷新页面后重试');
                 return;
             }
-            var pk = $ptable.bootstrapTable('getOptions').pk || 'ID';
+            var pk = 'ID';
             var row = null;
-            $.each($ptable.bootstrapTable('getData'), function (i, r) {
-                if (String(r[pk]) === String(ids)) {
-                    row = r;
-                    return false;
-                }
-            });
+            if ($ptable.length) {
+                pk = $ptable.bootstrapTable('getOptions').pk || 'ID';
+                $.each($ptable.bootstrapTable('getData'), function (i, r) {
+                    if (String(r[pk]) === String(ids)) {
+                        row = r;
+                        return false;
+                    }
+                });
+            }
             var mergeRows = [];
             var mergeFlag = window.Fast && Fast.api ? String(Fast.api.query('merge') || '') : '';
             if (mergeFlag === '1') {
@@ -1827,11 +2028,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     );
                     $tb.append($tr);
                 });
-                var isPickModeUi = String($('#review-form').data('pickMode') || $('#review-form').data('pick-mode') || '') === '1';
+                var isPickModeUi = procuremenReviewIsPickMode();
                 if (isPickModeUi && list.length > 1) {
                     $('.procuremen-review-submit-tip').html(
                         '<i class="fa fa-exclamation-triangle"></i> '
-                        + '<strong>合并单:</strong>本步骤仅保存下发并勾选多家供应商,<strong>不发送短信或邮件</strong>;'
+                        + '<strong>合并单:</strong>确认后将向所选供应商<strong>发送短信与邮件</strong>;'
                         + '本单含 <strong>' + list.length + ' 道工序</strong>,请核对后再确认。'
                     );
                 }
@@ -1840,7 +2041,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
 
             applyProcuremenMergeReviewUi(mergeRows.length ? mergeRows : (row ? [row] : []));
 
-            var isPickMode = String($('#review-form').data('pickMode') || $('#review-form').data('pick-mode') || '') === '1';
+            var isPickMode = procuremenReviewIsPickMode();
 
             $('#c-row-json').val(JSON.stringify(row));
 
@@ -2133,69 +2334,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 });
             });
 
-            $('#btn-review-submit').off('click.reviewSubmit').on('click.reviewSubmit', function () {
-                var selected = [];
-                $.each(reviewSelectedMap, function (k, c) {
-                    if (c) {
-                        selected.push(c);
-                    }
-                });
-                if (!selected.length) {
-                    Toastr.warning(isPickMode ? '请至少选择一家合作供应商' : '请至少选择一个下发单位');
-                    return;
-                }
-                var sysRq = ($('#review-sys-rq').val() || '').trim();
-                if (!sysRq) {
-                    Toastr.warning('请选择截止时间');
-                    $('#review-sys-rq').focus();
-                    return;
-                }
-                var cons;
-                try {
-                    cons = JSON.parse($('#c-row-json').val() || '{}');
-                } catch (e) {
-                    cons = {};
-                }
-                var mergePayload = ($('#c-merge-rows-json').val() || '').trim();
-                if (!mergePayload) {
-                    mergePayload = JSON.stringify([cons]);
-                }
-                var $submitBtn = $('#btn-review-submit');
-                var submitBtnHtml = $submitBtn.html();
-                $submitBtn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> 提交中…');
-                Fast.api.ajax({
-                    url: isPickMode ? 'procuremen/picksubmit' : 'procuremen/review',
-                    type: 'POST',
-                    data: {
-                        __token__: $('input[name=\'__token__\']').val(),
-                        row_json: JSON.stringify(cons),
-                        merge_rows_json: mergePayload,
-                        companies_json: JSON.stringify(selected),
-                        sys_rq: sysRq
-                    }
-                }, function (data, ret) {
-                    var msg = (ret && ret.msg) ? ret.msg : '操作成功';
-                    try {
-                        sessionStorage.removeItem('procuremen_merge_rows');
-                    } catch (ignoreClr) {
-                    }
-                    var index = parent.Layer.getFrameIndex(window.name);
-                    if (typeof parent !== 'undefined' && parent.Layer && index) {
-                        parent.Layer.close(index);
-                    }
-                    if (typeof parent !== 'undefined' && parent.Toastr) {
-                        parent.Toastr.success(msg);
-                    }
-                    if (parent && parent.$ && parent.$('#table').length) {
-                        parent.$('#table').bootstrapTable('refresh', {silent: true});
-                    }
-                    return false;
-                }, function () {
-                    $submitBtn.prop('disabled', false).html(submitBtnHtml);
-                    return false;
-                });
-            });
-
             /** 加载供应商列表(弹窗内勾选单位) */
             function loadReviewCompaniesPanel() {
                 Fast.api.ajax({
@@ -2382,94 +2520,134 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
         },
 
         auditissue: function () {
-            procuremenBindSysRqPicker('#audit-sys-rq', 'auditSysRq');
+            function auditIssueClose() {
+                var index = parent.Layer.getFrameIndex(window.name);
+                parent.Layer.close(index);
+            }
 
-            var auditNotifyGroups = [];
-            try {
-                auditNotifyGroups = JSON.parse($('#audit-notify-groups-json').val() || '[]');
-            } catch (ignoreAudNg) {
-                auditNotifyGroups = [];
+            function auditIssueSysRq() {
+                return ($('#audit-sys-rq').val() || '').trim();
+            }
+
+            function auditIssueValidateSysRq() {
+                var sysRq = auditIssueSysRq();
+                if (!sysRq) {
+                    Toastr.warning('请选择报价截止时间');
+                    $('#audit-sys-rq').focus();
+                    return false;
+                }
+                return true;
+            }
+
+            function auditIssueAjaxData(extra) {
+                var data = {
+                    __token__: $('input[name=\'__token__\']').val(),
+                    scydgy_id: $('input[name=\'scydgy_id\']').val(),
+                    sys_rq: auditIssueSysRq()
+                };
+                if (extra) {
+                    $.extend(data, extra);
+                }
+                return data;
+            }
+
+            procuremenBindSysRqPicker('#audit-sys-rq', 'auditIssue');
+
+            function auditIssueSelectedCompany() {
+                var $checked = $('input[name="audit_quote_pick"]:checked');
+                if (!$checked.length) {
+                    return '';
+                }
+                return $.trim($checked.val());
             }
 
-            function auditIssueSyncCheckAll() {
-                var $rows = $('#audit-notify-tbody .audit-notify-pick');
-                var $checked = $rows.filter(':checked');
-                var $all = $('#audit-notify-check-all');
-                if (!$all.length || !$rows.length) {
+            function auditIssuePostResendEmail(companies) {
+                if (!companies || !companies.length) {
+                    Toastr.warning('请选择供应商');
                     return;
                 }
-                $all.prop('checked', $rows.length > 0 && $checked.length === $rows.length);
-                $all.prop('indeterminate', $checked.length > 0 && $checked.length < $rows.length);
+                if (!auditIssueValidateSysRq()) {
+                    return;
+                }
+                var company = companies[0];
+                Layer.confirm('向「' + company + '」发送邮件?', {icon: 3, title: '发邮件', btn: ['发送', '取消']}, function (layerIdx) {
+                    Layer.close(layerIdx);
+                    Fast.api.ajax({
+                        url: 'procuremen/auditresendemail',
+                        type: 'POST',
+                        data: auditIssueAjaxData({
+                            companies_json: JSON.stringify([company])
+                        })
+                    }, function (data, ret) {
+                        var msg = (ret && ret.msg) ? ret.msg : '已发送';
+                        if (typeof parent !== 'undefined' && parent.Toastr) {
+                            parent.Toastr.success(msg);
+                        }
+                        return false;
+                    });
+                });
             }
 
-            function auditIssueClose() {
-                var index = parent.Layer.getFrameIndex(window.name);
-                parent.Layer.close(index);
+            function auditIssuePostResendSms(company) {
+                if (!company) {
+                    Toastr.warning('请选择供应商');
+                    return;
+                }
+                if (!auditIssueValidateSysRq()) {
+                    return;
+                }
+                Layer.confirm('向「' + company + '」发送短信?', {icon: 3, title: '发短信', btn: ['发送', '取消']}, function (layerIdx) {
+                    Layer.close(layerIdx);
+                    Fast.api.ajax({
+                        url: 'procuremen/auditresendsms',
+                        type: 'POST',
+                        data: auditIssueAjaxData({
+                            selected_company: company
+                        })
+                    }, function (data, ret) {
+                        var msg = (ret && ret.msg) ? ret.msg : '已发送';
+                        if (typeof parent !== 'undefined' && parent.Toastr) {
+                            parent.Toastr.success(msg);
+                        }
+                        return false;
+                    });
+                });
             }
 
-            $('#audit-notify-check-all').off('change.auditNotifyAll').on('change.auditNotifyAll', function () {
-                var on = $(this).prop('checked');
-                $('#audit-notify-tbody .audit-notify-pick').prop('checked', on);
-                $(this).prop('indeterminate', false);
-            });
-            $('#audit-notify-tbody').off('change.auditNotifyPick', '.audit-notify-pick').on('change.auditNotifyPick', '.audit-notify-pick', auditIssueSyncCheckAll);
-            $('#audit-notify-tbody').off('click.auditNotifyRow', 'tr').on('click.auditNotifyRow', 'tr', function (e) {
-                if ($(e.target).is('input, label, a')) {
+            $('#audit-quote-tbody').off('click.auditQuoteRow', 'tr').on('click.auditQuoteRow', 'tr', function (e) {
+                if ($(e.target).closest('input, label, a, button').length) {
                     return;
                 }
-                var $cb = $(this).find('.audit-notify-pick').first();
-                if ($cb.length) {
-                    $cb.prop('checked', !$cb.prop('checked'));
-                    auditIssueSyncCheckAll();
+                var $radio = $(this).find('.audit-quote-pick').first();
+                if ($radio.length) {
+                    $radio.prop('checked', true);
                 }
             });
-            auditIssueSyncCheckAll();
 
             $('#btn-audit-issue-close').off('click.auditClose').on('click.auditClose', function () {
                 auditIssueClose();
             });
+
             $('#btn-audit-issue-submit').off('click.auditIssue').on('click.auditIssue', function () {
-                var selected = [];
-                $('#audit-notify-tbody .audit-notify-pick:checked').each(function () {
-                    var idx = parseInt($(this).val(), 10);
-                    if (!isNaN(idx) && auditNotifyGroups[idx]) {
-                        var co = auditNotifyGroups[idx];
-                        selected.push({
-                            name: co.name || co.company_name || '',
-                            company_name: co.name || co.company_name || '',
-                            email: co.email || '',
-                            phone: co.phone || '',
-                            username: co.username || ''
-                        });
-                    }
-                });
-                if (!selected.length) {
-                    Toastr.warning('请至少勾选一家供应商');
+                var company = auditIssueSelectedCompany();
+                if (!company) {
+                    Toastr.warning('请选择一家供应商');
                     return;
                 }
-                var sysRq = ($('#audit-sys-rq').val() || '').trim();
-                if (!sysRq) {
-                    Toastr.warning('请选择截止时间');
-                    $('#audit-sys-rq').focus();
+                if (!auditIssueValidateSysRq()) {
                     return;
                 }
-                var names = selected.map(function (c) {
-                    return c.name || c.company_name || '';
-                }).filter(Boolean).join('、');
                 Layer.confirm(
-                    '确认向以下 <strong>' + selected.length + ' 家</strong>供应商发送短信与邮件?<br/><span style="color:#666;">' + names + '</span>',
-                    {icon: 3, title: '确认通知', btn: ['确认通知', '取消']},
+                    '确认选定供应商「' + company + '」并进入采购终审?<br/><span style="color:#666;">本步不发送短信。</span>',
+                    {icon: 3, title: '确认供应商', btn: ['确认', '取消']},
                     function (layerIdx) {
                         Layer.close(layerIdx);
                         Fast.api.ajax({
                             url: 'procuremen/auditsubmit',
                             type: 'POST',
-                            data: {
-                                __token__: $('input[name=\'__token__\']').val(),
-                                scydgy_id: $('input[name=\'scydgy_id\']').val(),
-                                notify_companies_json: JSON.stringify(selected),
-                                sys_rq: sysRq
-                            }
+                            data: auditIssueAjaxData({
+                                selected_company: company
+                            })
                         }, function (data, ret) {
                             var msg = (ret && ret.msg) ? ret.msg : '操作成功';
                             if (typeof parent !== 'undefined' && parent.Toastr) {
@@ -2484,6 +2662,26 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     }
                 );
             });
+
+            $('#audit-quote-tbody').off('click.auditRowEmail', '.audit-row-send-email').on('click.auditRowEmail', '.audit-row-send-email', function (e) {
+                e.preventDefault();
+                e.stopPropagation();
+                var company = $.trim($(this).attr('data-company') || '');
+                if (!company) {
+                    return;
+                }
+                auditIssuePostResendEmail([company]);
+            });
+
+            $('#audit-quote-tbody').off('click.auditRowSms', '.audit-row-send-sms').on('click.auditRowSms', '.audit-row-send-sms', function (e) {
+                e.preventDefault();
+                e.stopPropagation();
+                var company = $.trim($(this).attr('data-company') || '');
+                if (!company) {
+                    return;
+                }
+                auditIssuePostResendSms(company);
+            });
         },
 
         api: {

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