|
@@ -57,7 +57,7 @@ class Procuremen extends Backend
|
|
|
$eid = (int)$purchaseOrderDetailId;
|
|
$eid = (int)$purchaseOrderDetailId;
|
|
|
$base = $this->resolveMprocMobilePublicBaseUrl();
|
|
$base = $this->resolveMprocMobilePublicBaseUrl();
|
|
|
if ($base === '') {
|
|
if ($base === '') {
|
|
|
- throw new \Exception('请在 application/extra/mproc.php 中配置外网可访问的正式域名');
|
|
|
|
|
|
|
+ throw new \Exception('无法生成手机端链接,请检查站点访问地址或 application/extra/mproc.php 中的 mobile_base_url');
|
|
|
}
|
|
}
|
|
|
$path = trim((string)Config::get('mproc.mobile_index_path'));
|
|
$path = trim((string)Config::get('mproc.mobile_index_path'));
|
|
|
if ($path === '') {
|
|
if ($path === '') {
|
|
@@ -92,7 +92,6 @@ class Procuremen extends Backend
|
|
|
if (preg_match('/^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/', $host)) {
|
|
if (preg_match('/^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/', $host)) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
- // 无点主机名(xh、erp 等)在小米/企业邮安全跳转中常报 Invalid url
|
|
|
|
|
if (strpos($host, '.') === false) {
|
|
if (strpos($host, '.') === false) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
@@ -101,7 +100,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 解析用于外发邮件/短信的手机端站点根(https://域名 无末尾斜杠)
|
|
|
|
|
|
|
+ * 解析用于外发邮件/短信的手机端站点根
|
|
|
*/
|
|
*/
|
|
|
protected function resolveMprocMobilePublicBaseUrl()
|
|
protected function resolveMprocMobilePublicBaseUrl()
|
|
|
{
|
|
{
|
|
@@ -125,8 +124,13 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Log::write('外发邮件手机链接:未配置有效 mproc.mobile_base_url,且当前访问主机不适合作为外链,请在 application/extra/mproc.php 设置 https 正式域名', 'warning');
|
|
|
|
|
|
|
+ // 本地联调:127.0.0.1、内网 IP、虚拟主机等无法用「公网域名」规则时,退回当前请求根地址
|
|
|
|
|
+ $reqBase = rtrim($this->request->scheme() . '://' . $this->request->host(), '/');
|
|
|
|
|
+ if ($reqBase !== '' && preg_match('#^https?://#i', $reqBase)) {
|
|
|
|
|
+ return $reqBase;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ Log::write('外发邮件手机链接:配置地址失效', 'warning');
|
|
|
return '';
|
|
return '';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -146,47 +150,49 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 左侧菜单:仅「近 12 个自然月(含当月)」
|
|
|
|
|
|
|
+ * 获取 Redis 中 procuremen_redis
|
|
|
*/
|
|
*/
|
|
|
- protected function getIndexSidebarYearMonths()
|
|
|
|
|
|
|
+ protected function ProcuremenRedis(): array
|
|
|
{
|
|
{
|
|
|
- $ymSet = [];
|
|
|
|
|
- $anchor = strtotime(date('Y-m-01'));
|
|
|
|
|
- for ($i = 0; $i < 12; $i++) {
|
|
|
|
|
- $ym = date('Y-m', strtotime("-{$i} month", $anchor));
|
|
|
|
|
- $ymSet[$ym] = true;
|
|
|
|
|
- }
|
|
|
|
|
- $windowKeys = array_keys($ymSet);
|
|
|
|
|
- $minYm = min($windowKeys);
|
|
|
|
|
- $maxYm = max($windowKeys);
|
|
|
|
|
-
|
|
|
|
|
- $rows = [];
|
|
|
|
|
try {
|
|
try {
|
|
|
- $query = Db::table('scydgy')
|
|
|
|
|
- ->alias('a')
|
|
|
|
|
- ->join('mcyd b', 'b.ICYDID = a.ICYDID AND b.iStatus >= 10', 'inner')
|
|
|
|
|
- ->where([
|
|
|
|
|
- 'a.bwjg' => 1,
|
|
|
|
|
- 'a.iEndBz' => 0,
|
|
|
|
|
- 'a.iType' => 0,
|
|
|
|
|
- 'a.iStatus' => 10,
|
|
|
|
|
- ]);
|
|
|
|
|
- $this->whereMcydDputrecordValid($query, 'a');
|
|
|
|
|
- $rows = $query->field("DATE_FORMAT(a.dputrecord, '%Y-%m') as ym")
|
|
|
|
|
- ->group("DATE_FORMAT(a.dputrecord, '%Y-%m')")
|
|
|
|
|
- ->orderRaw("DATE_FORMAT(a.dputrecord, '%Y-%m') DESC")
|
|
|
|
|
- ->select();
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
- $rows = [];
|
|
|
|
|
|
|
+ $redis = redis();
|
|
|
|
|
+ $raw = $redis->get('procuremen_redis');
|
|
|
|
|
+ if ($raw === false || $raw === '') {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ $decoded = json_decode($raw, true);
|
|
|
|
|
+ if (!is_array($decoded) || !isset($decoded['data']) || !is_array($decoded['data'])) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ return $decoded['data'];
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ return [];
|
|
|
}
|
|
}
|
|
|
- foreach ($rows as $r) {
|
|
|
|
|
- $ym = isset($r['ym']) ? trim((string)$r['ym']) : '';
|
|
|
|
|
- if (!preg_match('/^\d{4}-\d{2}$/', $ym)) {
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 左侧菜单
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function GetIndexYearMonths()
|
|
|
|
|
+ {
|
|
|
|
|
+ $ymSet = [];
|
|
|
|
|
+ //获取此方法调用缓存数据
|
|
|
|
|
+ foreach ($this->ProcuremenRedis() as $r) {
|
|
|
|
|
+ if (!is_array($r)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $ds = trim((string)($r['dputrecord'] ?? ''));
|
|
|
|
|
+ if ($ds === '' || stripos($ds, '0000-00-00') === 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!preg_match('/^([12]\d{3})-(\d{1,2})-(\d{1,2})/', $ds, $m)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- if (strcmp($ym, $minYm) >= 0 && strcmp($ym, $maxYm) <= 0) {
|
|
|
|
|
- $ymSet[$ym] = true;
|
|
|
|
|
|
|
+ $mo = (int)$m[2];
|
|
|
|
|
+ if ($mo < 1 || $mo > 12) {
|
|
|
|
|
+ continue;
|
|
|
}
|
|
}
|
|
|
|
|
+ $ymSet[$m[1] . '-' . str_pad((string)$mo, 2, '0', STR_PAD_LEFT)] = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$ymList = array_keys($ymSet);
|
|
$ymList = array_keys($ymSet);
|
|
@@ -194,15 +200,12 @@ class Procuremen extends Backend
|
|
|
|
|
|
|
|
$byYear = [];
|
|
$byYear = [];
|
|
|
foreach ($ymList as $ym) {
|
|
foreach ($ymList as $ym) {
|
|
|
- if (!preg_match('/^\d{4}-\d{2}$/', $ym)) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
$y = substr($ym, 0, 4);
|
|
$y = substr($ym, 0, 4);
|
|
|
- $m = (int)substr($ym, 5, 2);
|
|
|
|
|
|
|
+ $mo = (int)substr($ym, 5, 2);
|
|
|
if (!isset($byYear[$y])) {
|
|
if (!isset($byYear[$y])) {
|
|
|
$byYear[$y] = [];
|
|
$byYear[$y] = [];
|
|
|
}
|
|
}
|
|
|
- $byYear[$y][] = ['ym' => $ym, 'label' => $m . '月'];
|
|
|
|
|
|
|
+ $byYear[$y][] = ['ym' => $ym, 'label' => $mo . '月'];
|
|
|
}
|
|
}
|
|
|
krsort($byYear, SORT_NUMERIC);
|
|
krsort($byYear, SORT_NUMERIC);
|
|
|
foreach ($byYear as $y => $items) {
|
|
foreach ($byYear as $y => $items) {
|
|
@@ -226,8 +229,16 @@ class Procuremen extends Backend
|
|
|
$this->request->filter(['strip_tags', 'trim']);
|
|
$this->request->filter(['strip_tags', 'trim']);
|
|
|
|
|
|
|
|
if (!$this->request->isAjax()) {
|
|
if (!$this->request->isAjax()) {
|
|
|
|
|
+ $rootTrue = rtrim((string)$this->request->root(true), '/');
|
|
|
|
|
+ $indexPhpRoot = preg_replace('#/[^/]+\.php$#i', '/index.php', $rootTrue);
|
|
|
|
|
+ if ($indexPhpRoot === $rootTrue && !preg_match('#/index\.php$#i', $rootTrue)) {
|
|
|
|
|
+ $indexPhpRoot = $rootTrue . '/index.php';
|
|
|
|
|
+ }
|
|
|
|
|
+ $procuremenRedisApi = $indexPhpRoot . '/api/procuremen/getprocuremen';
|
|
|
|
|
+ $this->view->assign('procuremenRedisApi', $procuremenRedisApi);
|
|
|
$this->view->assign('defaultYm', date('Y-m'));
|
|
$this->view->assign('defaultYm', date('Y-m'));
|
|
|
- $this->view->assign('sidebarYearMonths', $this->getIndexSidebarYearMonths());
|
|
|
|
|
|
|
+ $this->view->assign('sidebarYearMonths', $this->GetIndexYearMonths());
|
|
|
|
|
+
|
|
|
return $this->view->fetch();
|
|
return $this->view->fetch();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -285,7 +296,6 @@ class Procuremen extends Backend
|
|
|
|
|
|
|
|
if (in_array($wffTab, ['pending', 'done', 'picked'], true)) {
|
|
if (in_array($wffTab, ['pending', 'done', 'picked'], true)) {
|
|
|
$wantStatus = $wffTab === 'pending' ? 0 : 1;
|
|
$wantStatus = $wffTab === 'pending' ? 0 : 1;
|
|
|
- $pool = [];
|
|
|
|
|
$dbRows = [];
|
|
$dbRows = [];
|
|
|
try {
|
|
try {
|
|
|
if ($wantStatus === 0) {
|
|
if ($wantStatus === 0) {
|
|
@@ -317,95 +327,16 @@ class Procuremen extends Backend
|
|
|
return $sid > 0 && isset($pickedSidSet[$sid]);
|
|
return $sid > 0 && isset($pickedSidSet[$sid]);
|
|
|
}));
|
|
}));
|
|
|
}
|
|
}
|
|
|
- $dStampMap = [];
|
|
|
|
|
- $sidList = [];
|
|
|
|
|
- foreach ($dbRows as $tmpRow) {
|
|
|
|
|
- if (is_array($tmpRow) && isset($tmpRow['scydgy_id'])) {
|
|
|
|
|
- $sid = (int)$tmpRow['scydgy_id'];
|
|
|
|
|
- if ($sid > 0) {
|
|
|
|
|
- $sidList[$sid] = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if ($sidList !== []) {
|
|
|
|
|
- try {
|
|
|
|
|
- $dStampMap = Db::table('scydgy')->where('ID', 'in', array_keys($sidList))->column('dStamp', 'ID');
|
|
|
|
|
- } catch (\Throwable $e) {
|
|
|
|
|
- $dStampMap = [];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- foreach ($dbRows as $dbRow) {
|
|
|
|
|
- $rj = null;
|
|
|
|
|
- if (!empty($dbRow['row_json'])) {
|
|
|
|
|
- $decoded = json_decode($dbRow['row_json'], true);
|
|
|
|
|
- if (is_array($decoded)) {
|
|
|
|
|
- $rj = $decoded;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if ($rj !== null && isset($rj['ID'])) {
|
|
|
|
|
- $rid = (int)$rj['ID'];
|
|
|
|
|
- $dsFix = isset($rj['dStamp']) ? trim((string)$rj['dStamp']) : '';
|
|
|
|
|
- if (($dsFix === '' || stripos($dsFix, '0000-00-00') === 0)
|
|
|
|
|
- && isset($dStampMap[$rid]) && trim((string)$dStampMap[$rid]) !== '') {
|
|
|
|
|
- $rj['dStamp'] = $dStampMap[$rid];
|
|
|
|
|
- }
|
|
|
|
|
- if (array_key_exists('id', $dbRow)) {
|
|
|
|
|
- $rj['purchase_order_id'] = (int)$dbRow['id'];
|
|
|
|
|
- }
|
|
|
|
|
- $pool[] = $rj;
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- $r = [];
|
|
|
|
|
- foreach ($dbRow as $k => $v) {
|
|
|
|
|
- $lk = strtolower((string)$k);
|
|
|
|
|
- if ($lk === 'id' || $lk === 'row_json') {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- $r[$k] = $v;
|
|
|
|
|
- }
|
|
|
|
|
- if (isset($dbRow['scydgy_id'])) {
|
|
|
|
|
- $r['ID'] = (int)$dbRow['scydgy_id'];
|
|
|
|
|
- $sid = $r['ID'];
|
|
|
|
|
- $dsOut = '';
|
|
|
|
|
- if (isset($dStampMap[$sid])) {
|
|
|
|
|
- $t = trim((string)$dStampMap[$sid]);
|
|
|
|
|
- if ($t !== '' && stripos($t, '0000-00-00') !== 0) {
|
|
|
|
|
- $dsOut = $dStampMap[$sid];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if ($dsOut === '' && !empty($dbRow['createtime'])) {
|
|
|
|
|
- $ct = $dbRow['createtime'];
|
|
|
|
|
- if (is_numeric($ct) && (int)$ct > 946684800) {
|
|
|
|
|
- $dsOut = date('Y-m-d H:i:s', (int)$ct);
|
|
|
|
|
- } elseif (is_string($ct) && trim($ct) !== '') {
|
|
|
|
|
- $tc = trim($ct);
|
|
|
|
|
- if ($tc !== '' && stripos($tc, '0000-00-00') !== 0) {
|
|
|
|
|
- $dsOut = $tc;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if ($dsOut !== '') {
|
|
|
|
|
- $r['dStamp'] = $dsOut;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (array_key_exists('id', $dbRow)) {
|
|
|
|
|
- $r['purchase_order_id'] = (int)$dbRow['id'];
|
|
|
|
|
- }
|
|
|
|
|
- $pool[] = $r;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ $pool = $this->procuremenPoolFromPurchaseOrderDbRows($dbRows);
|
|
|
} else {
|
|
} else {
|
|
|
- $redis = redis();
|
|
|
|
|
- $raw = $redis->get('procuremen_redis');
|
|
|
|
|
- if ($raw === false || $raw === '') {
|
|
|
|
|
|
|
+ $pool = $this->ProcuremenRedis();
|
|
|
|
|
+ if ($pool === []) {
|
|
|
return json([
|
|
return json([
|
|
|
'total' => 0,
|
|
'total' => 0,
|
|
|
'rows' => [],
|
|
'rows' => [],
|
|
|
'msg' => '暂无缓存数据',
|
|
'msg' => '暂无缓存数据',
|
|
|
]);
|
|
]);
|
|
|
}
|
|
}
|
|
|
- $decoded = json_decode($raw, true);
|
|
|
|
|
- $pool = (is_array($decoded) && isset($decoded['data']) && is_array($decoded['data']))
|
|
|
|
|
- ? $decoded['data'] : [];
|
|
|
|
|
|
|
|
|
|
// 未发:主表已有且 status 为 0/1 才从列表隐藏;status 为空(NULL)仍可在未发展示
|
|
// 未发:主表已有且 status 为 0/1 才从列表隐藏;status 为空(NULL)仍可在未发展示
|
|
|
try {
|
|
try {
|
|
@@ -668,6 +599,100 @@ class Procuremen extends Backend
|
|
|
return $out;
|
|
return $out;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 与列表「已下发 / 已选中 / 已完结」同源:将 purchase_order 行还原为工序列表行(含 row_json、dStamp 补全)
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return array<int, array<string, mixed>>
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function procuremenPoolFromPurchaseOrderDbRows(array $dbRows): array
|
|
|
|
|
+ {
|
|
|
|
|
+ $pool = [];
|
|
|
|
|
+ if (!is_array($dbRows) || $dbRows === []) {
|
|
|
|
|
+ return $pool;
|
|
|
|
|
+ }
|
|
|
|
|
+ $dStampMap = [];
|
|
|
|
|
+ $sidList = [];
|
|
|
|
|
+ foreach ($dbRows as $tmpRow) {
|
|
|
|
|
+ if (is_array($tmpRow) && isset($tmpRow['scydgy_id'])) {
|
|
|
|
|
+ $sid = (int)$tmpRow['scydgy_id'];
|
|
|
|
|
+ if ($sid > 0) {
|
|
|
|
|
+ $sidList[$sid] = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($sidList !== []) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $dStampMap = Db::table('scydgy')->where('ID', 'in', array_keys($sidList))->column('dStamp', 'ID');
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ $dStampMap = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ foreach ($dbRows as $dbRow) {
|
|
|
|
|
+ if (!is_array($dbRow)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $rj = null;
|
|
|
|
|
+ if (!empty($dbRow['row_json'])) {
|
|
|
|
|
+ $decoded = json_decode($dbRow['row_json'], true);
|
|
|
|
|
+ if (is_array($decoded)) {
|
|
|
|
|
+ $rj = $decoded;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($rj !== null && isset($rj['ID'])) {
|
|
|
|
|
+ $rid = (int)$rj['ID'];
|
|
|
|
|
+ $dsFix = isset($rj['dStamp']) ? trim((string)$rj['dStamp']) : '';
|
|
|
|
|
+ if (($dsFix === '' || stripos($dsFix, '0000-00-00') === 0)
|
|
|
|
|
+ && isset($dStampMap[$rid]) && trim((string)$dStampMap[$rid]) !== '') {
|
|
|
|
|
+ $rj['dStamp'] = $dStampMap[$rid];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (array_key_exists('id', $dbRow)) {
|
|
|
|
|
+ $rj['purchase_order_id'] = (int)$dbRow['id'];
|
|
|
|
|
+ }
|
|
|
|
|
+ $pool[] = $rj;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $r = [];
|
|
|
|
|
+ foreach ($dbRow as $k => $v) {
|
|
|
|
|
+ $lk = strtolower((string)$k);
|
|
|
|
|
+ if ($lk === 'id' || $lk === 'row_json') {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $r[$k] = $v;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isset($dbRow['scydgy_id'])) {
|
|
|
|
|
+ $r['ID'] = (int)$dbRow['scydgy_id'];
|
|
|
|
|
+ $sid = $r['ID'];
|
|
|
|
|
+ $dsOut = '';
|
|
|
|
|
+ if (isset($dStampMap[$sid])) {
|
|
|
|
|
+ $t = trim((string)$dStampMap[$sid]);
|
|
|
|
|
+ if ($t !== '' && stripos($t, '0000-00-00') !== 0) {
|
|
|
|
|
+ $dsOut = $dStampMap[$sid];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($dsOut === '' && !empty($dbRow['createtime'])) {
|
|
|
|
|
+ $ct = $dbRow['createtime'];
|
|
|
|
|
+ if (is_numeric($ct) && (int)$ct > 946684800) {
|
|
|
|
|
+ $dsOut = date('Y-m-d H:i:s', (int)$ct);
|
|
|
|
|
+ } elseif (is_string($ct) && trim($ct) !== '') {
|
|
|
|
|
+ $tc = trim($ct);
|
|
|
|
|
+ if ($tc !== '' && stripos($tc, '0000-00-00') !== 0) {
|
|
|
|
|
+ $dsOut = $tc;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($dsOut !== '') {
|
|
|
|
|
+ $r['dStamp'] = $dsOut;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (array_key_exists('id', $dbRow)) {
|
|
|
|
|
+ $r['purchase_order_id'] = (int)$dbRow['id'];
|
|
|
|
|
+ }
|
|
|
|
|
+ $pool[] = $r;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $pool;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 已下发列表汇总:按工序行 ID 统计 purchase_order_detail 条数、已填金额条数、已填货期条数
|
|
* 已下发列表汇总:按工序行 ID 统计 purchase_order_detail 条数、已填金额条数、已填货期条数
|
|
|
*
|
|
*
|
|
@@ -721,7 +746,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 列表筛选:月份、dStamp 合法性、快速搜索、Bootstrap Table filter(与原先 Redis 分支一致)
|
|
|
|
|
|
|
+ * 列表筛选:月份按 dputrecord(提交日期)、快速搜索、Bootstrap Table filter
|
|
|
*
|
|
*
|
|
|
* @return array
|
|
* @return array
|
|
|
*/
|
|
*/
|
|
@@ -755,13 +780,20 @@ class Procuremen extends Backend
|
|
|
if (!is_array($r)) {
|
|
if (!is_array($r)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- $ds = isset($r['dStamp']) ? trim((string)$r['dStamp']) : '';
|
|
|
|
|
|
|
+ $ds = isset($r['dputrecord']) ? trim((string)$r['dputrecord']) : '';
|
|
|
if ($ds === '' || stripos($ds, '0000-00-00') === 0
|
|
if ($ds === '' || stripos($ds, '0000-00-00') === 0
|
|
|
- || !preg_match('/^[12]\d{3}-\d{1,2}-\d{1,2}/', $ds)) {
|
|
|
|
|
|
|
+ || !preg_match('/^([12]\d{3})-(\d{1,2})-(\d{1,2})/', $ds, $m)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
if ($applyMonthRange) {
|
|
if ($applyMonthRange) {
|
|
|
- if (strcmp($ds, $monthStart) < 0 || strcmp($ds, $monthEnd) > 0) {
|
|
|
|
|
|
|
+ $mo = (int)$m[2];
|
|
|
|
|
+ if ($mo < 1 || $mo > 12) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $ymRow = $m[1] . '-' . str_pad((string)$mo, 2, '0', STR_PAD_LEFT);
|
|
|
|
|
+ $rowMonthStart = $ymRow . '-01 00:00:00';
|
|
|
|
|
+ $rowMonthEnd = date('Y-m-t 23:59:59', strtotime($rowMonthStart));
|
|
|
|
|
+ if (strcmp($rowMonthEnd, $monthStart) < 0 || strcmp($rowMonthStart, $monthEnd) > 0) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1813,6 +1845,19 @@ class Procuremen extends Backend
|
|
|
$this->error('请至少选择一个下发单位');
|
|
$this->error('请至少选择一个下发单位');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ $sysRq = trim((string)$this->request->post('sys_rq', ''));
|
|
|
|
|
+ if ($sysRq === '') {
|
|
|
|
|
+ $this->error('请选择截止时间');
|
|
|
|
|
+ }
|
|
|
|
|
+ $sysRqTs = strtotime($sysRq);
|
|
|
|
|
+ if ($sysRqTs === false || $sysRqTs <= 0) {
|
|
|
|
|
+ $this->error('截止时间格式无效');
|
|
|
|
|
+ }
|
|
|
|
|
+ //示例:2026-05-18 14:31:09
|
|
|
|
|
+ $sysRqDb = date('Y-m-d H:i:s', $sysRqTs);
|
|
|
|
|
+ //示例:2026-05-18 14:31
|
|
|
|
|
+ $sysRqNotify = date('Y-m-d H:i', $sysRqTs);
|
|
|
|
|
+
|
|
|
$toDb = function ($value) {
|
|
$toDb = function ($value) {
|
|
|
if ($value === null) {
|
|
if ($value === null) {
|
|
|
return null;
|
|
return null;
|
|
@@ -1852,6 +1897,7 @@ class Procuremen extends Backend
|
|
|
'This_quantity' => $row['This_quantity'] ?? $row['this_quantity'] ?? null,
|
|
'This_quantity' => $row['This_quantity'] ?? $row['this_quantity'] ?? null,
|
|
|
'ceilingPrice' => $row['ceilingPrice'] ?? $row['ceiling_price'] ?? null,
|
|
'ceilingPrice' => $row['ceilingPrice'] ?? $row['ceiling_price'] ?? null,
|
|
|
'status' => 0,
|
|
'status' => 0,
|
|
|
|
|
+ 'sys_rq' => $sysRqDb,
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
if ($exists) {
|
|
if ($exists) {
|
|
@@ -1925,23 +1971,25 @@ class Procuremen extends Backend
|
|
|
您好,{$companyName}:<br><br>
|
|
您好,{$companyName}:<br><br>
|
|
|
您有新的外发加工订单待处理:<br>
|
|
您有新的外发加工订单待处理:<br>
|
|
|
订单号:{$row['CCYDH']}<br>
|
|
订单号:{$row['CCYDH']}<br>
|
|
|
- 印件名称:{$row['CYJMC']}<br><br>
|
|
|
|
|
- 请点击下面链接,登录后可直接打开本条订单(无需再搜索):<br>
|
|
|
|
|
|
|
+ 印件名称:{$row['CYJMC']}<br>
|
|
|
|
|
+ 请在 <strong>{$sysRqNotify}</strong> 前登陆我司平台处理<br><br>
|
|
|
|
|
+ 您可点击链接进行查看等操作:<br>
|
|
|
<a href=\"{$mprocUrlEsc}\">{$mprocUrlEsc}</a><br><br>
|
|
<a href=\"{$mprocUrlEsc}\">{$mprocUrlEsc}</a><br><br>
|
|
|
- 登录后可在手机端填写金额与交货日期。<br><br>
|
|
|
|
|
请及时查收并处理,谢谢!
|
|
请及时查收并处理,谢谢!
|
|
|
";
|
|
";
|
|
|
|
|
|
|
|
$mail->send();
|
|
$mail->send();
|
|
|
|
|
|
|
|
|
|
+ //发送短信
|
|
|
$ccydh = isset($row['CCYDH']) ? (string)$row['CCYDH'] : '';
|
|
$ccydh = isset($row['CCYDH']) ? (string)$row['CCYDH'] : '';
|
|
|
$cyjmc = isset($row['CYJMC']) ? (string)$row['CYJMC'] : '';
|
|
$cyjmc = isset($row['CYJMC']) ? (string)$row['CYJMC'] : '';
|
|
|
$smsContent = "您好,{$companyName}:\n\n"
|
|
$smsContent = "您好,{$companyName}:\n\n"
|
|
|
. "您有新的外发加工订单待处理:\n"
|
|
. "您有新的外发加工订单待处理:\n"
|
|
|
. "订单号:{$ccydh}\n"
|
|
. "订单号:{$ccydh}\n"
|
|
|
- . "印件名称:{$cyjmc}\n\n"
|
|
|
|
|
- . "手机打开链接(登录后直达本条):\n"
|
|
|
|
|
- . $mprocUrl . "\n\n"
|
|
|
|
|
|
|
+ . "印件名称:{$cyjmc}\n"
|
|
|
|
|
+ . "请在 {$sysRqNotify} 前登陆我司平台处理\n\n"
|
|
|
|
|
+// . "您可点击链接进行查看等操作::\n"
|
|
|
|
|
+// . $mprocUrl . "\n\n"
|
|
|
. '请及时查收并处理,谢谢!';
|
|
. '请及时查收并处理,谢谢!';
|
|
|
$this->smsbao($phone, $smsContent);
|
|
$this->smsbao($phone, $smsContent);
|
|
|
}
|
|
}
|
|
@@ -2161,7 +2209,8 @@ class Procuremen extends Backend
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 月份外发明细导出
|
|
|
|
|
|
|
+ * 按月份导出:已完结且采购确认已选定供应商(明细 status=1),与列表「已完结」∩「已选中」一致。
|
|
|
|
|
+ * 表头固定 8 列(与历史「外发明细」模板一致):序号、传票号、传票名称、外加工单位、订法、客户名称、工序、加工金额。
|
|
|
*/
|
|
*/
|
|
|
public function export_month_outward()
|
|
public function export_month_outward()
|
|
|
{
|
|
{
|
|
@@ -2172,35 +2221,99 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
$monthStart = $ym . '-01 00:00:00';
|
|
$monthStart = $ym . '-01 00:00:00';
|
|
|
$monthEnd = date('Y-m-t 23:59:59', strtotime($monthStart));
|
|
$monthEnd = date('Y-m-t 23:59:59', strtotime($monthStart));
|
|
|
- $unixStart = (int)strtotime($monthStart);
|
|
|
|
|
- $unixEnd = (int)strtotime($monthEnd);
|
|
|
|
|
|
|
|
|
|
- $rows = [];
|
|
|
|
|
|
|
+ $dbRows = [];
|
|
|
try {
|
|
try {
|
|
|
- $rows = Db::table('purchase_order_detail')
|
|
|
|
|
- ->whereRaw(
|
|
|
|
|
- '(TRIM(CAST(createtime AS CHAR(64))) LIKE ?)'
|
|
|
|
|
- . ' OR ((createtime REGEXP \'^[0-9]+$\') AND CAST(createtime AS UNSIGNED) BETWEEN ? AND ?)',
|
|
|
|
|
- [$ym . '%', $unixStart, $unixEnd]
|
|
|
|
|
- )
|
|
|
|
|
- ->order('CCYDH', 'asc')
|
|
|
|
|
- ->order('company_name', 'asc')
|
|
|
|
|
- ->order('id', 'asc')
|
|
|
|
|
- ->select();
|
|
|
|
|
|
|
+ $dbRows = Db::table('purchase_order')->where('status', 1)->select();
|
|
|
} catch (\Throwable $e) {
|
|
} catch (\Throwable $e) {
|
|
|
- $rows = [];
|
|
|
|
|
|
|
+ $dbRows = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!is_array($dbRows)) {
|
|
|
|
|
+ $dbRows = [];
|
|
|
}
|
|
}
|
|
|
|
|
+ $pickedSidSet = $this->loadScydgyIdsWithPickedSupplierDetail();
|
|
|
|
|
+ $dbRows = array_values(array_filter($dbRows, function ($dbRow) use ($pickedSidSet) {
|
|
|
|
|
+ if (!is_array($dbRow)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ $sid = (int)($dbRow['scydgy_id'] ?? 0);
|
|
|
|
|
+ if ($sid <= 0 && isset($dbRow['SCYDGY_ID'])) {
|
|
|
|
|
+ $sid = (int)$dbRow['SCYDGY_ID'];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- $groups = [];
|
|
|
|
|
- foreach ($rows as $r) {
|
|
|
|
|
- if (!is_array($r)) {
|
|
|
|
|
|
|
+ return $sid > 0 && isset($pickedSidSet[$sid]);
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ $pool = $this->procuremenPoolFromPurchaseOrderDbRows($dbRows);
|
|
|
|
|
+ $filtered = $this->filterProcuremenIndexPool($pool, $monthStart, $monthEnd, true, '', [], []);
|
|
|
|
|
+
|
|
|
|
|
+ $mainBySid = [];
|
|
|
|
|
+ foreach ($filtered as $rw) {
|
|
|
|
|
+ if (!is_array($rw)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- $k = (string)($r['CCYDH'] ?? '') . "\x1f" . (string)($r['company_name'] ?? '');
|
|
|
|
|
|
|
+ $rid = (int)($rw['ID'] ?? 0);
|
|
|
|
|
+ if ($rid > 0) {
|
|
|
|
|
+ $mainBySid[$rid] = $rw;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($mainBySid === []) {
|
|
|
|
|
+ $detailRows = [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $detailRows = Db::table('purchase_order_detail')
|
|
|
|
|
+ ->where('scydgy_id', 'in', array_keys($mainBySid))
|
|
|
|
|
+ ->where('status', 1)
|
|
|
|
|
+ ->order('CCYDH', 'asc')
|
|
|
|
|
+ ->order('company_name', 'asc')
|
|
|
|
|
+ ->order('id', 'asc')
|
|
|
|
|
+ ->select();
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $detailRows = Db::table('purchase_order_detail')
|
|
|
|
|
+ ->where('scydgy_id', 'in', array_keys($mainBySid))
|
|
|
|
|
+ ->where('status', 1)
|
|
|
|
|
+ ->order('CCYDH', 'asc')
|
|
|
|
|
+ ->order('company_name', 'asc')
|
|
|
|
|
+ ->order('ID', 'asc')
|
|
|
|
|
+ ->select();
|
|
|
|
|
+ } catch (\Throwable $e2) {
|
|
|
|
|
+ $detailRows = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!is_array($detailRows)) {
|
|
|
|
|
+ $detailRows = [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $exportLines = [];
|
|
|
|
|
+ foreach ($detailRows as $dr) {
|
|
|
|
|
+ if (!is_array($dr)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $sid = (int)($dr['scydgy_id'] ?? $dr['SCYDGY_ID'] ?? 0);
|
|
|
|
|
+ if ($sid <= 0 || !isset($mainBySid[$sid])) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $m = $mainBySid[$sid];
|
|
|
|
|
+ $exportLines[] = [
|
|
|
|
|
+ 'CCYDH' => (string)($dr['CCYDH'] ?? $m['CCYDH'] ?? ''),
|
|
|
|
|
+ 'CYJMC' => (string)($dr['CYJMC'] ?? $m['CYJMC'] ?? ''),
|
|
|
|
|
+ 'company_name' => (string)($dr['company_name'] ?? ''),
|
|
|
|
|
+ 'CDF' => (string)($m['CDF'] ?? ''),
|
|
|
|
|
+ 'cGzzxMc' => (string)($m['cGzzxMc'] ?? ''),
|
|
|
|
|
+ 'gx' => $this->procuremenExportGxText($m),
|
|
|
|
|
+ 'detail' => $dr,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $groups = [];
|
|
|
|
|
+ foreach ($exportLines as $line) {
|
|
|
|
|
+ $k = $line['CCYDH'] . "\x1f" . $line['company_name'];
|
|
|
if (!isset($groups[$k])) {
|
|
if (!isset($groups[$k])) {
|
|
|
$groups[$k] = [];
|
|
$groups[$k] = [];
|
|
|
}
|
|
}
|
|
|
- $groups[$k][] = $r;
|
|
|
|
|
|
|
+ $groups[$k][] = $line;
|
|
|
}
|
|
}
|
|
|
ksort($groups, SORT_STRING);
|
|
ksort($groups, SORT_STRING);
|
|
|
|
|
|
|
@@ -2229,31 +2342,32 @@ class Procuremen extends Backend
|
|
|
$sumSubtotalCounts = 0;
|
|
$sumSubtotalCounts = 0;
|
|
|
$grandAmount = 0.0;
|
|
$grandAmount = 0.0;
|
|
|
|
|
|
|
|
- if (empty($groups)) {
|
|
|
|
|
|
|
+ if ($groups === []) {
|
|
|
$sheet->mergeCells('A3:H3');
|
|
$sheet->mergeCells('A3:H3');
|
|
|
- $sheet->setCellValue('A3', '(当月暂无外发明细)');
|
|
|
|
|
|
|
+ $sheet->setCellValue('A3', '(当月暂无符合条件的外发明细)');
|
|
|
$sheet->getStyle('A3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
|
$sheet->getStyle('A3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
|
|
$rowNum = 4;
|
|
$rowNum = 4;
|
|
|
} else {
|
|
} else {
|
|
|
foreach ($groups as $items) {
|
|
foreach ($groups as $items) {
|
|
|
- if (empty($items)) {
|
|
|
|
|
|
|
+ if ($items === []) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
$groupLineCount = count($items);
|
|
$groupLineCount = count($items);
|
|
|
$subAmount = 0.0;
|
|
$subAmount = 0.0;
|
|
|
$i = 0;
|
|
$i = 0;
|
|
|
- foreach ($items as $r) {
|
|
|
|
|
|
|
+ foreach ($items as $line) {
|
|
|
$i++;
|
|
$i++;
|
|
|
- $amt = $this->procuremenExportAmount($r);
|
|
|
|
|
|
|
+ $dr = $line['detail'];
|
|
|
|
|
+ $amt = $this->procuremenExportAmount($dr);
|
|
|
$subAmount += $amt;
|
|
$subAmount += $amt;
|
|
|
|
|
|
|
|
$sheet->setCellValue('A' . $rowNum, $i);
|
|
$sheet->setCellValue('A' . $rowNum, $i);
|
|
|
- $sheet->setCellValue('B' . $rowNum, (string)($r['CCYDH'] ?? ''));
|
|
|
|
|
- $sheet->setCellValue('C' . $rowNum, (string)($r['CYJMC'] ?? ''));
|
|
|
|
|
- $sheet->setCellValue('D' . $rowNum, (string)($r['company_name'] ?? ''));
|
|
|
|
|
- $sheet->setCellValue('E' . $rowNum, (string)($r['CDF'] ?? ''));
|
|
|
|
|
- $sheet->setCellValue('F' . $rowNum, (string)($r['cGzzxMc'] ?? ''));
|
|
|
|
|
- $sheet->setCellValue('G' . $rowNum, $this->procuremenExportGxText($r));
|
|
|
|
|
|
|
+ $sheet->setCellValue('B' . $rowNum, $line['CCYDH']);
|
|
|
|
|
+ $sheet->setCellValue('C' . $rowNum, $line['CYJMC']);
|
|
|
|
|
+ $sheet->setCellValue('D' . $rowNum, $line['company_name']);
|
|
|
|
|
+ $sheet->setCellValue('E' . $rowNum, $line['CDF']);
|
|
|
|
|
+ $sheet->setCellValue('F' . $rowNum, $line['cGzzxMc']);
|
|
|
|
|
+ $sheet->setCellValue('G' . $rowNum, $line['gx']);
|
|
|
$sheet->setCellValue('H' . $rowNum, $amt);
|
|
$sheet->setCellValue('H' . $rowNum, $amt);
|
|
|
$sheet->getStyle('H' . $rowNum)->getNumberFormat()->setFormatCode('"¥"#,##0.00');
|
|
$sheet->getStyle('H' . $rowNum)->getNumberFormat()->setFormatCode('"¥"#,##0.00');
|
|
|
$rowNum++;
|
|
$rowNum++;
|
|
@@ -2272,7 +2386,7 @@ class Procuremen extends Backend
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $sheet->setCellValue('A' . $rowNum, '总合');
|
|
|
|
|
|
|
+ $sheet->setCellValue('A' . $rowNum, '总计');
|
|
|
$sheet->setCellValue('B' . $rowNum, $sumSubtotalCounts);
|
|
$sheet->setCellValue('B' . $rowNum, $sumSubtotalCounts);
|
|
|
$sheet->mergeCells('G' . $rowNum . ':H' . $rowNum);
|
|
$sheet->mergeCells('G' . $rowNum . ':H' . $rowNum);
|
|
|
$sheet->setCellValue('G' . $rowNum, '¥ ' . number_format($grandAmount, 2, '.', ','));
|
|
$sheet->setCellValue('G' . $rowNum, '¥ ' . number_format($grandAmount, 2, '.', ','));
|
|
@@ -2289,7 +2403,6 @@ class Procuremen extends Backend
|
|
|
],
|
|
],
|
|
|
]);
|
|
]);
|
|
|
$sheet->getStyle('A3:H' . $lastRow)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
|
|
$sheet->getStyle('A3:H' . $lastRow)->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
|
|
|
- // 长文案列:加宽 + 自动换行,避免导出后被截断
|
|
|
|
|
if ($lastRow >= 3) {
|
|
if ($lastRow >= 3) {
|
|
|
$sheet->getStyle('C3:C' . $lastRow)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
|
|
$sheet->getStyle('C3:C' . $lastRow)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
|
|
|
$sheet->getStyle('D3:D' . $lastRow)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
|
|
$sheet->getStyle('D3:D' . $lastRow)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
|