param( [string]$BaseUrl = 'https://sms.smt.com.my/sas/api', [string]$DatabaseHost = '127.0.0.1', [int]$DatabasePort = 3306, [string]$DatabaseName = 'app072', [string]$DatabaseUser = 'root', [string]$MySqlPath = 'D:\Program Files\mysql\MySQL Server 8.0\bin\mysql.exe' ) $ErrorActionPreference = 'Stop' if ([string]::IsNullOrWhiteSpace($env:SAS_USERNAME) -or [string]::IsNullOrWhiteSpace($env:SAS_PASSWORD)) { throw 'Please set SAS_USERNAME and SAS_PASSWORD.' } if ([string]::IsNullOrWhiteSpace($env:MYSQL_PWD)) { throw 'Please set MYSQL_PWD.' } function ConvertTo-SqlValue($value) { if ($null -eq $value -or [string]::IsNullOrWhiteSpace([string]$value)) { return 'NULL' } return "'" + ([string]$value).Replace("'", "''") + "'" } function Limit-Text($value, [int]$length) { if ($null -eq $value) { return $null } $text = [string]$value if ($text.Length -le $length) { return $text } return $text.Substring(0, $length) } function ConvertTo-IsoDate($value) { if ($null -eq $value -or [string]::IsNullOrWhiteSpace([string]$value)) { return $null } return ([DateTime]::Parse([string]$value)).ToString('yyyy-MM-dd') } function Join-Present([object[]]$values, [string]$separator) { return (($values | Where-Object { $null -ne $_ -and -not [string]::IsNullOrWhiteSpace([string]$_) }) -join $separator) } $loginBody = @{ username = $env:SAS_USERNAME password = $env:SAS_PASSWORD } | ConvertTo-Json $login = Invoke-RestMethod -Uri "$BaseUrl/auth/login" -Method Post -ContentType 'application/json' -Body $loginBody if (-not $login.token) { throw 'SAS login did not return a token.' } $headers = @{ Authorization = "Bearer $($login.token)" } $hardware = (Invoke-RestMethod -Uri "$BaseUrl/hardware?limit=9999&page=1" -Headers $headers).data $software = (Invoke-RestMethod -Uri "$BaseUrl/software?limit=9999&page=1" -Headers $headers).data $simCards = (Invoke-RestMethod -Uri "$BaseUrl/sim?limit=9999&page=1" -Headers $headers).data $sql = New-Object System.Text.StringBuilder [void]$sql.AppendLine('SET NAMES utf8mb4; START TRANSACTION;') [void]$sql.AppendLine("SET @cat_hardware=(SELECT id FROM tbl_asset_category WHERE category_code='HARDWARE' LIMIT 1);") [void]$sql.AppendLine("SET @cat_software=(SELECT id FROM tbl_asset_category WHERE category_code='SOFTWARE' LIMIT 1);") [void]$sql.AppendLine("SET @cat_sim=(SELECT id FROM tbl_asset_category WHERE category_code='SIM_CARD' LIMIT 1);") [void]$sql.AppendLine("SET @creator=(SELECT id FROM tbl_user WHERE IFNULL(delete_flag,'0')!='1' ORDER BY id LIMIT 1);") foreach ($item in $hardware) { $code = if ([string]::IsNullOrWhiteSpace([string]$item.asset_code)) { "SAS-HW-$($item.id)" } else { [string]$item.asset_code } $name = Join-Present @($item.brand, $item.model) ' ' if ([string]::IsNullOrWhiteSpace($name)) { $name = Join-Present @($item.type, "硬件资产 $($item.id)") ' ' } $specification = Limit-Text (Join-Present @( $item.type, $item.brand, $item.model, $item.operating_system, $item.cpu, $item.memory_capacity, $item.storage_capacity ) ' / ') 150 $status = switch ([string]$item.status) { 'Dormant' { 'IDLE' } 'Spoil' { 'REPAIR' } 'Dispose' { 'SCRAPPED' } default { 'IN_USE' } } $remark = Limit-Text (Join-Present @( $(if ($item.serial_number) { "序列号: $($item.serial_number)" }), $(if ($item.mac_address) { "MAC: $($item.mac_address)" }), $(if ($item.purpose) { "用途: $($item.purpose)" }), $(if ($item.remarks) { "原备注: $($item.remarks)" }) ) ';') 500 $values = @( (ConvertTo-SqlValue (Limit-Text $code 64)), (ConvertTo-SqlValue (Limit-Text $name 150)), '@cat_hardware', (ConvertTo-SqlValue '硬件资产'), (ConvertTo-SqlValue $specification), (ConvertTo-SqlValue '台'), '1', '0', (ConvertTo-SqlValue (ConvertTo-IsoDate $item.date_of_purchase)), (ConvertTo-SqlValue (Limit-Text $item.department 100)), (ConvertTo-SqlValue (Limit-Text $item.person_in_charge 100)), (ConvertTo-SqlValue (Limit-Text $item.location 255)), (ConvertTo-SqlValue $status), (ConvertTo-SqlValue 'SAS'), (ConvertTo-SqlValue 'HARDWARE'), (ConvertTo-SqlValue ([string]$item.id)), (ConvertTo-SqlValue $remark), '@creator', "'0'", 'NOW()', 'NOW()' ) -join ',' $statement = "INSERT INTO tbl_asset " + "(asset_code,asset_name,category_id,asset_category,specification,unit,quantity,original_value,purchase_date,use_department,keeper,location,status,source,external_source,external_id,remark,creator,delete_flag,create_time,update_time) " + "VALUES($values) ON DUPLICATE KEY UPDATE " + "asset_code=VALUES(asset_code),asset_name=VALUES(asset_name),category_id=VALUES(category_id)," + "asset_category=VALUES(asset_category),specification=VALUES(specification),purchase_date=VALUES(purchase_date)," + "use_department=VALUES(use_department),keeper=VALUES(keeper),location=VALUES(location),status=VALUES(status)," + "remark=VALUES(remark),updater=@creator,delete_flag='0',update_time=NOW();" [void]$sql.AppendLine($statement) } foreach ($item in $software) { $code = "SAS-SW-$($item.id)" $name = if ([string]::IsNullOrWhiteSpace([string]$item.description)) { "软件资产 $($item.id)" } else { [string]$item.description } $specification = Limit-Text (Join-Present @($item.vendor, $item.cd_cert) ' / ') 150 $quantity = if ($null -eq $item.quantity -or [decimal]$item.quantity -le 0) { [decimal]1 } else { [decimal]$item.quantity } $originalValue = if ($null -eq $item.price) { [decimal]0 } else { [decimal]$item.price * $quantity } $quantityText = $quantity.ToString([System.Globalization.CultureInfo]::InvariantCulture) $valueText = $originalValue.ToString([System.Globalization.CultureInfo]::InvariantCulture) $remark = Limit-Text (Join-Present @( $(if ($item.vendor) { "供应商: $($item.vendor)" }), $(if ($item.license_key) { "许可证: $($item.license_key)" }), $(if ($item.invoice_no) { "发票号: $($item.invoice_no)" }), $(if ($item.remark) { "原备注: $($item.remark)" }) ) ';') 500 $values = @( (ConvertTo-SqlValue $code), (ConvertTo-SqlValue (Limit-Text $name 150)), '@cat_software', (ConvertTo-SqlValue '软件资产'), (ConvertTo-SqlValue $specification), (ConvertTo-SqlValue '套'), $quantityText, $valueText, (ConvertTo-SqlValue (ConvertTo-IsoDate $item.invoice_date)), (ConvertTo-SqlValue (Limit-Text $item.department 100)), 'NULL', 'NULL', (ConvertTo-SqlValue 'IN_USE'), (ConvertTo-SqlValue 'SAS'), (ConvertTo-SqlValue 'SOFTWARE'), (ConvertTo-SqlValue ([string]$item.id)), (ConvertTo-SqlValue $remark), '@creator', "'0'", 'NOW()', 'NOW()' ) -join ',' $statement = "INSERT INTO tbl_asset " + "(asset_code,asset_name,category_id,asset_category,specification,unit,quantity,original_value,purchase_date,use_department,keeper,location,status,source,external_source,external_id,remark,creator,delete_flag,create_time,update_time) " + "VALUES($values) ON DUPLICATE KEY UPDATE " + "asset_name=VALUES(asset_name),category_id=VALUES(category_id),asset_category=VALUES(asset_category)," + "specification=VALUES(specification),quantity=VALUES(quantity),original_value=VALUES(original_value)," + "purchase_date=VALUES(purchase_date),use_department=VALUES(use_department),status=VALUES(status)," + "remark=VALUES(remark),updater=@creator,delete_flag='0',update_time=NOW();" [void]$sql.AppendLine($statement) } foreach ($item in $simCards) { $code = if ([string]::IsNullOrWhiteSpace([string]$item.sim_number)) { "SAS-SIM-$($item.id)" } else { "SIM-$($item.sim_number)" } $name = if ([string]::IsNullOrWhiteSpace([string]$item.sim_number)) { "SIM卡 $($item.id)" } else { "SIM卡 $($item.sim_number)" } $specification = Limit-Text (Join-Present @($item.ip_address, $item.comm_device, $item.comm_device_serial) ' / ') 150 $status = if ([string]$item.status -eq 'Eliminated') { 'SCRAPPED' } else { 'IN_USE' } $remark = Limit-Text (Join-Present @( $(if ($item.comm_device_serial) { "设备序列号: $($item.comm_device_serial)" }), $(if ($item.meter_serial) { "电表序列号: $($item.meter_serial)" }), $(if ($item.duration) { "使用期限: $($item.duration)" }), $(if ($item.date_activation) { "启用日期: $(ConvertTo-IsoDate $item.date_activation)" }) ) ';') 500 $values = @( (ConvertTo-SqlValue (Limit-Text $code 64)), (ConvertTo-SqlValue (Limit-Text $name 150)), '@cat_sim', (ConvertTo-SqlValue 'SIM卡'), (ConvertTo-SqlValue $specification), (ConvertTo-SqlValue '张'), '1', '0', (ConvertTo-SqlValue (ConvertTo-IsoDate $item.date_activation)), 'NULL', (ConvertTo-SqlValue (Limit-Text $item.owner 100)), (ConvertTo-SqlValue (Limit-Text $item.location 255)), (ConvertTo-SqlValue $status), (ConvertTo-SqlValue 'SAS'), (ConvertTo-SqlValue 'SIM'), (ConvertTo-SqlValue ([string]$item.id)), (ConvertTo-SqlValue $remark), '@creator', "'0'", 'NOW()', 'NOW()' ) -join ',' $statement = "INSERT INTO tbl_asset " + "(asset_code,asset_name,category_id,asset_category,specification,unit,quantity,original_value,purchase_date,use_department,keeper,location,status,source,external_source,external_id,remark,creator,delete_flag,create_time,update_time) " + "VALUES($values) ON DUPLICATE KEY UPDATE " + "asset_code=VALUES(asset_code),asset_name=VALUES(asset_name),category_id=VALUES(category_id)," + "asset_category=VALUES(asset_category),specification=VALUES(specification),purchase_date=VALUES(purchase_date)," + "keeper=VALUES(keeper),location=VALUES(location),status=VALUES(status),remark=VALUES(remark)," + "updater=@creator,delete_flag='0',update_time=NOW();" [void]$sql.AppendLine($statement) } [void]$sql.AppendLine('COMMIT;') $OutputEncoding = New-Object System.Text.UTF8Encoding($false) $sql.ToString() | & $MySqlPath -h $DatabaseHost -P $DatabasePort -u $DatabaseUser -D $DatabaseName --default-character-set=utf8mb4 if ($LASTEXITCODE -ne 0) { throw "MySQL synchronization failed with exit code $LASTEXITCODE." } Write-Output "SYNCED hardware=$($hardware.Count) software=$($software.Count) sim=$($simCards.Count)"