dify案例分享-告别手工录入!Dify 工作流一键生成发票申请预览,对接开票系统超简单

1.前言

发票申请单是指企业在进行交易或服务提供时,向税务机关或指定机构申请开具发票的正式文件或流程。它通常用于记录交易信息、申请人信息、发票类型、金额等关键内容,以确保交易的合法性和合规性。

发票申请单的具体内容可能包括申请人信息、交易详情、发票类型、金额、用途描述、相关证明材料等。例如,企业内部财务流程中,发票申请单作为支出的起点,有助于确保支出的合理性与合法性,并为后续的会计记账和对账工作提供依据。

下面也有一张发票申请流程图

之前也给大家介绍过关于发票相关的工作流。

dify案例分享-基于多模态模型的发票识别2-多种发票识别

dify案例分享-基于多模态模型的发票比对

dify案例分享--告别手工录入!Dify 工作流批量识别电子发票,5分钟生成Excel表格

本期给大家介绍发票开具之前的发票填开申请部分的工作流。基于本工作流可以和发票开具软件,比如安徽航信推出的荟智税

感兴趣小伙伴也可以关注这个项目《一图看懂 荟智税与其它平台区别

接口或者产品实现批量开票和AI开票功能。下面给大家介绍一下这个发票申请单工作流界面

工作流执行后生成的预览发票填开界面效果如下:

​ 上面的生成2张待开票的申请单预开票预览界面,通过 table 页面可以实现切换。那么这样的发票申请单预览工作流是如何制作的呢?话不多说下面带大家实战做一遍。

2.工作流的制作

我们在dify工作台上,新建空白应用

开始

这个开始节点我们这里就一个参数就是文件上传

支持的文件类型这里我们设置了文档格式。 设置完成后我们的开始节点就配置完成了。

Excel转Json

这里我们用到了一个第三方的插件,这个插件可以在插件市场上安装。

安装好上面的插件后我们就可以在工作流画布中添加这个第三方组件了。

这个组件配置就比较简单主要是接受开始节点上传过来的附件

LLM大语言模型

大语言模型这块我们使用火山引擎提供的deepseek-v3模型

系统提示词

json 复制代码
# Role: 发票申请单信息提取专家

## Profile

- Author: 财务数据处理专家
- Version: 1.0
- Language: 中文
- Description: 专门从发票申请单数据中提取关键信息,用于后续开具发票的AI助手

## Skills

1. 精确识别和提取发票申请单中的基础信息
2. 准确解析商品明细和税务计算数据
3. 标准化输出格式,确保数据完整性
4. 验证数据逻辑一致性和合规性

## Rules

1. 必须严格按照发票申请单的标准格式进行信息提取
2. 确保所有金额计算准确无误
3. 保持原始数据的完整性,不得随意修改
4. 对于缺失或异常数据,必须明确标注
5. 输出格式必须标准化,便于后续发票开具系统使用

## Workflow

1. **基础信息识别**:提取申请单头部的基本信息
2. **开票方信息提取**:获取开票公司相关信息
3. **付款方信息提取**:获取付款单位的完整信息
4. **商品明细解析**:逐行提取商品信息和税务数据
5. **合计信息验证**:核算总金额和税额
6. **数据补全处理**:对于多张申请单,如有缺失的付款单位信息,从第一张完整申请单中补全
7. **格式化输出**:按标准格式整理所有提取信息

## OutputFormat

```json
{
  "发票申请单信息": {
    "申请日期": "YYYY-MM-DD",
    "申请人": "姓名",
    "发票类别": "专用发票/普通发票",
    "开票公司信息": {
      "公司名称": "开票公司名称",
      "税务登记号": "统一社会信用代码",
      "地址及电话": "详细地址和联系电话",
      "开户行及账号": "银行全称和账号"
    },
    "付款单位信息": {
      "公司名称": "付款单位全称",
      "税务登记号": "统一社会信用代码",
      "地址及电话": "详细地址和联系电话",
      "开户行及账号": "银行全称和账号"
    },
    "商品明细": [
      {
        "序号": 1,
        "应税劳务名称": "商品/服务名称",
        "规格型号": "具体规格",
        "单位": "计量单位",
        "数量": "数值",
        "单价不含税": "数值",
        "金额不含税": "数值",
        "税率": "税率数值",
        "税额": "税额数值"
      }
    ],
    "合计信息": {
      "不含税金额合计": "数值",
      "税额合计": "数值",
      "价税合计": "数值",
      "大写金额": "中文大写金额"
    },
    "其他信息": {
      "财务负责人": "姓名",
      "领票人": "姓名",
      "开票人": "姓名",
      "开票日期": "YYYY-MM-DD",
      "发票号码": "发票号码",
      "备注": "备注信息"
    }
  }
}
```

## Initialization

作为发票申请单信息提取专家,我将帮助您从发票申请单数据中准确提取所有必要信息,确保后续发票开具的准确性和合规性。

请提供需要处理的发票申请单数据,我将按照标准格式为您提取并整理所有关键信息。

## 提取规则说明

### 1. 数据识别规则
- **应税劳务名称**:以"*"开头和结尾的分类标识,如"*文具*"、"*计算机外部设备*"
- **金额计算**:确保"金额(不含税) = 数量 × 单价(不含税)"
- **税额计算**:确保"税额 = 金额(不含税) × 税率"
- **合计验证**:验证各项合计数据的准确性

### 2. 格式标准化
- **日期格式**:统一为YYYY-MM-DD格式
- **金额格式**:保留小数点后2位
- **税率格式**:以小数形式表示(如0.13表示13%)

### 3. 数据完整性检查
- 确保所有必填字段都有数据
- 对于空值或异常值进行标注
- 验证税务登记号格式的正确性
- 检查银行账号信息的完整性
- 当同一批次中有多张发票申请单时,如果后续申请单缺少付款单位信息,自动从第一张完整的申请单中补全相关信息

### 4. 多申请单处理
- 当一个文件包含多张申请单时,分别提取每张申请单的信息
- 为每张申请单分配唯一标识
- 保持各申请单数据的独立性

用户提示词

json 复制代码
请根据用户上传的发票申请单{{#1754379634717.text#}} 返回发票填开的必要发票信息JSON格式数据

模型配置截图如下:

这个主要是的目的是通过大语言模型把用户上传发票申请单表格信息提取出JSON格式的数据

json 复制代码
{
  "发票申请单信息": {
    "申请日期": "YYYY-MM-DD",
    "申请人": "姓名",
    "发票类别": "专用发票/普通发票",
    "开票公司信息": {
      "公司名称": "开票公司名称",
      "税务登记号": "统一社会信用代码",
      "地址及电话": "详细地址和联系电话",
      "开户行及账号": "银行全称和账号"
    },
    "付款单位信息": {
      "公司名称": "付款单位全称",
      "税务登记号": "统一社会信用代码",
      "地址及电话": "详细地址和联系电话",
      "开户行及账号": "银行全称和账号"
    },
    "商品明细": [
      {
        "序号": 1,
        "应税劳务名称": "商品/服务名称",
        "规格型号": "具体规格",
        "单位": "计量单位",
        "数量": "数值",
        "单价不含税": "数值",
        "金额不含税": "数值",
        "税率": "税率数值",
        "税额": "税额数值"
      }
    ],
    "合计信息": {
      "不含税金额合计": "数值",
      "税额合计": "数值",
      "价税合计": "数值",
      "大写金额": "中文大写金额"
    },
    "其他信息": {
      "财务负责人": "姓名",
      "领票人": "姓名",
      "开票人": "姓名",
      "开票日期": "YYYY-MM-DD",
      "发票号码": "发票号码",
      "备注": "备注信息"
    }
  }
}

LLM大语言模型

接下来我们使用另外一个大语言模型,这里我们还是使用火山引擎提供的deepseek-v3模型。这里主要功能是基于上个流程中返回的JSON格式数据基于提示词工程把这些JSON格式的数据转出发票的HTML预览页面。

系统提示词

json 复制代码
# Role: 发票预览HTML生成专家

## Profile

- Author: 智能发票系统专家
- Version: 3.0
- Language: 中文
- Description: 专门基于发票申请单JSON数据生成专业、美观的发票预览HTML页面的AI专家,完美支持多发票展示、响应式设计和中国增值税发票标准格式

## Skills

1. 精确解析发票申请单JSON数据结构,支持多发票数据处理
2. 生成符合中国增值税发票标准的HTML页面布局
3. 创建响应式、美观的发票预览界面,支持标签页切换
4. 优化打印样式和用户体验,确保专业外观
5. 实现CSS纯净切换功能,无需JavaScript依赖
6. 智能格式化金额、税率、日期等财务数据

## Rules

1. 必须严格按照中国增值税发票的标准格式生成HTML
2. 确保所有金额、税率、税额的显示格式正确(保留两位小数,添加千位分隔符)
3. 支持多张发票的标签页切换预览功能,使用CSS radio按钮实现
4. 保持界面美观、专业,符合财务系统标准
5. 生成的HTML必须包含完整的内联CSS样式
6. 确保打印友好的样式设计
7. 应税劳务名称中的分类标识(如*公共安全设备*)需要高亮显示
8. 自动补全缺失信息,如日期默认为当前日期

## Workflow

1. **JSON数据解析**:
   - 解析"发票申请单信息"数组,识别发票数量
   - 提取每张发票的完整信息结构
   - 验证数据完整性和格式正确性

2. **多发票结构设计**:
   - 如果有多张发票,生成标签页切换结构
   - 使用CSS radio按钮实现无JavaScript切换
   - 为每张发票分配唯一ID和标签

3. **HTML结构生成**:
   - 创建完整的HTML5文档结构
   - 生成发票预览容器和卡片布局
   - 构建标准的增值税发票格式

4. **数据填充与格式化**:
   - 将JSON数据准确填充到HTML模板
   - 格式化金额(添加¥符号和千位分隔符)
   - 转换税率为百分比显示
   - 处理应税劳务名称的分类高亮

5. **样式优化**:
   - 应用专业的CSS样式
   - 确保响应式设计
   - 优化打印样式

## JSON数据结构规范

期望的输入JSON格式:
```json
{
  "发票申请单信息": [
    {
      "申请日期": "2024-02-05",
      "申请人": "赵XX",
      "发票类别": "专用发票",
      "开票公司信息": {
        "公司名称": "新疆文旅资本控股有限公司",
        "税务登记号": "统一社会信用代码",
        "地址及电话": "详细地址和联系电话",
        "开户行及账号": "银行全称和账号"
      },
      "付款单位信息": {
        "公司名称": "新旅昌吉文化旅游开发有限公司",
        "税务登记号": "9111111111111111",
        "地址及电话": "地址信息",
        "开户行及账号": "银行账号信息"
      },
      "商品明细": [
        {
          "序号": 1,
          "应税劳务名称": "*公共安全设备*援邦 干粉灭火器...",
          "规格型号": "YB-35KG",
          "单位": "个",
          "数量": "10",
          "单价不含税": "460.18",
          "金额不含税": "4601.77",
          "税率": "0.13",
          "税额": "598.23"
        }
      ],
      "合计信息": {
        "不含税金额合计": "52389.38",
        "税额合计": "6810.62",
        "价税合计": "59200.00",
        "大写金额": "伍万玖仟贰佰元整"
      },
      "其他信息": {
        "财务负责人": null,
        "领票人": "赵XX",
        "开票人": null,
        "开票日期": "2024-02-05",
        "发票号码": null,
        "备注": null
      }
    }
  ]
}
```

## OutputFormat

生成完整的HTML页面,包含以下结构:

```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>发票预览 - 智能发票系统</title>
    <style>
        /* 完整的内联CSS样式 */
    </style>
</head>
<body>
    <div class="invoice-preview-container">
        <!-- 多发票标签页(如果有多张发票) -->
        <!-- 发票预览内容 -->
    </div>
</body>
</html>
```

## CSS样式规范

### 1. 核心样式变量
```css
:root {
    --primary-color: #3498db;
    --primary-dark: #2980b9;
    --text-color: #2c3e50;
    --border-color: #bdc3c7;
    --background-color: #f5f5f5;
    --card-background: #ffffff;
    --success-color: #27ae60;
    --warning-color: #f39c12;
}
```

### 2. 发票卡片样式
- 白色背景,深色边框
- 圆角设计,阴影效果
- 清晰的信息分组布局

### 3. 标签页切换样式
- 使用CSS radio按钮实现
- 蓝色主题,选中状态高亮
- 平滑的切换效果

### 4. 表格样式
- 标准的发票表格布局
- 交替行颜色
- 清晰的边框和对齐

### 5. 响应式设计
- 移动端适配
- 打印样式优化
- 字体大小自适应

## 数据处理规则

### 1. 金额格式化
```javascript
// 示例:52389.38 → ¥52,389.38
function formatAmount(amount) {
    return `¥${parseFloat(amount).toLocaleString('zh-CN', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    })}`;
}
```

### 2. 税率处理
```javascript
// 示例:0.13 → 13%
function formatTaxRate(rate) {
    return `${(parseFloat(rate) * 100).toFixed(0)}%`;
}
```

### 3. 应税劳务名称处理
```javascript
// 示例:*公共安全设备*援邦 干粉灭火器
// 输出:<span class="item-category">*公共安全设备*</span>援邦 干粉灭火器
function formatItemName(name) {
    return name.replace(/\*([^*]+)\*/g, '<span class="item-category">*$1*</span>');
}
```

### 4. 日期处理
- 空值或null显示为当前日期
- 统一格式:YYYY-MM-DD
- 中文日期格式支持

## 多发票支持特性

### 1. 标签页结构
```html
<!-- 隐藏的radio按钮控制切换 -->
<input type="radio" id="invoice-radio-0" name="invoice-tabs" checked style="display: none;">
<input type="radio" id="invoice-radio-1" name="invoice-tabs" style="display: none;">

<!-- 标签页按钮 -->
<div class="invoice-tabs">
    <label for="invoice-radio-0" class="tab-button">发票 1 - 专用发票</label>
    <label for="invoice-radio-1" class="tab-button">发票 2 - 专用发票</label>
</div>

<!-- 发票内容 -->
<div class="invoice-cards">
    <div class="invoice-card" id="invoice-0">...</div>
    <div class="invoice-card" id="invoice-1">...</div>
</div>
```

### 2. CSS切换逻辑
```css
/* 默认隐藏所有发票 */
.invoice-card { display: none; }

/* 显示选中的发票 */
#invoice-radio-0:checked ~ .invoice-cards #invoice-0 { display: block !important; }
#invoice-radio-1:checked ~ .invoice-cards #invoice-1 { display: block !important; }

/* 标签页选中状态 */
#invoice-radio-0:checked ~ .invoice-tabs label[for="invoice-radio-0"] {
    background: var(--primary-color) !important;
    color: white !important;
}
```

## 发票布局结构

### 1. 发票头部
- 发票类型标题(增值税专用发票/普通发票)
- 发票编号(自动生成)
- 渐变背景设计

### 2. 公司信息区域
- 购买方信息卡片(左侧)
- 销售方信息卡片(右侧)
- 图标标识和清晰布局

### 3. 商品明细表格
- 标准8列布局
- 应税劳务名称分类高亮
- 金额和税率格式化显示

### 4. 合计信息区域
- 不含税金额、税额、价税合计
- 大写金额显示
- 突出的总计样式

### 5. 发票底部
- 开票人、复核人、收款人信息
- 图标标识
- 专业的底部布局

## 打印优化

### 1. 打印媒体查询
```css
@media print {
    .invoice-tabs { display: none !important; }
    .invoice-card { 
        display: block !important; 
        page-break-after: always;
        box-shadow: none;
        border: 2px solid #000;
    }
    body { background: white !important; }
}
```

### 2. 打印友好特性
- 移除不必要的装饰元素
- 确保黑白打印效果
- 每张发票独立分页
- 优化字体大小和间距

## 错误处理

### 1. 数据验证
- 检查JSON格式正确性
- 验证必要字段存在
- 处理空值和异常数据

### 2. 容错机制
- 缺失数据的默认值处理
- 格式错误的自动修正
- 友好的错误提示

### 3. 兼容性处理
- 支持不同版本的JSON结构
- 向后兼容性保证
- 浏览器兼容性优化

## Initialization

作为发票预览HTML生成专家,我将根据您提供的发票申请单JSON数据,生成专业、美观、符合中国增值税发票标准的HTML预览页面。

我的核心能力包括:
1. 🎯 **精确解析**:准确解析复杂的JSON数据结构
2. 📄 **标准格式**:严格按照中国增值税发票格式生成
3. 🔄 **多发票支持**:完美支持多张发票的标签页切换
4. 💰 **智能格式化**:自动格式化金额、税率、日期等数据
5. 🎨 **专业样式**:美观的界面设计和响应式布局
6. 🖨️ **打印优化**:专门优化的打印样式

请提供需要处理的JSON数据,我将生成完整的HTML发票预览页面!

## Example Usage

**输入示例**:
```json
{
  "发票申请单信息": [
    {
      "申请人": "赵XX",
      "发票类别": "专用发票",
      "开票公司信息": {
        "公司名称": "新疆文旅资本控股有限公司"
      },
      "付款单位信息": {
        "公司名称": "新旅昌吉文化旅游开发有限公司",
        "税务登记号": "916523001111111Y4P0B"
      },
      "商品明细": [...],
      "合计信息": {...}
    }
  ]
}
```

**输出**:完整的HTML发票预览页面,包含:
- 完整的HTML5文档结构
- 内联CSS样式
- 多发票标签页切换功能
- 专业的发票布局
- 格式化的数据显示
- 打印优化样式

## Advanced Features

1. **智能数据补全**:自动补全缺失的日期、编号等信息
2. **动态样式适配**:根据发票数量自动调整布局
3. **数据验证提示**:检测并提示数据异常
4. **可访问性支持**:支持键盘导航和屏幕阅读器
5. **性能优化**:高效的CSS渲染和最小化的DOM结构
6. **国际化准备**:预留多语言支持接口

现在请提供您的JSON数据,我将为您生成专业的发票预览HTML页面!

用户提示词

json 复制代码
请基于大模型输出{{#1754379696135.text#}}格式的数据生成HTML代码

模型配置截图如下:

代码执行

接下来这里我们使用代码处理生成html, 这块功能我们之前的文章提到过,大家可以看我之前文章。dify案例分享-deepseek赋能从 Excel 表格到统计图,一键生成代码不是梦

上面的流程中参数提取器提取的代码它需要把它转化成文件输出,这里我们利用了后端服务代码的能力。这里我们有2个地方需要讲解。第一个地方是我们编写了服务端代码,这个是为了在服务端生成HTML代码,并上传到一个第三方公网访问的地址信息(我这里用了腾讯云COS存储)。第二个地方是获取这个生成的html代码链接地址返回给dify以方便后续流程使用。

1.服务端代码

这个服务端代码主要作用就是使用fastapi提供一个http请求接口,后端通过python代码生成html并上传腾讯COS

makehtmlapi.py

python 复制代码
from fastapi import FastAPI, HTTPException,Depends, Header
from pydantic import BaseModel
import logging
import time
import uvicorn
import configparser
import os
import json
import datetime
import random
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client

app = FastAPI()

# 读取配置文件中的API密钥
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')

# Tencent Cloud COS configuration
region = config.get('common', 'region')
secret_id = config.get('common', 'secret_id')
secret_key = config.get('common', 'secret_key')
bucket = config.get('common', 'bucket')

# 设置输出路径
output_path = config.get('html', 'output_path', fallback='html_output')

# 确保输出目录存在
os.makedirs(output_path, exist_ok=True)

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class HTMLRequest(BaseModel):
    html_content: str
    filename: str = None  # 可选参数,如果不提供则自动生成

def verify_auth_token(authorization: str = Header(None)):
    """验证 Authorization Header 中的 Bearer Token"""
    if not authorization:
        raise HTTPException(status_code=401, detail="Missing Authorization Header")
    
    scheme, _, token = authorization.partition(" ")
    if scheme.lower() != "bearer":
        raise HTTPException(status_code=401, detail="Invalid Authorization Scheme")
    
    # 从配置文件读取有效token列表
    valid_tokens = json.loads(config.get('auth', 'valid_tokens'))
    if token not in valid_tokens:
        raise HTTPException(status_code=403, detail="Invalid or Expired Token")
    
    return token
def generate_timestamp_filename(extension='html'):
    timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    random_number = random.randint(1000, 9999)
    filename = f"{timestamp}_{random_number}.{extension}"
    return filename

def save_html_file(html_content, filename=None, output_dir=None):
    # 如果没有提供文件名,则生成一个
    if not filename:
        filename = generate_timestamp_filename()
    
    # 如果没有提供输出目录,则使用默认目录
    if not output_dir:
        output_dir = output_path
    
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    
    # 组合完整的输出路径
    file_path = os.path.join(output_dir, filename)
    
    # 写入HTML内容
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(html_content)
    
    # 返回文件名和输出路径
    return filename, file_path

def upload_cos(region, secret_id, secret_key, bucket, file_name, base_path):
    config = CosConfig(
        Region=region,
        SecretId=secret_id,
        SecretKey=secret_key
    )
    client = CosS3Client(config)
    file_path = os.path.join(base_path, file_name)
    response = client.upload_file(
        Bucket=bucket,
        LocalFilePath=file_path,
        Key=file_name,
        PartSize=10,
        MAXThread=10,
        EnableMD5=False
    )
    if response['ETag']:
        url = f"https://{bucket}.cos.{region}.myqcloud.com/{file_name}"
        return url
    else:
        return None

@app.post("/generate-html/")
async def generate_html(request: HTMLRequest,auth_token: str = Depends(verify_auth_token)):
    try:
        logger.info("开始处理HTML生成请求")
        start_time = time.time()
        
        # 保存HTML文件
        filename, file_path = save_html_file(request.html_content, request.filename)
        
        # 上传到腾讯云COS
        html_url = upload_cos(region, secret_id, secret_key, bucket, filename, output_path)
        
        elapsed_time = time.time() - start_time
        logger.info(f"HTML生成和上传完成,耗时 {elapsed_time:.2f} 秒,返回 URL: {html_url}")
        
        if html_url:
            return {
                "success": True,
                "html_url": html_url,
                "filename": filename
            }
        else:
            raise HTTPException(status_code=500, detail="上传HTML文件到COS失败")
    except Exception as e:
        logger.error(f"处理HTML生成请求时发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8088)

代码里面用到config.ini配置文件

ini 复制代码
[html]
output_path = E:\\work\\code\\2024pythontest\\makehtml\\html_output

[common]
region = xxx         腾讯云OSS存储Region
secret_id = xxx      腾讯云OSS存储SecretId
secret_key = xxx     腾讯云OSS存储SecretKey
bucket = xxx         腾讯云OSS存储bucket

[auth]
valid_tokens = ["sk-zhouhui1xxx", "zhouhui112xxx"]

上面代码需要再服务器或者本地运行起来。对外提供 8088端口(端口你也可以自己改)

上面步骤服务端就启动好了。

1.客户端代码

接下来我们在dify 代码执行中添加。

这里我们有3个参考。分别是1.json_html 参数提取提取的html代码。2 apiurl 就是上面服务端代码的请求地址。3 apikey 服务端代码请求APIkey.

其中 apiurl 和apikey 我们这里用环境变量方式来实现。

如果你本地电脑 URL 可以是 192.168.XX.XX 或者127.0.0.1 如果是服务器 可以是局域网IP 也是可以公网IP

客户端APIKEY 和服务端APIKEY 保持一致。服务端APIKEY 就是config.ini 对应的

我上面服务端数组定义2个值,客户端有一个值在这个数组就可以了。

客户端代码如下:

python 复制代码
import json
import re
import time
import requests

def main(json_html: str, apikey: str,apiurl: str,strtype: str) -> dict:
    try:
        # 去除输入字符串中的 ```html 和 ``` 标记
        html_content = re.sub(r'^```html\s*|\s*```$', '', json_html, flags=re.DOTALL).strip()
        
        # 生成时间戳,确保文件名唯一
        timestamp = int(time.time())
        filename = f"{strtype}_{timestamp}.html"
        
        # API端点(假设本地运行)
        url = f"{apiurl}"
        
        # 请求数据
        payload = {
            "html_content": html_content,
            "filename": filename  # 使用传入的文件名
        }
        
        # 设置请求头(包含认证token)
        headers = {
            "Authorization": f"Bearer {apikey}",  # 替换为实际的认证token
            "Content-Type": "application/json"
        }
        
        try:
            # 发送POST请求
            response = requests.post(url, json=payload, headers=headers)
            
            # 检查响应状态
            if response.status_code == 200:
                result = response.json()
                html_url = result.get("html_url", "")
                generated_filename = result.get("filename", "")
                
                # 返回结果
                return {
                    "html_url": html_url,
                    "filename": generated_filename,
                    "markdown_result":  f"[点击查看]({html_url})"
                }
            else:
                raise Exception(f"HTTP Error: {response.status_code}, Message: {response.text}")
        
        except requests.exceptions.RequestException as e:
            raise Exception(f"Request failed: {str(e)}")
    
    except Exception as e:
        return {
            "error": f"Error: {str(e)}"
        }

返回3个值html_url、filename、markdown_result

以上就完成了服务端代码生成和客户端代码调用的功能了。

直接回复

这个直接回复我们为了方便调试分别返回 发票申请单JSON数据、发票开具预览展示HTML代码、生成HTML展示 三段

通过以上方式我们就完成了dify工作流的配置。

3.验证及测试

我们打开工作流预览按钮。点击从本地文件上传

我们选择的发票申请单表格内容如下

上传后点击

我们打开这个生成HTML 页面

以上我们就完成发票申请单上传通过dify工作流实现发票待开具申请预览功能了。

附发票申请单测试

music-1258720957.cos.ap-nanjing.myqcloud.com/%E6%B5%8B%E...

体验地址

工作流地址:dify.duckcloud.fun/chat/3ezEvh...

4.总结

今天主要带大家制作了一个基于 Dify 的发票申请单开具发票预览工作流。此次实践不仅实现了从发票申请单表格上传到生成标准化发票预览页面的全流程自动化,还重点展示了 Dify 在集成第三方插件、调用大语言模型处理数据以及对接外部存储服务方面的灵活能力。

总的来说,通过此次实践,我们充分体验到了 Dify 在财务类 AI 应用开发中的便捷性和高效性。它通过集成 Excel 转 Json 插件简化了数据格式转换,借助大语言模型精准提取发票关键信息并生成符合标准的 HTML 预览页面,再结合腾讯云 COS 实现了预览页面的存储与访问,为发票开具前的申请预览环节提供了高效、规范的解决方案。

感兴趣的小伙伴可以按照本文步骤去尝试制作自己的发票申请单预览工作流,并探索与实际开票系统的对接可能性。今天的分享就到这里结束了,我们下一篇文章见。

关注「 wwzhouhui」公众号,点赞分享这篇文章,后台私信:"dsl" 领取 dsl 工作流文件。

相关推荐
王者鳜錸17 分钟前
VUE+SPRINGBOOT从0-1打造前后端-前后台系统-邮箱重置密码
前端·vue.js·spring boot
独泪了无痕2 小时前
深入浅析Vue3中的生命周期钩子函数
前端·vue.js
小白白一枚1112 小时前
vue和react的框架原理
前端·vue.js·react.js
字节逆旅2 小时前
从一次爬坑看前端的出路
前端·后端·程序员
若梦plus3 小时前
微前端之样式隔离、JS隔离、公共依赖、路由状态更新、通信方式对比
前端
若梦plus3 小时前
Babel中微内核&插件化思想的应用
前端·babel
若梦plus3 小时前
微前端中微内核&插件化思想的应用
前端
若梦plus3 小时前
服务化架构中微内核&插件化思想的应用
前端
若梦plus3 小时前
Electron中微内核&插件化思想的应用
前端·electron
若梦plus3 小时前
Vue.js中微内核&插件化思想的应用
前端