m0_70156489 1 month ago
parent
commit
330ace34c2

+ 16 - 6
application/admin/controller/Procuremen.php

@@ -6,6 +6,7 @@ use app\common\controller\Backend;
 use app\common\library\AliyunOss;
 use app\common\library\ProcuremenGuard;
 use app\common\library\ProcuremenOperLog;
+use app\common\library\ProcuremenSchema;
 use app\common\library\ProcuremenStatus;
 use app\common\library\ProcuremenSupplierScore;
 use app\common\library\ProcuremenTime;
@@ -67,6 +68,10 @@ class Procuremen extends Backend
         $this->model = new \app\admin\model\Procuremen;
         $this->maybeMigrateLegacyWflowStatusText();
         $this->assignProcuremenAuthConfig();
+        try {
+            ProcuremenSchema::ensureAll();
+        } catch (\Throwable $e) {
+        }
         if (!Cache::get(self::EMAIL_SEND_LOG_SCHEMA_CACHE_KEY)) {
             $this->ensurePurchaseEmailSendLogTableOnce();
         }
@@ -8983,7 +8988,7 @@ class Procuremen extends Backend
     }
 
     /**
-     * 业务员新增进度查询(手工询价;发起人 / 通知业务员可见,超管看全部
+     * 业务员新增进度查询(手工询价;有查询权限看全部,含手机端新增且未通知业务员的
      */
     public function rfqlist()
     {
@@ -9007,7 +9012,7 @@ class Procuremen extends Backend
                 $applyFilters = function ($query) use ($where, $filterYm) {
                     $query->where('scydgy_id', '<', 0);
                     $this->applyPurchaseOrderNotDeletedWhere($query);
-                    $this->applyManualRfqViewerWhere($query);
+                    // 查询询价:有菜单权限即可看全部手工单(含手机端新增、尚未通知业务员的)
                     $this->applyRfqListMonthFilter($query, $filterYm);
                     if (!empty($where)) {
                         // 计算字段不能直接 where,避免 SQL 异常被吞成「暂无数据」
@@ -9174,7 +9179,6 @@ class Procuremen extends Backend
         try {
             $q = Db::table('purchase_order')->where('scydgy_id', '<', 0);
             $this->applyPurchaseOrderNotDeletedWhere($q);
-            $this->applyManualRfqViewerWhere($q);
             $rows = $q->field('createtime,dStamp')->limit(5000)->select();
         } catch (\Throwable $e) {
             $rows = [];
@@ -9199,11 +9203,13 @@ class Procuremen extends Backend
     }
 
     /**
-     * 手工询价可见范围:仅「需求发起人」或「通知业务员」与当前登录账号一致(超管看全部)
+     * 手工询价可见范围(用于详情/操作校验):
+     * 超管、具备「查询询价」权限、需求发起人、通知业务员 → 可见
+     * 列表页本身不再按发起人/通知过滤,避免手机端新增后后台看不到。
      */
     protected function applyManualRfqViewerWhere($query): void
     {
-        if ($this->auth->isSuperAdmin()) {
+        if ($this->auth->isSuperAdmin() || $this->hasProcuremenPerm(['rfqlist'])) {
             return;
         }
         [, $adminName] = $this->GetUseName();
@@ -9227,13 +9233,17 @@ class Procuremen extends Backend
     }
 
     /**
-     * 当前用户是否可查看/操作该手工询价单(需求发起人或通知业务员;超管全部)
+     * 当前用户是否可查看/操作该手工询价单
      */
     protected function canViewManualRfqOrder(array $po): bool
     {
         if ($this->auth->isSuperAdmin()) {
             return true;
         }
+        // 有查询询价权限则可操作全部手工询价(询价/查看报价/通知业务员等)
+        if ($this->hasProcuremenPerm(['rfqlist'])) {
+            return true;
+        }
         [, $adminName] = $this->GetUseName();
         $adminName = trim((string)$adminName);
         if ($adminName !== '' && trim((string)($po['cywyxm'] ?? '')) === $adminName) {

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

@@ -141,10 +141,10 @@
                 <input class="form-control" name="row[ceilingPrice]" type="text" autocomplete="off">
             </div>
         </div>
-        <div class="form-group">
+        <div class="form-group" style="display:none;">
             <label class="control-label col-xs-12 col-sm-2">订法:</label>
             <div class="col-xs-12 col-sm-8">
-                <input class="form-control" name="row[CDF]" type="text" autocomplete="off">
+                <input class="form-control" name="row[CDF]" type="text" autocomplete="off" value="">
             </div>
         </div>
 <!--        <div class="form-group">-->

+ 482 - 0
application/common/library/ProcuremenSchema.php

@@ -0,0 +1,482 @@
+<?php
+
+namespace app\common\library;
+
+use think\Cache;
+use think\Config;
+use think\Db;
+use think\Log;
+
+/**
+ * 协助采购 / 手机端报价相关表结构保障:
+ * - 表不存在 → CREATE(完整字段)
+ * - 表存在但缺列 → ALTER ADD(静默,不抛「字段不存在」给业务)
+ */
+class ProcuremenSchema
+{
+    public const CACHE_KEY = 'procuremen_quote_schema_ok_v1';
+
+    /** @var bool */
+    protected static $done = false;
+
+    public static function ensureAll(): void
+    {
+        if (self::$done) {
+            return;
+        }
+        self::$done = true;
+        try {
+            if (Cache::get(self::CACHE_KEY)) {
+                return;
+            }
+        } catch (\Throwable $e) {
+        }
+
+        $changed = false;
+        try {
+            $changed = self::ensurePurchaseOrderTable() || $changed;
+            $changed = self::ensurePurchaseOrderDetailTable() || $changed;
+            $changed = self::ensurePurchaseOrderOperLogTable() || $changed;
+            $changed = self::ensurePurchaseOrderBidOpenTable() || $changed;
+            $changed = self::ensurePurchaseOrderInboundScoreTable() || $changed;
+            $changed = self::ensurePurchaseEmailSendLogTable() || $changed;
+            $changed = self::ensurePurchaseSmsTemplateTable() || $changed;
+            try {
+                ProcuremenSupplierScore::ensureSchema();
+            } catch (\Throwable $e) {
+                Log::write('ProcuremenSchema score: ' . $e->getMessage(), 'error');
+            }
+            if ($changed) {
+                self::clearTableFieldsCache([
+                    'purchase_order',
+                    'purchase_order_detail',
+                    'purchase_order_oper_log',
+                    'purchase_order_bid_open',
+                    'purchase_order_inbound_score',
+                    'purchase_email_send_log',
+                    'purchase_sms_template',
+                ]);
+            }
+            try {
+                Cache::set(self::CACHE_KEY, 1, 86400);
+            } catch (\Throwable $e) {
+            }
+        } catch (\Throwable $e) {
+            Log::write('ProcuremenSchema::ensureAll: ' . $e->getMessage(), 'error');
+        }
+    }
+
+    /**
+     * 强制下次请求重新探测(改库后可清 runtime cache 或调此方法)
+     */
+    public static function invalidateCache(): void
+    {
+        self::$done = false;
+        try {
+            Cache::rm(self::CACHE_KEY);
+        } catch (\Throwable $e) {
+        }
+    }
+
+    protected static function tableExists(string $table): bool
+    {
+        try {
+            Db::query('SELECT 1 FROM `' . str_replace('`', '', $table) . '` LIMIT 1');
+
+            return true;
+        } catch (\Throwable $e) {
+            return false;
+        }
+    }
+
+    /**
+     * @param array<string, string> $columns col => ADD COLUMN ... DDL fragment (without ADD COLUMN prefix ok if starts with ADD)
+     */
+    protected static function ensureColumns(string $table, array $columns): bool
+    {
+        $changed = false;
+        $table = str_replace('`', '', $table);
+        foreach ($columns as $col => $ddl) {
+            $col = str_replace('`', '', (string)$col);
+            if ($col === '') {
+                continue;
+            }
+            try {
+                $exists = Db::query("SHOW COLUMNS FROM `{$table}` LIKE '{$col}'");
+                if (is_array($exists) && $exists !== []) {
+                    continue;
+                }
+                $ddl = trim($ddl);
+                if (stripos($ddl, 'ADD ') !== 0) {
+                    $ddl = 'ADD COLUMN ' . $ddl;
+                }
+                Db::execute("ALTER TABLE `{$table}` {$ddl}");
+                $changed = true;
+            } catch (\Throwable $e) {
+                Log::write("ProcuremenSchema {$table}.{$col}: " . $e->getMessage(), 'error');
+            }
+        }
+
+        return $changed;
+    }
+
+    /**
+     * @param string[] $tables
+     */
+    protected static function clearTableFieldsCache(array $tables): void
+    {
+        $db = '';
+        try {
+            $db = (string)Config::get('database.database');
+        } catch (\Throwable $e) {
+        }
+        try {
+            $ref = new \ReflectionProperty(\think\db\Query::class, 'info');
+            $ref->setAccessible(true);
+            $info = $ref->getValue();
+            if (is_array($info)) {
+                foreach ($tables as $t) {
+                    $key = ($db !== '' ? $db . '.' : '') . $t;
+                    unset($info[$key], $info[$t]);
+                }
+                $ref->setValue(null, $info);
+            }
+        } catch (\Throwable $e) {
+        }
+        if ($db === '') {
+            return;
+        }
+        foreach ($tables as $t) {
+            $schemaFile = RUNTIME_PATH . 'schema' . DIRECTORY_SEPARATOR . $db . '.' . $t . '.php';
+            if (is_file($schemaFile)) {
+                @unlink($schemaFile);
+            }
+        }
+    }
+
+    protected static function ensurePurchaseOrderTable(): bool
+    {
+        $changed = false;
+        if (!self::tableExists('purchase_order')) {
+            try {
+                Db::execute("CREATE TABLE IF NOT EXISTS `purchase_order` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `scydgy_id` int DEFAULT NULL COMMENT '工序行ID(手工询价为负数)',
+  `CCYDH` varchar(255) DEFAULT NULL COMMENT '订单号',
+  `CYJMC` varchar(255) DEFAULT NULL COMMENT '印件名称',
+  `CDXMC` varchar(255) DEFAULT NULL,
+  `CGYBH` varchar(255) DEFAULT NULL,
+  `CCLBMMC` varchar(255) DEFAULT NULL COMMENT '需求部门',
+  `CGYMC` varchar(255) DEFAULT NULL COMMENT '工序名称',
+  `CDW` varchar(255) DEFAULT NULL COMMENT '单位',
+  `czlyq` varchar(64) NOT NULL DEFAULT '' COMMENT '类型',
+  `NGZL` varchar(255) DEFAULT NULL COMMENT '工作量',
+  `This_quantity` varchar(255) DEFAULT NULL COMMENT '本次数量',
+  `ceilingPrice` varchar(255) DEFAULT NULL COMMENT '最高限价',
+  `CDF` varchar(255) DEFAULT NULL COMMENT '订法',
+  `cGzzxMc` varchar(255) DEFAULT NULL COMMENT '外厂单位',
+  `MBZ` varchar(255) DEFAULT NULL COMMENT '备注',
+  `bwjg` varchar(255) DEFAULT NULL,
+  `iStatus` varchar(255) DEFAULT NULL,
+  `dStamp` varchar(255) DEFAULT NULL,
+  `dputrecord` varchar(255) DEFAULT NULL,
+  `cywyxm` varchar(255) DEFAULT NULL COMMENT '业务员/需求发起人',
+  `notify_salesman` varchar(500) NOT NULL DEFAULT '' COMMENT '通知业务员(可多选)',
+  `rfq_salesman_notified` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '手工询价已通知业务员0否1是',
+  `rfq_salesman_notify_time` datetime DEFAULT NULL COMMENT '手工询价通知业务员时间',
+  `status` varchar(255) DEFAULT NULL COMMENT '空=未完结、0=进行中、1=已完结',
+  `createtime` varchar(255) DEFAULT NULL COMMENT '录入时间',
+  `pdf_url` varchar(255) DEFAULT NULL COMMENT 'pdf路径',
+  `sys_rq` varchar(255) DEFAULT NULL COMMENT '招标截止日期',
+  `delivery_deadline` date DEFAULT NULL COMMENT '交货截止日期',
+  `wflow_status` varchar(255) DEFAULT NULL COMMENT '流程状态',
+  `pick_company_name` varchar(255) DEFAULT NULL COMMENT '中标/选定供应商',
+  `manual_pick` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '1=自选供应商(免开标)',
+  `manual_pick_reason` varchar(500) NOT NULL DEFAULT '' COMMENT '自选供应商说明',
+  `pick_time` datetime DEFAULT NULL COMMENT '选定时间',
+  `score_rule_id` int unsigned NOT NULL DEFAULT 0 COMMENT '评分规则ID',
+  `score_rule_name` varchar(100) NOT NULL DEFAULT '' COMMENT '规则名称快照',
+  `score_quality_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '质量权重快照%',
+  `score_price_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '价格权重快照%',
+  `score_lead_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '交货权重快照%',
+  `mod_rq` varchar(255) DEFAULT NULL COMMENT '软删除日期',
+  PRIMARY KEY (`id`),
+  KEY `idx_scydgy_id` (`scydgy_id`),
+  KEY `idx_CCYDH` (`CCYDH`(64)),
+  KEY `idx_wflow_status` (`wflow_status`(32))
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购订单(工序行)'");
+                $changed = true;
+            } catch (\Throwable $e) {
+                Log::write('ProcuremenSchema create purchase_order: ' . $e->getMessage(), 'error');
+            }
+        }
+
+        $changed = self::ensureColumns('purchase_order', [
+            'czlyq'                     => "`czlyq` varchar(64) NOT NULL DEFAULT '' COMMENT '类型'",
+            'notify_salesman'           => "`notify_salesman` varchar(500) NOT NULL DEFAULT '' COMMENT '通知业务员(可多选)'",
+            'rfq_salesman_notified'     => "`rfq_salesman_notified` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '手工询价已通知业务员0否1是'",
+            'rfq_salesman_notify_time'  => "`rfq_salesman_notify_time` datetime DEFAULT NULL COMMENT '手工询价通知业务员时间'",
+            'manual_pick'               => "`manual_pick` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '1=自选供应商(免开标)'",
+            'manual_pick_reason'        => "`manual_pick_reason` varchar(500) NOT NULL DEFAULT '' COMMENT '自选供应商说明'",
+            'pick_time'                 => "`pick_time` datetime DEFAULT NULL COMMENT '选定时间'",
+            'delivery_deadline'         => "`delivery_deadline` date DEFAULT NULL COMMENT '交货截止日期'",
+            'score_rule_id'             => "`score_rule_id` int unsigned NOT NULL DEFAULT 0 COMMENT '评分规则ID'",
+            'score_rule_name'           => "`score_rule_name` varchar(100) NOT NULL DEFAULT '' COMMENT '规则名称快照'",
+            'score_quality_weight'      => "`score_quality_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '质量权重快照%'",
+            'score_price_weight'        => "`score_price_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '价格权重快照%'",
+            'score_lead_weight'         => "`score_lead_weight` int unsigned NOT NULL DEFAULT 0 COMMENT '交货权重快照%'",
+            'This_quantity'             => "`This_quantity` varchar(255) DEFAULT NULL COMMENT '本次数量'",
+            'ceilingPrice'              => "`ceilingPrice` varchar(255) DEFAULT NULL COMMENT '最高限价'",
+            'pick_company_name'         => "`pick_company_name` varchar(255) DEFAULT NULL COMMENT '中标/选定供应商'",
+            'wflow_status'              => "`wflow_status` varchar(255) DEFAULT NULL COMMENT '流程状态'",
+            'mod_rq'                    => "`mod_rq` varchar(255) DEFAULT NULL COMMENT '软删除日期'",
+            'cywyxm'                    => "`cywyxm` varchar(255) DEFAULT NULL COMMENT '业务员/需求发起人'",
+            'CCLBMMC'                   => "`CCLBMMC` varchar(255) DEFAULT NULL COMMENT '需求部门'",
+            'MBZ'                       => "`MBZ` varchar(255) DEFAULT NULL COMMENT '备注'",
+            'createtime'                => "`createtime` varchar(255) DEFAULT NULL COMMENT '录入时间'",
+            'pdf_url'                   => "`pdf_url` varchar(255) DEFAULT NULL COMMENT 'pdf路径'",
+            'sys_rq'                    => "`sys_rq` varchar(255) DEFAULT NULL COMMENT '招标截止日期'",
+        ]) || $changed;
+
+        return $changed;
+    }
+
+    protected static function ensurePurchaseOrderDetailTable(): bool
+    {
+        $changed = false;
+        if (!self::tableExists('purchase_order_detail')) {
+            try {
+                Db::execute("CREATE TABLE IF NOT EXISTS `purchase_order_detail` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `scydgy_id` int DEFAULT NULL COMMENT '工序行ID',
+  `CCYDH` varchar(255) DEFAULT NULL COMMENT '订单号',
+  `CYJMC` varchar(255) DEFAULT NULL COMMENT '印件名称',
+  `CGYMC` varchar(255) DEFAULT NULL COMMENT '工序名称',
+  `amount` varchar(255) DEFAULT NULL COMMENT '单价/金额',
+  `delivery` datetime DEFAULT NULL COMMENT '交货日期',
+  `delivery_createtime` datetime DEFAULT NULL COMMENT '报价提交时间',
+  `lead_days` int unsigned DEFAULT NULL COMMENT '预估工期(天)',
+  `company_name` varchar(255) DEFAULT NULL COMMENT '供应商名称',
+  `username` varchar(128) DEFAULT NULL COMMENT '供应商账号',
+  `email` varchar(255) DEFAULT NULL COMMENT '邮箱',
+  `phone` varchar(255) DEFAULT NULL COMMENT '手机号',
+  `createtime` datetime DEFAULT NULL COMMENT '下发时间',
+  `status` varchar(255) DEFAULT NULL COMMENT '数值状态',
+  `status_name` varchar(255) DEFAULT NULL COMMENT '状态名',
+  `remark` varchar(500) DEFAULT NULL COMMENT '供应商整单备注',
+  PRIMARY KEY (`id`),
+  KEY `idx_scydgy_id` (`scydgy_id`),
+  KEY `idx_CCYDH` (`CCYDH`(64)),
+  KEY `idx_company_name` (`company_name`(64)),
+  KEY `idx_status_name` (`status_name`(32))
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购报价明细'");
+                $changed = true;
+            } catch (\Throwable $e) {
+                Log::write('ProcuremenSchema create purchase_order_detail: ' . $e->getMessage(), 'error');
+            }
+        }
+
+        $changed = self::ensureColumns('purchase_order_detail', [
+            'amount'               => "`amount` varchar(255) DEFAULT NULL COMMENT '单价/金额'",
+            'delivery'             => "`delivery` datetime DEFAULT NULL COMMENT '交货日期'",
+            'delivery_createtime'  => "`delivery_createtime` datetime DEFAULT NULL COMMENT '报价提交时间'",
+            'lead_days'            => "`lead_days` int unsigned DEFAULT NULL COMMENT '预估工期(天)'",
+            'company_name'         => "`company_name` varchar(255) DEFAULT NULL COMMENT '供应商名称'",
+            'username'             => "`username` varchar(128) DEFAULT NULL COMMENT '供应商账号'",
+            'email'                => "`email` varchar(255) DEFAULT NULL COMMENT '邮箱'",
+            'phone'                => "`phone` varchar(255) DEFAULT NULL COMMENT '手机号'",
+            'status'               => "`status` varchar(255) DEFAULT NULL COMMENT '数值状态'",
+            'status_name'          => "`status_name` varchar(255) DEFAULT NULL COMMENT '状态名'",
+            'remark'               => "`remark` varchar(500) DEFAULT NULL COMMENT '供应商整单备注'",
+            'CYJMC'                => "`CYJMC` varchar(255) DEFAULT NULL COMMENT '印件名称'",
+            'CGYMC'                => "`CGYMC` varchar(255) DEFAULT NULL COMMENT '工序名称'",
+            'CCYDH'                => "`CCYDH` varchar(255) DEFAULT NULL COMMENT '订单号'",
+            'scydgy_id'            => "`scydgy_id` int DEFAULT NULL COMMENT '工序行ID'",
+            'createtime'           => "`createtime` datetime DEFAULT NULL COMMENT '下发时间'",
+        ]) || $changed;
+
+        return $changed;
+    }
+
+    protected static function ensurePurchaseOrderOperLogTable(): bool
+    {
+        if (self::tableExists('purchase_order_oper_log')) {
+            return self::ensureColumns('purchase_order_oper_log', [
+                'scydgy_id'         => "`scydgy_id` int NOT NULL DEFAULT 0 COMMENT '工序行ID'",
+                'purchase_order_id' => "`purchase_order_id` int unsigned DEFAULT NULL COMMENT 'purchase_order.id'",
+                'admin_id'          => "`admin_id` int unsigned DEFAULT NULL COMMENT '操作人'",
+                'admin_name'        => "`admin_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人快照'",
+                'action'            => "`action` varchar(64) NOT NULL DEFAULT '' COMMENT '动作码'",
+                'content'           => "`content` varchar(1000) NOT NULL DEFAULT '' COMMENT '描述'",
+                'createtime'        => "`createtime` int unsigned NOT NULL DEFAULT 0 COMMENT 'Unix时间戳'",
+            ]);
+        }
+        try {
+            Db::execute("CREATE TABLE IF NOT EXISTS `purchase_order_oper_log` (
+  `id` int unsigned NOT NULL AUTO_INCREMENT,
+  `scydgy_id` int NOT NULL DEFAULT 0 COMMENT '工序行 scydgy.ID',
+  `purchase_order_id` int unsigned DEFAULT NULL COMMENT 'purchase_order.id',
+  `admin_id` int unsigned DEFAULT NULL COMMENT '操作人 admin.id',
+  `admin_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人昵称/账号快照',
+  `action` varchar(64) NOT NULL DEFAULT '' COMMENT '动作码',
+  `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '中文描述',
+  `createtime` int unsigned NOT NULL DEFAULT 0 COMMENT 'Unix 时间戳',
+  PRIMARY KEY (`id`),
+  KEY `idx_scydgy_ct` (`scydgy_id`,`createtime`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购操作日志'");
+
+            return true;
+        } catch (\Throwable $e) {
+            Log::write('ProcuremenSchema create purchase_order_oper_log: ' . $e->getMessage(), 'error');
+
+            return false;
+        }
+    }
+
+    protected static function ensurePurchaseOrderBidOpenTable(): bool
+    {
+        if (self::tableExists('purchase_order_bid_open')) {
+            return false;
+        }
+        try {
+            Db::execute("CREATE TABLE IF NOT EXISTS `purchase_order_bid_open` (
+  `id` int unsigned NOT NULL AUTO_INCREMENT,
+  `ccydh` varchar(64) NOT NULL DEFAULT '' COMMENT '订单号',
+  `verifier1_id` int unsigned NOT NULL DEFAULT 0,
+  `verifier1_name` varchar(64) NOT NULL DEFAULT '',
+  `verifier2_id` int unsigned NOT NULL DEFAULT 0,
+  `verifier2_name` varchar(64) NOT NULL DEFAULT '',
+  `operator_id` int unsigned NOT NULL DEFAULT 0,
+  `operator_name` varchar(64) NOT NULL DEFAULT '',
+  `createtime` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_ccydh` (`ccydh`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='开标双重验证'");
+
+            return true;
+        } catch (\Throwable $e) {
+            Log::write('ProcuremenSchema create purchase_order_bid_open: ' . $e->getMessage(), 'error');
+
+            return false;
+        }
+    }
+
+    protected static function ensurePurchaseOrderInboundScoreTable(): bool
+    {
+        $changed = false;
+        if (!self::tableExists('purchase_order_inbound_score')) {
+            try {
+                Db::execute("CREATE TABLE IF NOT EXISTS `purchase_order_inbound_score` (
+  `id` int unsigned NOT NULL AUTO_INCREMENT,
+  `scydgy_id` int NOT NULL DEFAULT 0 COMMENT '工序ID',
+  `purchase_order_id` int unsigned NOT NULL DEFAULT 0 COMMENT 'purchase_order.id',
+  `ccydh` varchar(64) NOT NULL DEFAULT '' COMMENT '订单号',
+  `cyjmc` varchar(255) NOT NULL DEFAULT '' COMMENT '印件名称',
+  `cgymc` varchar(255) NOT NULL DEFAULT '' COMMENT '工序名称',
+  `company_name` varchar(255) NOT NULL DEFAULT '' COMMENT '中标供应商',
+  `result` varchar(16) NOT NULL DEFAULT '' COMMENT '合格/不合格',
+  `delivery_status` varchar(16) NOT NULL DEFAULT '' COMMENT '交货情况 准时/滞后',
+  `delivery_date` date DEFAULT NULL COMMENT '交货日期',
+  `customer_complaint` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '客户是否投诉 1=是',
+  `complaint_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '投诉说明',
+  `order_interrupt` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '订单是否中断 1=是',
+  `admin_id` int unsigned NOT NULL DEFAULT 0,
+  `admin_name` varchar(64) NOT NULL DEFAULT '',
+  `remark` varchar(500) NOT NULL DEFAULT '',
+  `createtime` datetime DEFAULT NULL,
+  `updatetime` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_scydgy_id` (`scydgy_id`),
+  KEY `idx_ccydh` (`ccydh`),
+  KEY `idx_result` (`result`),
+  KEY `idx_updatetime` (`updatetime`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='质量/交货评分'");
+                $changed = true;
+            } catch (\Throwable $e) {
+                Log::write('ProcuremenSchema create inbound_score: ' . $e->getMessage(), 'error');
+            }
+        }
+
+        return self::ensureColumns('purchase_order_inbound_score', [
+            'delivery_status'    => "`delivery_status` varchar(16) NOT NULL DEFAULT '' COMMENT '交货情况 准时/滞后'",
+            'delivery_date'      => "`delivery_date` date DEFAULT NULL COMMENT '交货日期'",
+            'customer_complaint' => "`customer_complaint` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '客户是否投诉 1=是'",
+            'complaint_remark'   => "`complaint_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '投诉说明'",
+            'order_interrupt'    => "`order_interrupt` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '订单是否中断 1=是'",
+            'result'             => "`result` varchar(16) NOT NULL DEFAULT '' COMMENT '合格/不合格'",
+            'company_name'       => "`company_name` varchar(255) NOT NULL DEFAULT '' COMMENT '中标供应商'",
+            'ccydh'              => "`ccydh` varchar(64) NOT NULL DEFAULT '' COMMENT '订单号'",
+            'scydgy_id'          => "`scydgy_id` int NOT NULL DEFAULT 0 COMMENT '工序ID'",
+        ]) || $changed;
+    }
+
+    protected static function ensurePurchaseEmailSendLogTable(): bool
+    {
+        if (self::tableExists('purchase_email_send_log')) {
+            return false;
+        }
+        try {
+            Db::execute("CREATE TABLE IF NOT EXISTS `purchase_email_send_log` (
+  `id` int unsigned NOT NULL AUTO_INCREMENT,
+  `from_email` varchar(128) NOT NULL DEFAULT '' COMMENT '发件邮箱',
+  `to_email` varchar(128) NOT NULL DEFAULT '' COMMENT '收件邮箱',
+  `send_time` datetime DEFAULT NULL COMMENT '发送时间',
+  `scene` varchar(32) NOT NULL DEFAULT '' COMMENT '场景',
+  `ccydh` varchar(64) NOT NULL DEFAULT '' COMMENT '订单号',
+  `company_name` varchar(128) NOT NULL DEFAULT '' COMMENT '供应商名称',
+  `mail_subject` varchar(255) NOT NULL DEFAULT '' COMMENT '邮件主题',
+  `status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '1成功 0失败',
+  `fail_reason` varchar(500) NOT NULL DEFAULT '' COMMENT '失败原因',
+  `admin_id` int unsigned NOT NULL DEFAULT 0 COMMENT '操作人ID',
+  `admin_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人',
+  `scydgy_id` int NOT NULL DEFAULT 0 COMMENT '工序行ID',
+  `purchase_order_id` int unsigned NOT NULL DEFAULT 0 COMMENT 'purchase_order.id',
+  `createtime` datetime DEFAULT NULL COMMENT '记录创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_send_time` (`send_time`),
+  KEY `idx_to_email` (`to_email`),
+  KEY `idx_ccydh` (`ccydh`),
+  KEY `idx_scene` (`scene`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购邮件发送日志'");
+
+            return true;
+        } catch (\Throwable $e) {
+            Log::write('ProcuremenSchema create email_send_log: ' . $e->getMessage(), 'error');
+
+            return false;
+        }
+    }
+
+    protected static function ensurePurchaseSmsTemplateTable(): bool
+    {
+        if (self::tableExists('purchase_sms_template')) {
+            return self::ensureColumns('purchase_sms_template', [
+                'scene'   => "`scene` varchar(32) DEFAULT NULL COMMENT '场景码'",
+                'title'   => "`title` varchar(100) DEFAULT '' COMMENT '模版名称'",
+                'content' => "`content` text COMMENT '正文'",
+                'remark'  => "`remark` varchar(255) DEFAULT '' COMMENT '备注'",
+                'status'  => "`status` varchar(30) DEFAULT 'normal'",
+            ]);
+        }
+        try {
+            Db::execute("CREATE TABLE IF NOT EXISTS `purchase_sms_template` (
+  `id` int unsigned NOT NULL AUTO_INCREMENT,
+  `scene` varchar(32) DEFAULT NULL COMMENT '场景码',
+  `title` varchar(100) DEFAULT '' COMMENT '模版名称',
+  `content` text COMMENT '正文',
+  `remark` varchar(255) DEFAULT '' COMMENT '备注',
+  `status` varchar(30) DEFAULT 'normal',
+  `createtime` datetime DEFAULT NULL,
+  `updatetime` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_scene` (`scene`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='协助采购短信/邮件模版'");
+
+            return true;
+        } catch (\Throwable $e) {
+            Log::write('ProcuremenSchema create sms_template: ' . $e->getMessage(), 'error');
+
+            return false;
+        }
+    }
+}

+ 13 - 13
application/database.php

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

+ 3 - 0
application/extra/mproc.php

@@ -9,6 +9,9 @@
  *   - 生产部/生产员(auth_group)→ 交货情况(准时/滞后)
  *   - 业务员(auth_group)→ 新增订单询价
  *   - 其它后台账号 → 提示「账号或密码错误」(不可进手机端)
+ *
+ * 报价相关表结构:访问手机端 Index / 后台 Procuremen 时由
+ * app\common\library\ProcuremenSchema::ensureAll() 自动建表并补齐字段。
  */
 return [
     // 邮件根地址(正式环境);本地未配或校验不通过时自动用当前访问域名

+ 5 - 0
application/index/controller/Index.php

@@ -3,6 +3,7 @@
 namespace app\index\controller;
 
 use app\common\controller\Frontend;
+use app\common\library\ProcuremenSchema;
 use app\common\library\ProcuremenStatus;
 use think\Cache;
 use think\captcha\Captcha;
@@ -52,6 +53,10 @@ class Index extends Frontend
             ini_set('session.cookie_lifetime', (string)$this->mprocTtlSeconds);
             ini_set('session.gc_maxlifetime', (string)$this->mprocTtlSeconds);
         }
+        try {
+            ProcuremenSchema::ensureAll();
+        } catch (\Throwable $e) {
+        }
     }
 
     /** 登录有效小时数(用于前端 localStorage 过期时间) */

+ 105 - 48
application/index/view/index/rfqadd.html

@@ -117,7 +117,7 @@
         }
         .rfq-mask.show { display: flex; }
         .rfq-sheet {
-            width: 100%; max-width: 340px; max-height: min(72vh, 560px);
+            width: 100%; max-width: 360px; max-height: min(78vh, 620px);
             background: #fff; border-radius: 12px;
             display: flex; flex-direction: column; overflow: hidden;
             box-shadow: 0 8px 28px rgba(0,0,0,.18);
@@ -133,23 +133,31 @@
         }
         .rfq-sheet-body {
             flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
-            padding: 10px 12px 6px;
+            padding: 8px 12px 6px;
+        }
+        .rfq-field {
+            display: flex; align-items: center; gap: 8px;
+            margin-bottom: 0; padding: 7px 0;
         }
-        .rfq-field { margin-bottom: 8px; }
         .rfq-field label {
-            display: block; font-size: 12px; color: #666; margin-bottom: 4px; font-weight: 600;
+            flex: 0 0 5.6em; margin: 0; padding: 0;
+            font-size: 13px; color: #555; font-weight: 600;
+            line-height: 1.35; text-align: left;
         }
-        .rfq-field label .req { color: #e74c3c; margin-left: 2px; }
+        .rfq-field label .req { color: #e74c3c; margin-left: 1px; }
+        .rfq-field-ctrl { flex: 1 1 auto; min-width: 0; }
         .rfq-field input,
         .rfq-field textarea {
-            width: 100%; padding: 8px 10px; border: 1px solid #ddd; border-radius: 8px;
+            width: 100%; padding: 7px 8px; border: 1px solid #ddd; border-radius: 6px;
             font-size: 14px; font-family: inherit; background: #fff; color: #333;
         }
         .rfq-field input:focus,
         .rfq-field textarea:focus { outline: none; border-color: #3c8dbc; }
         .rfq-field input[readonly] { background: #f5f5f5; color: #555; }
-        .rfq-field textarea { resize: vertical; min-height: 64px; }
-        .rfq-dept-combo { position: relative; }
+        .rfq-field.rfq-field-area { align-items: flex-start; }
+        .rfq-field.rfq-field-area label { padding-top: 8px; }
+        .rfq-field textarea { resize: vertical; min-height: 56px; }
+        .rfq-dept-combo { position: relative; z-index: 20; width: 100%; }
         .rfq-dept-combo .rfq-dept-row {
             display: flex; align-items: stretch; gap: 0;
             border: 1px solid #ddd; border-radius: 8px; background: #fff; overflow: hidden;
@@ -166,15 +174,17 @@
         }
         .rfq-dept-combo .rfq-dept-menu {
             display: none; position: absolute; left: 0; right: 0; top: calc(100% + 4px);
-            z-index: 5; max-height: 160px; overflow-y: auto;
+            z-index: 30; max-height: min(42vh, 240px); overflow-y: auto; overflow-x: hidden;
+            -webkit-overflow-scrolling: touch; touch-action: pan-y; overscroll-behavior: contain;
             background: #fff; border: 1px solid #ddd; border-radius: 8px;
             box-shadow: 0 6px 18px rgba(0,0,0,.12);
         }
         .rfq-dept-combo.open .rfq-dept-menu { display: block; }
         .rfq-dept-combo .rfq-dept-item {
-            display: block; width: 100%; padding: 9px 10px; border: none;
+            display: block; width: 100%; padding: 11px 10px; border: none;
             background: #fff; text-align: left; font-size: 13px; color: #333;
             font-family: inherit; cursor: pointer; border-bottom: 1px solid #f3f3f3;
+            -webkit-tap-highlight-color: transparent;
         }
         .rfq-dept-combo .rfq-dept-item:last-child { border-bottom: none; }
         .rfq-dept-combo .rfq-dept-item:active,
@@ -291,6 +301,7 @@
                 <div><b>工序:</b>{$row.CGYMC|default=''|htmlentities}</div>
                 <div><b>本次数量:</b>{$row.This_quantity|default=''|htmlentities}</div>
                 <div><b>最高限价:</b>{$row.ceilingPrice|default=''|htmlentities}</div>
+                <div><b>备注:</b>{$row.MBZ|default=''|htmlentities}</div>
                 <div><b>需求发起人:</b>{$row.cywyxm|default=''|htmlentities}</div>
                 <div><b>需求发起时间:</b>{$row.createtime|default=''|htmlentities}</div>
             </div>
@@ -333,54 +344,68 @@
         <div class="rfq-sheet-body">
             <div class="rfq-field">
                 <label>需求编号</label>
-                <input type="text" id="ccydh" value="{$nextOrderCcydh|default=''|htmlentities}" readonly>
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="ccydh" value="{$nextOrderCcydh|default=''|htmlentities}" readonly>
+                </div>
             </div>
             <div class="rfq-field">
                 <label>印件名称<span class="req">*</span></label>
-                <input type="text" id="cyjmc" maxlength="200" autocomplete="off" placeholder="请输入印件名称">
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="cyjmc" maxlength="200" autocomplete="off">
+                </div>
             </div>
             <div class="rfq-field">
                 <label>需求部门<span class="req">*</span></label>
-                <div class="rfq-dept-combo" id="rfqDeptCombo">
-                    <div class="rfq-dept-row">
-                        <input type="text" id="cclbmmc" value="{$defaultCclbmmc|default='营销中心'|htmlentities}" maxlength="100" autocomplete="off" placeholder="可下拉选择或自行输入">
-                        <button type="button" class="rfq-dept-toggle" id="rfqDeptToggle" aria-label="选择部门">▼</button>
-                    </div>
-                    <div class="rfq-dept-menu" id="rfqDeptMenu">
-                        {volist name="rfqDeptOptions" id="deptName"}
-                        <button type="button" class="rfq-dept-item" data-value="{$deptName|htmlentities}">{$deptName|htmlentities}</button>
-                        {/volist}
-                        <div class="rfq-dept-empty">无匹配部门,可直接输入</div>
+                <div class="rfq-field-ctrl">
+                    <div class="rfq-dept-combo" id="rfqDeptCombo">
+                        <div class="rfq-dept-row">
+                            <input type="text" id="cclbmmc" value="{$defaultCclbmmc|default='营销中心'|htmlentities}" maxlength="100" autocomplete="off" placeholder="可下拉选择或自行输入">
+                            <button type="button" class="rfq-dept-toggle" id="rfqDeptToggle" aria-label="选择部门">▼</button>
+                        </div>
+                        <div class="rfq-dept-menu" id="rfqDeptMenu">
+                            {volist name="rfqDeptOptions" id="deptName"}
+                            <button type="button" class="rfq-dept-item" data-value="{$deptName|htmlentities}">{$deptName|htmlentities}</button>
+                            {/volist}
+                            <div class="rfq-dept-empty">无匹配部门,可直接输入</div>
+                        </div>
                     </div>
                 </div>
             </div>
             <div class="rfq-field">
                 <label>工序名称</label>
-                <input type="text" id="cgymc" maxlength="200" autocomplete="off">
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="cgymc" maxlength="200" autocomplete="off">
+                </div>
             </div>
             <div class="rfq-field">
                 <label>单位</label>
-                <input type="text" id="cdw" maxlength="50" autocomplete="off">
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="cdw" maxlength="50" autocomplete="off">
+                </div>
             </div>
             <div class="rfq-field">
                 <label>本次数量</label>
-                <input type="text" id="thisQty" maxlength="50" autocomplete="off" inputmode="decimal">
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="thisQty" maxlength="50" autocomplete="off" inputmode="decimal">
+                </div>
             </div>
             <div class="rfq-field">
                 <label>最高限价</label>
-                <input type="text" id="ceilingPrice" maxlength="50" autocomplete="off" inputmode="decimal">
-            </div>
-            <div class="rfq-field">
-                <label>订法</label>
-                <input type="text" id="cdf" maxlength="100" autocomplete="off">
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="ceilingPrice" maxlength="50" autocomplete="off" inputmode="decimal">
+                </div>
             </div>
             <div class="rfq-field">
                 <label>需求发起人</label>
-                <input type="text" id="cywyxm" value="{$adminNickname|default=''|htmlentities}" readonly>
+                <div class="rfq-field-ctrl">
+                    <input type="text" id="cywyxm" value="{$adminNickname|default=''|htmlentities}" readonly>
+                </div>
             </div>
-            <div class="rfq-field">
+            <div class="rfq-field rfq-field-area">
                 <label>备注</label>
-                <textarea id="mbz" maxlength="500"></textarea>
+                <div class="rfq-field-ctrl">
+                    <textarea id="mbz" maxlength="500"></textarea>
+                </div>
             </div>
         </div>
         <div class="rfq-sheet-acts">
@@ -554,6 +579,7 @@
                 + '<div><b>工序:</b>' + esc(row.CGYMC || '') + '</div>'
                 + '<div><b>本次数量:</b>' + esc(row.This_quantity || '') + '</div>'
                 + '<div><b>最高限价:</b>' + esc(row.ceilingPrice || '') + '</div>'
+                + '<div><b>备注:</b>' + esc(row.MBZ || '') + '</div>'
                 + '<div><b>需求发起人:</b>' + esc(row.cywyxm || '') + '</div>'
                 + '<div><b>需求发起时间:</b>' + esc(row.createtime || '') + '</div>'
                 + '</div>';
@@ -633,7 +659,18 @@
             if (e.target === rfqMask) closeAddModal();
         });
     }
-    if (rfqSheet) rfqSheet.addEventListener('click', function (e) { e.stopPropagation(); });
+    if (rfqSheet) {
+        rfqSheet.addEventListener('click', function (e) {
+            e.stopPropagation();
+            // 部门下拉展开时,点弹窗内空白处收起
+            var deptCombo = document.getElementById('rfqDeptCombo');
+            if (deptCombo && deptCombo.classList.contains('open') && !deptCombo.contains(e.target)) {
+                deptCombo.classList.remove('open');
+                var sheetBody = document.querySelector('.rfq-sheet-body');
+                if (sheetBody) sheetBody.style.overflowY = '';
+            }
+        });
+    }
 
     var quoteMask = document.getElementById('quoteMask');
     var quoteSheet = document.getElementById('quoteSheet');
@@ -721,7 +758,6 @@
         document.getElementById('cdw').value = '';
         document.getElementById('thisQty').value = '';
         document.getElementById('ceilingPrice').value = '';
-        document.getElementById('cdf').value = '';
         document.getElementById('mbz').value = '';
         document.getElementById('cywyxm').value = defaultStarter || '';
         if (!keepCcydh) {
@@ -741,13 +777,19 @@
         if (!combo || !input || !menu) return;
         var items = menu.querySelectorAll('.rfq-dept-item');
         var emptyEl = menu.querySelector('.rfq-dept-empty');
+        var sheetBody = document.querySelector('.rfq-sheet-body');
+        var typing = false;
 
-        function openMenu() {
+        function openMenu(showAll) {
             combo.classList.add('open');
-            filterMenu(input.value || '');
+            if (sheetBody) sheetBody.style.overflowY = 'hidden';
+            if (showAll) filterMenu('');
+            else filterMenu(input.value || '');
         }
         function closeMenu() {
             combo.classList.remove('open');
+            typing = false;
+            if (sheetBody) sheetBody.style.overflowY = '';
         }
         function filterMenu(keyword) {
             var kw = String(keyword || '').trim().toLowerCase();
@@ -765,38 +807,53 @@
             toggle.addEventListener('click', function (e) {
                 e.preventDefault();
                 e.stopPropagation();
+                typing = false;
                 if (combo.classList.contains('open')) closeMenu();
-                else openMenu();
+                else openMenu(true);
             });
         }
         input.addEventListener('focus', function () {
-            openMenu();
+            // 聚焦时展开全部部门,避免已填「营销中心」只剩一项
+            if (!typing) openMenu(true);
+            else openMenu(false);
         });
         input.addEventListener('click', function () {
-            openMenu();
+            if (!typing) openMenu(true);
         });
         input.addEventListener('input', function () {
-            openMenu();
+            typing = true;
+            openMenu(false);
             filterMenu(input.value || '');
         });
         items.forEach(function (btn) {
             btn.addEventListener('click', function (e) {
                 e.preventDefault();
+                e.stopPropagation();
                 var v = String(btn.getAttribute('data-value') || btn.textContent || '').trim();
                 input.value = v;
+                typing = false;
                 closeMenu();
             });
         });
         document.addEventListener('click', function (e) {
             if (!combo.contains(e.target)) closeMenu();
         });
+        // 兼容:点弹窗内其它输入框/空白时收起(rfqSheet 会 stopPropagation,需单独监听)
         if (rfqSheet) {
-            rfqSheet.addEventListener('scroll', closeMenu, true);
-        }
-        var sheetBody = document.querySelector('.rfq-sheet-body');
-        if (sheetBody) {
-            sheetBody.addEventListener('scroll', closeMenu);
+            rfqSheet.addEventListener('touchstart', function (e) {
+                if (combo.classList.contains('open') && !combo.contains(e.target)) {
+                    closeMenu();
+                }
+            }, { passive: true });
         }
+
+        // 下拉内部滚动:阻止手势冒泡到弹窗外层
+        menu.addEventListener('touchmove', function (e) {
+            e.stopPropagation();
+        }, { passive: true });
+        menu.addEventListener('wheel', function (e) {
+            e.stopPropagation();
+        }, { passive: true });
     })();
 
     document.getElementById('btnSubmit').addEventListener('click', function () {
@@ -819,7 +876,7 @@
             CDW: (document.getElementById('cdw').value || '').trim(),
             This_quantity: (document.getElementById('thisQty').value || '').trim(),
             ceilingPrice: (document.getElementById('ceilingPrice').value || '').trim(),
-            CDF: (document.getElementById('cdf').value || '').trim(),
+            CDF: '',
             MBZ: (document.getElementById('mbz').value || '').trim()
         }).then(function (ret) {
             btn.disabled = false;
@@ -829,7 +886,7 @@
                     nextCcydh = String(data.nextOrderCcydh);
                     document.getElementById('ccydh').value = nextCcydh;
                 }
-                showToast((ret.msg || '新增成功') + (data.CCYDH ? (':' + data.CCYDH) : ''), 'ok');
+                showToast((ret.msg || '新增成功'), 'ok');
                 closeAddModal();
                 loadList();
             } else if (ret && (ret.code === 401 || ret.code === '401')) {

+ 2 - 7
public/assets/js/backend/procuremen.js

@@ -2984,7 +2984,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     }
                 },
                 {field: 'CDW', title: '单位', operate: 'LIKE', width: 70, align: 'center', halign: 'center', valign: 'middle', class: 'procuremen-rfq-num-col'},
-                {field: 'CDF', title: '订法', operate: 'LIKE', width: 80, align: 'center', halign: 'center', valign: 'middle', class: 'procuremen-rfq-num-col'},
+                // 订法暂不展示
+                // {field: 'CDF', title: '订法', operate: 'LIKE', width: 80, align: 'center', halign: 'center', valign: 'middle', class: 'procuremen-rfq-num-col'},
                 {field: 'MBZ', title: '备注', operate: 'LIKE', width: 140, class: 'autocontent', formatter: Table.api.formatter.content},
                 {field: 'cywyxm', title: '需求发起人', operate: 'LIKE', width: 90, align: 'center', halign: 'center'},
                 {
@@ -3325,7 +3326,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 var cdw = (data && data.CDW) ? String(data.CDW) : '';
                 var qty = (data && data.This_quantity) ? String(data.This_quantity) : '';
                 var ceiling = (data && data.ceilingPrice) ? String(data.ceilingPrice) : '';
-                var cdf = (data && data.CDF) ? String(data.CDF) : '';
                 var mbz = (data && data.MBZ) ? String(data.MBZ) : '';
                 var html = '<div class="procuremen-rfq-issue-wrap" data-scydgy-id="' + rfqEscAttr(sid) + '" style="padding:12px 14px 4px;">'
                     + '<div style="margin:0 0 10px;overflow:auto;">'
@@ -3337,7 +3337,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     + '<th class="text-center" style="width:56px;">单位</th>'
                     + '<th class="text-center" style="width:72px;">本次数量</th>'
                     + '<th class="text-center" style="width:72px;">最高限价</th>'
-                    + '<th class="text-center" style="width:64px;">订法</th>'
                     + '<th style="width:100px;">备注</th>'
                     + '</tr></thead><tbody><tr>'
                     + '<td class="text-center">' + rfqEscHtml(ccydh) + '</td>'
@@ -3346,7 +3345,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     + '<td class="text-center">' + rfqEscHtml(cdw) + '</td>'
                     + '<td class="text-center">' + rfqEscHtml(qty) + '</td>'
                     + '<td class="text-center">' + rfqEscHtml(ceiling) + '</td>'
-                    + '<td class="text-center">' + rfqEscHtml(cdf) + '</td>'
                     + '<td>' + rfqEscHtml(mbz) + '</td>'
                     + '</tr></tbody></table></div>'
                     + '<div class="procuremen-rfq-issue-tip-row" style="margin:0 0 10px;display:flex;align-items:center;justify-content:space-between;gap:12px;">'
@@ -3593,7 +3591,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                     var cdw = (data && data.CDW) ? String(data.CDW) : '';
                     var qty = (data && data.This_quantity) ? String(data.This_quantity) : '';
                     var ceiling = (data && data.ceilingPrice) ? String(data.ceilingPrice) : '';
-                    var cdf = (data && data.CDF) ? String(data.CDF) : '';
                     var mbz = (data && data.MBZ) ? String(data.MBZ) : '';
                     var html = '<div class="procuremen-rfq-quotes-wrap" style="padding:12px 14px 8px;">'
                         + '<div style="margin:0 0 10px;overflow:auto;">'
@@ -3605,7 +3602,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         + '<th class="text-center" style="width:56px;">单位</th>'
                         + '<th class="text-center" style="width:72px;">本次数量</th>'
                         + '<th class="text-center" style="width:72px;">最高限价</th>'
-                        + '<th class="text-center" style="width:64px;">订法</th>'
                         + '<th style="width:100px;">备注</th>'
                         + '</tr></thead><tbody><tr>'
                         + '<td class="text-center">' + rfqEscHtml(ccydh) + '</td>'
@@ -3614,7 +3610,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         + '<td class="text-center">' + rfqEscHtml(cdw) + '</td>'
                         + '<td class="text-center">' + rfqEscHtml(qty) + '</td>'
                         + '<td class="text-center">' + rfqEscHtml(ceiling) + '</td>'
-                        + '<td class="text-center">' + rfqEscHtml(cdf) + '</td>'
                         + '<td>' + rfqEscHtml(mbz) + '</td>'
                         + '</tr></tbody></table></div>';
                     if (!list.length) {