tianyun 3 kuukautta sitten
vanhempi
commit
6b8449d5d9
9 muutettua tiedostoa jossa 530 lisäystä ja 64 poistoa
  1. 12 0
      .vscode/launch.json
  2. 65 0
      chat-room/main.py
  3. 128 0
      chat-room/templates/room.html
  4. 1 0
      folder-alias.json
  5. 71 29
      tmp10.py
  6. 104 0
      tmp11.py
  7. 32 1
      tmp3.py
  8. 111 13
      tmp8.py
  9. 6 21
      tmp9.py

+ 12 - 0
.vscode/launch.json

@@ -0,0 +1,12 @@
+{
+  "configurations": [
+    {
+      "type": "python",
+      "name": "debug tmp3.py",
+      "request": "launch",
+      "justMyCode": false,
+      "args": [],
+      "program": "/Users/alvin/IdeaProjects/python-base/tmp3.py"
+    }
+  ]
+}

+ 65 - 0
chat-room/main.py

@@ -0,0 +1,65 @@
+# app.py
+from flask import Flask, render_template, request
+from flask_socketio import SocketIO, join_room, leave_room
+
+app = Flask(__name__)
+app.config['SECRET_KEY'] = 'secret!'
+socketio = SocketIO(app, cors_allowed_origins="*")
+
+rooms = {}
+
+
+@socketio.on('join')
+def on_join(data):
+    room = data['room']
+    join_room(room)
+    rooms[request.sid] = room
+    socketio.emit('message', {'type': 'system', 'msg': '新用户加入'}, room=room)
+
+
+@socketio.on('leave')
+def on_leave():
+    room = rooms.get(request.sid)
+    if room:
+        leave_room(room)
+        del rooms[request.sid]
+        socketio.emit('message', {'type': 'system', 'msg': '用户离开'}, room=room)
+
+
+@socketio.on('offer')
+def handle_offer(data):
+    # 添加发送者标识
+    data['sender'] = request.sid
+    # 广播给房间内其他用户
+    socketio.emit('offer', data, room=data['room'], skip_sid=request.sid)
+
+@socketio.on('answer')
+def handle_answer(data):
+    data['sender'] = request.sid
+    # 发送给指定用户
+    socketio.emit('answer', data, room=data['target'])
+
+@socketio.on('candidate')
+def handle_candidate(data):
+    data['sender'] = request.sid
+    socketio.emit('candidate', data, room=data['target'])
+
+@socketio.on('answer')
+def handle_answer(data):
+    data['sender'] = request.sid
+    # 发送给指定用户
+    socketio.emit('answer', data, room=data['target'])
+
+@socketio.on('candidate')
+def handle_candidate(data):
+    data['sender'] = request.sid
+    socketio.emit('candidate', data, room=data['target'])
+
+
+@app.route('/room/<room_id>')
+def room(room_id):
+    return render_template('room.html', room_id=room_id)
+
+
+if __name__ == '__main__':
+    socketio.run(app, host='0.0.0.0', port=15000, debug=True, allow_unsafe_werkzeug=True)

+ 128 - 0
chat-room/templates/room.html

@@ -0,0 +1,128 @@
+<!-- templates/room.html -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>语音聊天室 - {{ room_id }}</title>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
+  </head>
+  <body>
+    <h1>语音聊天室 {{ room_id }}</h1>
+    <button id="micButton" onclick="toggleMic()">🎤 点击说话</button>
+    <div id="status"></div>
+
+    <script>
+      const room_id = "{{ room_id }}";
+      let isMute = true;
+      let localStream;
+      let socket = io();
+      const peers = {};
+
+      // 初始化WebSocket连接
+      socket.on("connect", () => {
+        socket.emit("join", { room: room_id });
+      });
+
+      // 获取麦克风权限
+      async function init() {
+        try {
+          localStream = await navigator.mediaDevices.getUserMedia({
+            audio: true,
+          });
+          document.getElementById("status").innerHTML = "麦克风已就绪";
+        } catch (err) {
+          console.error("Error accessing microphone:", err);
+        }
+      }
+
+      // 切换麦克风状态
+      async function toggleMic() {
+        isMute = !isMute;
+        const button = document.getElementById("micButton");
+        button.textContent = isMute ? "🎤 点击说话" : "🔴 正在说话";
+
+        localStream
+          .getAudioTracks()
+          .forEach((track) => (track.enabled = !isMute));
+
+        if (!isMute) {
+          const peer = new RTCPeerConnection();
+          peers[socket.id] = peer;
+
+          localStream
+            .getTracks()
+            .forEach((track) => peer.addTrack(track, localStream));
+
+          peer.onicecandidate = (e) => {
+            if (e.candidate) {
+              socket.emit("candidate", {
+                candidate: e.candidate,
+                room: room_id,
+                target: socket.id, // 添加目标标识
+              });
+            }
+          };
+
+          const offer = await peer.createOffer();
+          await peer.setLocalDescription(offer);
+
+          socket.emit("offer", {
+            sdp: offer,
+            room: room_id, // 使用room字段
+          });
+        }
+      }
+
+      // WebRTC信令处理
+      socket.on("offer", async (data) => {
+        // 添加发送者过滤
+        if (data.sender === socket.id) return;
+
+        const peer = new RTCPeerConnection();
+        peers[data.sender] = peer;
+
+        peer.onicecandidate = (e) => {
+          if (e.candidate) {
+            socket.emit("candidate", {
+              candidate: e.candidate,
+              target: data.sender,
+              room: room_id,
+            });
+          }
+        };
+
+        peer.ontrack = (e) => {
+          const audio = document.createElement("audio");
+          audio.srcObject = e.streams[0];
+          audio.play();
+        };
+
+        await peer.setRemoteDescription(data.sdp);
+        const answer = await peer.createAnswer();
+        await peer.setLocalDescription(answer);
+
+        socket.emit("answer", {
+          sdp: answer,
+          target: data.sender, // 指定目标用户
+          room: room_id,
+        });
+      });
+
+      socket.on("answer", (data) => {
+        if (data.sender === socket.id) return;
+        const peer = peers[data.sender];
+        if (peer) {
+          peer.setRemoteDescription(data.sdp);
+        }
+      });
+
+      // 修改candidate处理逻辑
+      socket.on("candidate", (data) => {
+        if (data.sender === socket.id) return;
+        const peer = peers[data.sender];
+        peer.addIceCandidate(new RTCIceCandidate(data.candidate));
+      });
+
+      init();
+    </script>
+  </body>
+</html>

+ 1 - 0
folder-alias.json

@@ -0,0 +1 @@
+{}

+ 71 - 29
tmp10.py

@@ -1,39 +1,81 @@
-from qdrant_client import QdrantClient
+import requests
+import json
 
-from qdrant_client.models import Distance, VectorParams
-from qdrant_client.models import PointStruct
+def chat_with_llm(messages):
+    url = "http://192.168.10.91:8000/v1/chat/completions"
+    headers = {
+        "Content-Type": "application/json",
+        "Accept": "text/event-stream"
+    }
+    data = {
+        "messages": messages
+    }
 
-client = QdrantClient(path="my_qdrant")
+    # 发送请求并获取响应
+    response = requests.post(url, headers=headers, json=data, stream=True)
 
+    # 完整的响应文本
+    full_response = ""
 
-def create_collection():
-    client.create_collection(
-        collection_name="test_collection",
-        vectors_config=VectorParams(size=4, distance=Distance.DOT),
-    )
+    # 处理流式响应
+    try:
+        for line in response.iter_lines():
+            if not line:
+                continue
 
+            # 解码二进制数据
+            line = line.decode('utf-8')
 
-def add_vectors():
-    operation_info = client.upsert(
-        collection_name="test_collection",
-        wait=True,
-        points=[
-            PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
-            PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
-            PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
-            PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": "New York"}),
-            PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"city": "Beijing"}),
-            PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44], payload={"city": "Mumbai"}),
-        ],
-    )
+            # 检查是否是SSE数据行
+            if line.startswith('data: '):
+                data = line[6:]  # 移除 'data: ' 前缀
 
-    print(operation_info)
+                if data == '[DONE]':
+                    print("\n[会话结束]")
+                    break
 
+                # 打印实时token并刷新输出
+                print(data, end='', flush=True)
+                full_response += data
 
-def query():
-    search_result = client.search(
-        collection_name="test_collection", query_vector=[0.2, 0.1, 0.9, 0.7], limit=3, with_vectors=True
-    )
-    print(search_result)
+    except KeyboardInterrupt:
+        print("\n[用户中断]")
+        return full_response
+    except Exception as e:
+        print(f"\n[错误] {str(e)}")
+        return full_response
 
-# create_collection()
+    return full_response
+
+def main():
+    # 初始化对话历史
+    conversation = []
+
+    print("开始对话 (输入 'quit' 结束对话)")
+
+    while True:
+        # 获取用户输入
+        user_input = input("\n用户: ")
+
+        if user_input.lower() == 'quit':
+            print("对话结束")
+            break
+
+        # 添加用户消息到对话历史
+        conversation.append({
+            "role": "user",
+            "content": user_input
+        })
+
+        # 调用API并打印响应
+        print("\nAI: ", end='')
+        response = chat_with_llm(conversation)
+
+        if response:  # 只有在有响应时才添加到对话历史
+            conversation.append({
+                "role": "assistant",
+                "content": response
+            })
+
+if __name__ == "__main__":
+    main()

+ 104 - 0
tmp11.py

@@ -0,0 +1,104 @@
+import pandas as pd
+from openpyxl.reader.excel import load_workbook
+
+# 读取模板Excel文件
+template_path = '/Users/alvin/Downloads/合同抽取字段表述250321.xlsx'
+df_template = pd.read_excel(template_path, engine='openpyxl')
+# 预处理:处理合并单元格逻辑
+for i in range(1, len(df_template)):  # 从第二行开始检查
+    if pd.isna(df_template.loc[i, '类别']) and not pd.isna(df_template.loc[i, '字段描述']):
+        df_template.loc[i, '类别'] = df_template.loc[i-1, '类别']
+
+# 定义JSON数据
+json_data = {
+    "基础": {
+        "合同总金额": "未填写(赊销总额度100万元)",
+        "不含税金额": "",
+        "税率": "",
+        "税额": "",
+        "合同类型": "买卖合同",
+        "签订日期": "",
+        "开始日期": "2021年(具体月份未填写)",
+        "结束日期": "2027年12月31日",
+        "违约金": "逾期60天内按0.03%/日计费,超60天按0.05%/日计费",
+        "质保金": "",
+        "质保期": "",
+        "固定总价": "",
+        "固定单价": "",
+        "暂估金额": "",
+        "付款方式": "账期结算(固定账单日每月15日,账期60天)",
+        "发票类型": "增值税专用发票"
+    },
+    "甲乙双方信息": {
+        "乙方名称": "北京京东世纪信息技术有限公司",
+        "乙方账户名称": "北京京东世纪信息技术有限公司",
+        "乙方开户行": "招商银行股份有限公司北京青年路支行",
+        "乙方银行账号": "110907697010208",
+        "乙方联系人": "张洪君",
+        "乙方联系电话": "15701277612",
+        "乙方邮箱": "zhanghongjun13@jd.com",
+        "乙方地址": "北京经济技术开发区科创十一街18号院C座2层215室",
+        "甲方名称": "海信集团有限公司",
+        "甲方账户名称": "",
+        "甲方开户行": "",
+        "甲方银行账号": "",
+        "甲方联系人": "李明",
+        "甲方联系电话": "13812345678",
+        "甲方邮箱": "554857923@qq.com",
+        "甲方地址": "青岛市市南区东海西路17号"
+    },
+    "履行": {
+        "交付与验收条件": "当场验收货物品类/规格/型号/数量/外包装",
+        "交付时间": "按订单约定时间发货(普通快递时效)",
+        "交付金额": "",
+        "支付方式": "账期支付",
+        "支付金额": "",
+        "支付时间节点": "固定账单日每月15日出账,还款周期内支付"
+    },
+    "表格": {
+        "序号": "",
+        "标的物": "",
+        "生产厂家": "",
+        "品牌": "",
+        "规格型号": "",
+        "计量单位": "",
+        "数量": "",
+        "含税单价": "",
+        "不含税总价": "",
+        "税率": "",
+        "增值税合计": "",
+        "价税合计": ""
+    }
+}
+
+
+# 将JSON数据转换为DataFrame以方便操作
+data_rows = []
+for category, fields in json_data.items():
+    for field_name, attributes in fields.items():
+        data_rows.append({'类别': category, '字段描述': field_name, '属性': attributes})
+df_data = pd.DataFrame(data_rows)
+
+# 合并两个DataFrame:基于'类别'和'字段描述'列进行左连接
+merged_df = df_template.merge(df_data, on=['类别', '字段描述'], how='left', suffixes=('', '_data'))
+
+# 更新属性列,用来自JSON的数据填充
+merged_df['属性'] = merged_df['属性_data'].fillna(merged_df['属性'])
+del merged_df['属性_data']
+
+# 使用openpyxl加载原始Excel文件
+wb = load_workbook(template_path)
+ws = wb.active
+
+# 遍历merged_df并将属性列的值写回到对应的单元格中
+row_num = 2  # 假设从第二行开始有数据
+for idx, row in merged_df.iterrows():
+    target_cell = ws[f"C{row_num}"]  # 假定属性列是C列
+    target_cell.value = row['属性']
+    row_num += 1
+
+# 保存工作簿
+output_path = '更新后的合同模板.xlsx'
+wb.save(output_path)
+
+print(f"已成功保存到{output_path}")

+ 32 - 1
tmp3.py

@@ -1 +1,32 @@
-# 给我举一个决策树算法 Decision Tree 的例子
+import json
+
+def convert_format(input_str):
+    try:
+        # 解析输入字符串为Python字典
+        input_data = json.loads(input_str)
+
+        # 构建输出数组
+        output_list = []
+
+        # 遍历每个键值对
+        for category_name, items in input_data.items():
+            output_item = {
+                "name": category_name,
+                "datas": items
+            }
+            output_list.append(output_item)
+
+        # 转换为JSON字符串并返回
+        return json.dumps(output_list, ensure_ascii=False)
+
+    except Exception as e:
+        return f"转换出错: {str(e)}"
+
+# 示例输入(多个key的情况)
+input_example = """
+{"常用工具":[{"title":"语雀图床","icon":"https://www.yuque.com/favicon.ico","mainUrl":"https://www.yuque.com/tianyunperfect/fg7hif/ecw4pcgn1y2ise60","description":"","extraUrls":[],"screenshot":"https://cdn.nlark.com/yuque/0/2025/png/241764/1743498516801-1b9a7c09-055e-4f87-b848-ef8168ba5445.png?x-oss-process=image%2Fformat%2Cwebp"}]}
+"""
+
+# 执行转换
+output_example = convert_format(input_example)
+print(output_example)

+ 111 - 13
tmp8.py

@@ -1,13 +1,111 @@
-from visualdl.server import app
-
-logdir = "./log/scalar_test/train"
-
-if __name__ == '__main__':
-    app.run(logdir=logdir,
-            host="127.0.0.1",
-            port=8080,
-            cache_timeout=20,
-            language=None,
-            public_path=None,
-            api_only=False,
-            open_browser=False)
+import os
+import uuid
+from datetime import datetime
+import pymysql
+from dbutils.pooled_db import PooledDB
+
+
+class MySQLPool:
+    def __init__(self, host, port, user, password, database, pool_size=5):
+        self.pool = PooledDB(
+            creator=pymysql,
+            maxconnections=pool_size,
+            host=host,
+            port=port,
+            user=user,
+            password=password,
+            database=database,
+            charset='utf8mb4',
+            cursorclass=pymysql.cursors.DictCursor,
+        )
+
+    def get_connection(self):
+        return self.pool.connection()
+
+    def exec(self, sql, params=None):
+        conn = self.get_connection()
+        try:
+            with conn.cursor() as cursor:
+                result = cursor.execute(sql, params)
+                conn.commit()
+                return result
+        finally:
+            conn.close()
+
+
+# 初始化连接池
+pool = MySQLPool(
+    host='www.tianyunperfect.cn',
+    port=3306,
+    user='memos',
+    password='s3ijTsaH5cciP8s8',
+    database='memos'
+)
+
+base_dir = "/Users/alvin/Downloads/fcf7e810-2472-4a76-9d00-b2e58bf5cf20_Export-b76ceacb-9576-437c-9ad3-fb0cea7a6076/梦记 de2ddb5d286e4dffacb1eb26a4e074be"
+
+
+def extract_date_and_process(text):
+    lines = text.splitlines()
+
+    # 移除第一行
+    new_lines = lines[1:]
+
+    # 提取第三行(原输入中的第三行,现在索引1)
+    try:
+        third_line = new_lines[1]
+    except IndexError:
+        return None, "输入内容不足,无法提取日期"
+
+    # 解析日期
+    if ':' in third_line:
+        parts = third_line.split(':', 1)
+        date_str = parts[1].strip()
+    else:
+        return None, "第三行格式不正确,缺少日期"
+
+    # 重新组合字符串
+    new_text = '\n'.join(new_lines)
+
+    return date_str, new_text
+
+
+for root, dirs, files in os.walk(base_dir):
+    for file in files:
+        if file.endswith(".md"):
+            file_path = os.path.join(root, file)
+            try:
+                with open(file_path, "r", encoding="utf-8") as f:
+                    content = f.read()
+
+                    created_ts, full_content = extract_date_and_process(content)
+
+                    full_content = "#梦记 " + full_content
+
+                    # 生成 resource_name uuid 去除特殊字符
+                    resource_name = str(uuid.uuid4()).replace('-', '')
+
+                    # 构建 SQL 参数
+                    params = (
+                        resource_name,
+                        1,  # creator_id
+                        created_ts,  # created_ts
+                        created_ts,  # updated_ts
+                        'NORMAL',  # row_status
+                        full_content,  # content
+                        'PRIVATE'  # visibility
+                    )
+
+                    # 执行插入
+                    sql = """
+                    INSERT INTO memo 
+                    (resource_name, creator_id, created_ts, updated_ts, row_status, content, visibility)
+                    VALUES (%s, %s, %s, %s, %s, %s, %s)
+                    """
+                    # 打印 SQL 参数
+                    print(f"SQL 参数: {params}")
+                    result = pool.exec(sql, params)
+                    print(f"成功插入: {file},影响行数: {result}")
+
+            except Exception as e:
+                print(f"处理文件 {file} 时出错: {str(e)}")

+ 6 - 21
tmp9.py

@@ -1,23 +1,8 @@
-import requests
+from docx import Document
 
-headers = {
-    'accept': '*/*',
-    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
-    'authorization': 'bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoidGlhbnl1bnBlcmZlY3QiLCJpc3MiOiJtZW1vcyIsInN1YiI6IjEiLCJhdWQiOlsidXNlci5hY2Nlc3MtdG9rZW4iXSwiaWF0IjoxNzA5MTc5NTUyfQ.LFxWB4efya1sL7VoJ42xpXxbAip-udT_Kx2OwZ8Y3-E',
-    'cache-control': 'no-cache',
-    'content-type': 'application/json',
-    'origin': 'https://web.tianyunperfect.cn',
-    'pragma': 'no-cache',
-    'priority': 'u=1, i',
-    'referer': 'https://web.tianyunperfect.cn/simple/memos.html',
-    'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Google Chrome";v="128"',
-    'sec-ch-ua-mobile': '?0',
-    'sec-ch-ua-platform': '"macOS"',
-    'sec-fetch-dest': 'empty',
-    'sec-fetch-mode': 'cors',
-    'sec-fetch-site': 'same-site',
-    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
-}
+# 打开.doc文件
+doc = Document("/Users/alvin/Downloads/11示例/合同文件/49.技术服务合同.docx")
 
-response = requests.get('https://memos.tianyunperfect.cn/api/v1/tag', headers=headers, verify=False)
-print(response)
+# 遍历文档的段落
+for para in doc.paragraphs:
+    print(para.text)