Practical Tutorial: Writing Production Report Feedback from Kingdee Cloud Cosmos Back to MySQL with Qeasy
What This Strategy Solves
After a production report is pushed from the MES or middle platform into Kingdee Cloud Cosmos, what the shop floor really cares about is not "was the document sent" but "did Kingdee actually accept it—was it successful or not, and what was the error." This strategy closes that loop: it takes Kingdee's acceptance result (document inner ID, document number, success flag, and message text) and writes it back to the MySQL business table by sourceid, so the upstream system can decide whether to retry.
In one of our manufacturing customer engagements, we used the Qeasy data integration platform to carry this feedback link—polling every 3 minutes—and when something fails, the result_message field points directly at the cause.
Data Flow and Field Mapping
Data flow: Kingdee Cloud Cosmos (acting as the "source," which is actually the queried side) → Qeasy middleware layer → MySQL (acting as the "target," the business write-back table).
The source uses Kingdee's "request no-op" style query API (POST) to fetch the latest feedback by the report's sourceid. The target executes an update SQL that writes the result back to a write-back table such as wms_instock_confirm_main_task_detail.
Key field mapping:
| Source field (Kingdee response) | Middleware token | Target field (MySQL) | Notes |
|---|---|---|---|
sourceid | :sourceid | KingDee_id join key | business write-back locator |
生产订单号 | :Number | KingDee_no | Kingdee document number |
is_sucess | :is_success | is_success | success flag |
result_message | :message | KingDee_message | failure reason / hint |
| — | :time | syn_time | sync time, injected by the platform |
How to Configure It in Qeasy
The source strategy uses a "request no-op" with autoFillResponse=true, so the platform automatically fills request context from the source document's Number and Id, avoiding manual injection each run. We recommend turning on idCheck—empty runs become immediately visible in the log.
The target strategy is a SQL-execution style WebAPI. The main_sql lives in otherRequest as a template, while main_params is declared in the request array. The typical pattern is:
update wms_instock_confirm_main_task_detail
set KingDee_id=:Id,
KingDee_no=:Number,
syn_time=:time,
is_success=:is_success,
KingDee_message=:message
where id=:sourceid
Three things to watch in configuration:
- Placeholder names must match the source response fields one-to-one—don't take shortcuts and use
:valueeverywhere. - Centralize encoding mapping in Qeasy's field-mapping module rather than scattering it across strategies; later table changes touch one place.
- Write back the header (success flag) and the body (message, number) in separate phases, so failed documents can still drop the flag first and you don't have to wait for all fields during troubleshooting.
Implementation Steps
We recommend three phases for a safe rollout:
Phase 1: Initialize the incremental starting point. Run a one-time full update on the MySQL side and set all unwritten historical records' is_success to "processing," so the new scheduling cycle doesn't misclassify old documents as "pending write-back."
Phase 2: Trigger the first batch. Run the strategy manually, verify 5–10 sample records, and confirm KingDee_id, KingDee_no, and KingDee_message are correctly written before turning on auto scheduling.
Phase 3: Turn on scheduled frequency. In production, poll on */3 * * * * (every 3 minutes). This guarantees a 5-minute loop closure while not flooding the Kingdee query interface.
If Kingdee has a large backlog, you can temporarily switch to "incremental + full dual-track": incremental every 3 minutes, full sync hourly as a catch-up, then stop the full sync.
Pitfalls from the Field
- Inconsistent spelling for
is_sucess. Kingdee's source returnsis_sucess(as the source material shows), while the MySQL column isis_success. The middleware layer must rename the field, otherwise the update appears to "succeed silently"—SQL runs but no value is written. - Duplicate
sourceidwrite-back. If the write-back table contains multiple rows for the samesourceid(e.g., retries), the update overwrites and historical error info is lost. We suggest using conditions likewhere id=:sourceid and syn_time is null, or switching to an append-only log table. - False positives on empty runs. With
idCheck=trueandautoFillResponse=true, even when the source has no data, one row is returned andis_successis wrongly set to "success." A safe approach is to add an existence check in the target SQL, or filter out empty responses before writing. - Kingdee rate limiting. Polling every 3 minutes with hundreds of records per round easily triggers Kingdee Cloud Cosmos API rate limits. The common pattern on the customer side is to pull 50 records at a time with 3 retries, which aligns with Qeasy's pagination and rate-limiting parameters.
- Message text encoding glitches.
result_messagefrom Kingdee sometimes contains emoji or special characters. If the MySQL table isn'tutf8mb4, you'll see truncation or?placeholders.
When This Applies and When It Doesn't
Applies: Kingdee Cloud Cosmos is the receiver, and the business needs the processing result (success / failure / document number / message) written back to the upstream business database for document loop closure or retry decisions.
Doesn't apply: Scenarios requiring second-level real-time response (this pattern is minute-level; use message push instead), or cases where Kingdee has no corresponding query API and the result is only available through callbacks.