Files
SMT-ERP/smtERP-boot/scripts/sync_sas_assets.ps1
2026-10-13 16:15:00 +08:00

195 lines
10 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)"