migrate_device_operation_sources.php 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <?php
  2. /**
  3. * php scripts/migrate_device_operation_sources.php --apply --legacy-schema=api
  4. * 不带 --apply 只检查。旧库可选,只回填唯一 SN、类型和 legacy_id 一致的设备成本。
  5. * 运行时的报表不依赖旧库;代理、商户比例始终读取新系统已有档案。
  6. */
  7. require dirname(__DIR__) . '/vendor/autoload.php';
  8. \Dotenv\Dotenv::createUnsafeMutable(dirname(__DIR__))->load();
  9. \support\App::loadAllConfig(['route']);
  10. \Webman\ThinkOrm\ThinkOrm::start(null);
  11. use support\think\Db;
  12. $options = getopt('', ['apply', 'legacy-schema:']);
  13. $apply = array_key_exists('apply', $options);
  14. $schema = $options['legacy-schema'] ?? '';
  15. if ($schema !== '' && !preg_match('/^[a-zA-Z0-9_]+$/D', $schema)) {
  16. throw new InvalidArgumentException('Invalid legacy schema name');
  17. }
  18. $migrations = [
  19. '20260908_use_device_operation_sources.sql',
  20. '20260908_add_device_product_dictionary.sql',
  21. ];
  22. foreach ($migrations as $migration) {
  23. if ($apply) {
  24. $sql = file_get_contents(dirname(__DIR__) . '/plugin/saiadmin/db/' . $migration);
  25. foreach (explode(';', $sql) as $statement) {
  26. if (trim($statement) !== '') {
  27. Db::execute($statement);
  28. }
  29. }
  30. }
  31. echo ($apply ? 'Applied: ' : 'Planned: ') . $migration . "\n";
  32. }
  33. if ($schema !== '') {
  34. // 不用机器码、名称或顺序猜对应关系;有重复 SN 时不导入。
  35. $legacy = "(SELECT goods_sn,goods_type,MIN(id) AS id,MIN(cost_price) AS cost_price
  36. FROM `$schema`.xs_market_goods WHERE is_delete=0
  37. GROUP BY goods_sn,goods_type HAVING COUNT(*)=1 AND MIN(cost_price)>=0) legacy";
  38. $join = "FROM sa_device d JOIN $legacy
  39. ON legacy.goods_sn=d.goods_sn AND legacy.goods_type=d.goods_type
  40. WHERE d.delete_time IS NULL AND (d.legacy_id IS NULL OR d.legacy_id=legacy.id)";
  41. $hasCost = Db::query("SELECT COUNT(*) AS n FROM information_schema.columns
  42. WHERE table_schema=DATABASE() AND table_name='sa_device' AND column_name='cost_price'")[0]['n'];
  43. $missingCost = $hasCost ? ' AND d.cost_price IS NULL' : '';
  44. $matches = (int) Db::query("SELECT COUNT(*) AS n $join $missingCost")[0]['n'];
  45. echo "Matching devices without cost: $matches\n";
  46. if ($apply && $matches > 0) {
  47. $updated = Db::execute("UPDATE sa_device d JOIN $legacy
  48. ON legacy.goods_sn=d.goods_sn AND legacy.goods_type=d.goods_type
  49. SET d.cost_price=legacy.cost_price
  50. WHERE d.delete_time IS NULL AND d.cost_price IS NULL
  51. AND (d.legacy_id IS NULL OR d.legacy_id=legacy.id)");
  52. echo "Imported device costs: $updated\n";
  53. }
  54. }
  55. if ($apply) {
  56. \plugin\saiadmin\app\cache\DictCache::clear();
  57. \plugin\saiadmin\app\cache\UserAuthCache::clear();
  58. \plugin\saiadmin\app\cache\UserMenuCache::clearMenuCache();
  59. }