This commit is contained in:
lychang
2026-05-20 03:25:35 +08:00
parent 5e3dac3020
commit 7f5350db62
30 changed files with 3370 additions and 1752 deletions

334
cmd/wasm/main.go Normal file
View File

@@ -0,0 +1,334 @@
package main
import (
"encoding/json"
"fmt"
"syscall/js"
"wasm-go/internal/api"
"wasm-go/internal/excel"
)
func main() {
// 注册各种功能函数
js.Global().Set("analyzeCompanyIndustryAsync", js.FuncOf(analyzeCompanyIndustryAsync))
js.Global().Set("parseExcelAsync", js.FuncOf(parseExcelAsync))
js.Global().Set("callLLMAsync", js.FuncOf(callLLMAsync))
js.Global().Set("callTaxHealthAsync", js.FuncOf(callTaxHealthAsync))
// 保持程序运行
select {} // 无限循环,保持程序运行
}
// analyzeCompanyIndustryAsync 异步版本的函数,返回Promise
func analyzeCompanyIndustryAsync(this js.Value, args []js.Value) interface{} {
// 获取公司名称参数
companyName := args[0].String()
// 创建一个通道来处理结果
resultChan := make(chan interface{}, 1)
errorChan := make(chan error, 1) // 使用error类型而不是interface{}
// 在goroutine中执行异步操作
go func() {
// 创建LLM客户端
llmClient := api.NewOllamaClient("http://localhost:11434", "qwen3.5:9b")
// 创建企业行业分类器
classifier := api.NewCompanyIndustryClassifier(llmClient)
// 分析企业行业
result, err := classifier.ClassifyCompany(companyName)
if err != nil {
// 发送错误到错误通道
errorChan <- err
} else {
// 发送结果到结果通道
resultChan <- result
}
}()
// 创建Promise
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
if len(promiseArgs) < 2 {
// 如果参数不足,返回一个立即拒绝的Promise
return nil
}
resolve := promiseArgs[0]
reject := promiseArgs[1]
// 启动一个goroutine来处理结果
go func() {
select {
case result := <-resultChan:
// 将复杂结构体序列化为JSON
jsonResult, err := json.Marshal(result)
if err != nil {
// 序列化失败,返回错误
reject.Invoke(js.ValueOf(map[string]string{
"error": "JSON序列化失败: " + err.Error(),
}))
return
}
// 将JSON字符串解析为JavaScript对象
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
resolve.Invoke(jsResult)
case err := <-errorChan:
// 将错误转换为JavaScript值
reject.Invoke(js.ValueOf(map[string]string{
"error": err.Error(),
}))
}
}()
return nil
}))
return promise
}
// parseExcelAsync 解析Excel文件的异步函数
func parseExcelAsync(this js.Value, args []js.Value) interface{} {
// 获取Excel文件的ArrayBuffer
arrayBuffer := args[0]
uint8Array := js.Global().Get("Uint8Array").New(arrayBuffer)
// 创建字节切片
length := uint8Array.Get("length").Int()
excelBytes := make([]byte, length)
// 将数据复制到Go字节切片
for i := 0; i < length; i++ {
excelBytes[i] = byte(uint8Array.Index(i).Int())
}
// 创建一个通道来处理结果
resultChan := make(chan interface{}, 1)
errorChan := make(chan error, 1)
// 在goroutine中执行异步操作
go func() {
// 创建Excel读取器
reader, err := excel.NewXLSXReaderFromBytes(excelBytes)
if err != nil {
errorChan <- err
return
}
// 读取所有工作表
sheetNames, err := reader.GetSheetNames()
if err != nil {
errorChan <- err
return
}
// 创建一个map来存储所有工作表的数据
sheets := make(map[string][][]string)
// 读取每个工作表的数据
for _, sheetName := range sheetNames {
sheetData, err := reader.GetSheetData(sheetName)
if err != nil {
// 记录错误但继续处理其他工作表
continue
}
sheets[sheetName] = sheetData
}
// 将结果转换为适当的格式
result := map[string]interface{}{
"sheets": sheets,
}
resultChan <- result
}()
// 创建Promise
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
if len(promiseArgs) < 2 {
// 如果参数不足,返回一个立即拒绝的Promise
return nil
}
resolve := promiseArgs[0]
reject := promiseArgs[1]
// 启动一个goroutine来处理结果
go func() {
select {
case result := <-resultChan:
// 将复杂结构体序列化为JSON
jsonResult, err := json.Marshal(result)
if err != nil {
// 序列化失败,返回错误
reject.Invoke(js.ValueOf(map[string]string{
"error": "JSON序列化失败: " + err.Error(),
}))
return
}
// 将JSON字符串解析为JavaScript对象
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
resolve.Invoke(jsResult)
case err := <-errorChan:
// 将错误转换为JavaScript值
reject.Invoke(js.ValueOf(map[string]string{
"error": err.Error(),
}))
}
}()
return nil
}))
return promise
}
// callLLMAsync 调用大模型的异步函数
func callLLMAsync(this js.Value, args []js.Value) interface{} {
// 获取提示词参数
prompt := args[0].String()
// 创建一个通道来处理结果
resultChan := make(chan interface{}, 1)
errorChan := make(chan error, 1)
// 在goroutine中执行异步操作
go func() {
// 创建LLM客户端(可以根据需要选择不同的模型)
llmClient := api.NewOllamaClient("http://localhost:11434", "qwen3.5:9b")
// 调用大模型
response, err := llmClient.SimpleChat(prompt)
if err != nil {
errorChan <- err
return
}
result := map[string]string{
"response": response,
}
resultChan <- result
}()
// 创建Promise
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
if len(promiseArgs) < 2 {
// 如果参数不足,返回一个立即拒绝的Promise
return nil
}
resolve := promiseArgs[0]
reject := promiseArgs[1]
// 启动一个goroutine来处理结果
go func() {
select {
case result := <-resultChan:
// 将复杂结构体序列化为JSON
jsonResult, err := json.Marshal(result)
if err != nil {
// 序列化失败,返回错误
reject.Invoke(js.ValueOf(map[string]string{
"error": "JSON序列化失败: " + err.Error(),
}))
return
}
// 将JSON字符串解析为JavaScript对象
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
resolve.Invoke(jsResult)
case err := <-errorChan:
// 将错误转换为JavaScript值
reject.Invoke(js.ValueOf(map[string]string{
"error": err.Error(),
}))
}
}()
return nil
}))
return promise
}
// callTaxHealthAsync 调用税务健康API的异步函数
// 注意:由于WASM环境的CORS限制,我们在这里提供模拟实现
func callTaxHealthAsync(this js.Value, args []js.Value) interface{} {
// 获取公司信息参数
companyInfoJSON := args[0].String()
// 创建一个通道来处理结果
resultChan := make(chan interface{}, 1)
errorChan := make(chan error, 1)
// 在goroutine中执行异步操作
go func() {
// 由于WASM环境无法直接调用外部API(CORS限制)
// 我们返回一个模拟的响应
simulatedResponse := map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"req_no": "REQ" + fmt.Sprint(js.Global().Get("Date").New().Call("getTime").Int()),
"order_no": "ORDER" + fmt.Sprint(js.Global().Get("Date").New().Call("getTime").Int()),
},
"message": "模拟的税务健康评估结果",
}
// 解析输入的JSON以获取一些信息用于模拟
var companyInfo map[string]interface{}
err := json.Unmarshal([]byte(companyInfoJSON), &companyInfo)
if err != nil {
errorChan <- err
return
}
// 根据输入数据添加一些模拟的评估结果
simulatedResponse["company_data"] = companyInfo
resultChan <- simulatedResponse
}()
// 创建Promise
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
if len(promiseArgs) < 2 {
// 如果参数不足,返回一个立即拒绝的Promise
return nil
}
resolve := promiseArgs[0]
reject := promiseArgs[1]
// 启动一个goroutine来处理结果
go func() {
select {
case result := <-resultChan:
// 将复杂结构体序列化为JSON
jsonResult, err := json.Marshal(result)
if err != nil {
// 序列化失败,返回错误
reject.Invoke(js.ValueOf(map[string]string{
"error": "JSON序列化失败: " + err.Error(),
}))
return
}
// 将JSON字符串解析为JavaScript对象
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
resolve.Invoke(jsResult)
case err := <-errorChan:
// 将错误转换为JavaScript值
reject.Invoke(js.ValueOf(map[string]string{
"error": err.Error(),
}))
}
}()
return nil
}))
return promise
}