D23-26 项目跟写

项目针对16-30岁的明日方舟爱好者,采用HTML+CSS+JavaScript基础搭建,结合BootStrap和jQuery框架,利用wangEditor进行内容编辑,并通过Echarts实现数据可视化。在开发过程中遇到环境配置、知识运用和错误调试等问题,计划巩固现有知识并学习更多技能。

 1.需求分析:

  1.1项目受众:面向16-30岁的明日方舟爱好者
  1.2创作背景:在明日方舟庞大背景下的模块化故事集分块
  1.3创作理念:为爱发电,高效、快捷地展示泰拉大陆发生的点点滴滴

 2.主要功能

  2.1后台发布增删改查
    2.1.1图片展示
在这里插入图片描述
    2.1.2非管理员图片展示
在这里插入图片描述

"users": [
    {
      "id": 1,
      "username": "admin",
      "password": "***",
      "role": "admin",
      "default": true
    }
    ]
//通过绑定role实现不同的管理员权限

  2.2借助wangEditor实现编辑框
    2.2.1图片展示
在这里插入图片描述
在这里插入图片描述

    2.2.2代码展示

<div class="maincontent">
                        <!-- 面包屑 -->
                        <nav aria-label="breadcrumb">
                            <ol class="breadcrumb">
                              <li class="breadcrumb-item" aria-current="page">见闻</li>
                              <li class="breadcrumb-item active" aria-current="page">修缮条约</li>
                            </ol>
                          </nav>

                          <form id="editNewsForm">
                            <div class="mb-3">
                                <label for="title" class="form-label">标题</label>
                                <input type="text" class="form-control" id="title" aria-describedby="emailHelp" required>
                              </div>
                              <div class="mb-3">
                                <label for="content" class="form-label">合约详情</label>
                                <div id="content" style="border:1px solid #ced4da;">
                                    <div id="toolbar-container"><!-- 工具栏 --></div>
                                    <div id="editor-container"><!-- 编辑器 --></div>
                                </div>
                              </div>
                              <div class="mb-3">
                                <label for="category" class="form-label">类别</label>
                                <select class="form-select" aria-label="Default select example" id="category">
                                    <option selected>记实</option>
                                    <option value="0">特别行动记述</option>
                                    <option value="1">公共事物实录</option>
                                    <option value="2">罗德岛公告</option>
                                  </select>             
                              </div>
                              <div class="mb-3">
                                <label for="coverfile" class="form-label">影像</label>
                                <input type="file" class="form-control" id="coverfile">
                              </div>
                              <button type="submit" class="btn btn-primary">缔造</button>
                            </form>

                        </div>
                        <script>
                        //引入模块

import {load,isLogin} from "/code/admin/util/LoadView.js"
load("sidemenu-newsList")  //加载topbar 以及未来的sidemenu

//获取id
//console.log(new URL(location.href).searchParams.get("id"))
let updateId = new URL(location.href).searchParams.get("id")

//绑定内容
let content = ""
let cover = ""

const { createEditor, createToolbar } = window.wangEditor

const editorConfig = {
    placeholder: 'Type here...',
    onChange(editor) {
      const html = editor.getHtml()
    //  console.log('editor content', html)
      // 也可以同步到 <textarea>
      content = html
    }
}

const editor = createEditor({
    selector: '#editor-container',
    html: '<p><br></p>',
    config: editorConfig,
    mode: 'default', // or 'simple'
})

const toolbarConfig = {}

const toolbar = createToolbar({
    editor,
    selector: '#toolbar-container',
    config: toolbarConfig,
    mode: 'default', // or 'simple'
})


coverfile.onchange = function(evt){
    //console.log(evt.target.files[0])
    //===>base64

    let reader = new FileReader()

    reader.readAsDataURL(evt.target.files[0])

    reader.onload = function(e){
        //console.log(e.target.result)
        cover = e.target.result 
    }
}

editNewsForm.onsubmit = async function(evt){
    evt.preventDefault()
    await fetch(`http://localhost:5000/news/${updateId}`,{
        headers:{
            "content-type":"application/json"
        },
        method:"PATCH",   //补丁式
        body:JSON.stringify({
            title:title.value,
            content,
            category:category.value,
            cover,
            //作者
            author:JSON.parse(isLogin()).username
        })
    }).then(res=>res.json())
    location.href = "/code/admin/views/news-manage/NewsList/index.html"
}

async function render(){
    let {title,category,content:mycontent,cover:mycover} =await fetch(`http://localhost:5000/news/${updateId}`).then
    (res=>res.json())
    //console.log()
    document.querySelector("#title").value = title
    document.querySelector("#category").value = category

    //设置content mycontent:防止串名
    editor.setHtml(mycontent)
    
    content = mycontent

    cover = mycover
}

render()
                        </script>
主要借助引入wangEditor模块,实现相关文本的编辑

  2.3Echarts数据显示
    2.3.1图片展示
在这里插入图片描述
    2.3.2实现原理:

通过对Echarts模块的调用,设置对象和for in 结构,将用户编辑的内容填充到饼状图中,实现数据的可视化

 3.实现技术

  3.1基础搭建:HTML+CSS+JavaScript
  3.2框架:BootStrap + jQuery
  3.3外部支持:BootStrap + Echarts + wangEditor

 4.项目总结

  4.1面对困难
    4.1.1缺乏对node.js的环境建设经验,由此衍生出后续其他开发工具环境建设的不熟悉
    4.1.2对于整体知识的运用和理解欠佳,知识点出现遗忘
    4.1.3操作不断失误,大小bug都有,复查周期长
  4.2后续规划
    4.2.1巩固现有知识,抽出时间将前面学习的编码内容复学
    4.2.2多写多练,代码编写唯手熟尔
    4.2.3根据空暇时间学习一点专业外技术,如PPT和剪辑
  4.3整体总结
    4.3.1对于本次项目跟写,所揭露出JS编码部分能力薄弱,模块化运用能力有待提高
    4.3.2初次尝试小网页的撰写,统筹总体,细致分化,合理节流,对三者的理解才刚刚开始
    4.3.3能力不足,胆气尚欠

import os import json import requests import sys from typing import Dict, Any, List, Tuple, Set, Optional import urllib.parse import time import datetime import re from dotenv import load_dotenv from collections import defaultdict # === 辅助工具 === class Timer: def __init__(self): self._start = None def start(self): self._start = time.perf_counter() def stop(self, msg=""): if self._start: print(f" - [计时] {msg}耗时: {time.perf_counter() - self._start:.4f}s"); self._start = None # --- 加载配置 --- try: script_dir = os.path.dirname(os.path.realpath(__file__)) except: script_dir = os.path.abspath(os.getcwd()) dotenv_path = os.path.join(script_dir, '.env') load_dotenv(dotenv_path) if os.path.exists(dotenv_path) else None APP_ID = os.getenv("APP_ID") APP_SECRET = os.getenv("APP_SECRET") SPREADSHEET_TOKEN = os.getenv("SPREADSHEET_TOKEN") REDIRECT_URI = os.getenv("REDIRECT_URI", "http://localhost:8080/auth") TOKEN_FILE = "feishu_token.json" # 列配置 ATTR_COL = os.getenv("ATTRIBUTE_COL", "B") # (新) 属性列 NAME_COL = os.getenv("MATERIAL_NAME_COL", "A") # 物料名称 S1_CODE_COL = os.getenv("SUPPLIER_1_CODE_COL", "C") S1_SUP_COL = os.getenv("SUPPLIER_1_SUPPLIER_COL", "D") S2_CODE_COL = os.getenv("SUPPLIER_2_CODE_COL", "E") S2_SUP_COL = os.getenv("SUPPLIER_2_SUPPLIER_COL", "F") START_ROW = int(os.getenv("START_ROW", "2")) END_ROW = int(os.getenv("END_ROW", "500")) SUMMARY_SHEET_NAME = os.getenv("SUMMARY_SHEET_NAME", "零部件比对汇总(新)") # === 1. 认证模块 (保持不变) === def save_token(data): try: with open(os.path.join(script_dir, TOKEN_FILE), 'w') as f: json.dump(data, f, indent=4) except Exception as e: print(f"Error saving token: {e}") def load_token(): path = os.path.join(script_dir, TOKEN_FILE) if not os.path.exists(path): return {} try: with open(path, 'r') as f: d = json.load(f) if 'expires_at' in d: d['expires_at'] = datetime.datetime.fromisoformat(d['expires_at']) return d except: return {} def get_access_token(): data = load_token() if data.get("access_token") and data.get("expires_at", datetime.datetime.min) > datetime.datetime.now(): return data["access_token"] if data.get("refresh_token"): try: url = "https://open.feishu.cn/open-apis/authen/v2/oauth/token" resp = requests.post(url, json={"grant_type": "refresh_token", "client_id": APP_ID, "client_secret": APP_SECRET, "refresh_token": data["refresh_token"]}) resp.raise_for_status() res = resp.json() if res.get("code") == 0: new_data = {"access_token": res["access_token"], "refresh_token": res["refresh_token"], "expires_at": (datetime.datetime.now() + datetime.timedelta(seconds=res["expires_in"]-300)).isoformat()} save_token({**new_data, "expires_at": new_data["expires_at"]}) return res["access_token"] except: pass scope = "sheets:spreadsheet sheets:spreadsheet:read sheets:spreadsheet:write_only sheets:spreadsheet.meta:read sheets:spreadsheet.meta:write" url = f"https://accounts.feishu.cn/open-apis/authen/v1/authorize?client_id={APP_ID}&response_type=code&redirect_uri={urllib.parse.quote(REDIRECT_URI)}&scope={scope}" print(f"请打开链接授权:\n{url}") code = input("请输入Code: ").strip() resp = requests.post("https://open.feishu.cn/open-apis/authen/v2/oauth/token", json={ "grant_type": "authorization_code", "client_id": APP_ID, "client_secret": APP_SECRET, "code": code, "redirect_uri": REDIRECT_URI}) res = resp.json() if res.get("code") != 0: raise Exception(f"Auth failed: {res}") token_data = {"access_token": res["access_token"], "refresh_token": res.get("refresh_token"), "expires_at": (datetime.datetime.now() + datetime.timedelta(seconds=res["expires_in"]-300)).isoformat()} save_token(token_data) return res["access_token"] # === 2. 飞书 API 基础操作 === def call_api(method, url, json_data=None, params=None): token = get_access_token() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json; charset=utf-8"} # 添加调试日志 print(f" - [API 调用] {method} {url}") resp = requests.request(method, url, headers=headers, json=json_data, params=params) try: resp.raise_for_status() except requests.exceptions.HTTPError as e: # 打印更详细的错误 print(f"API 请求失败: {e}") if e.response is not None: try: print(f"错误详情: {e.response.json()}") except json.JSONDecodeError: print(f"错误详情 (text): {e.response.text}") raise e # 重新抛出异常 res = resp.json() if res.get("code", 0) != 0: print(f"API 业务错误: {res}") raise Exception(f"API Error: {res}") return res def get_sheet_id_by_name(sp_token, name): res = call_api("GET", f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{sp_token}/sheets/query") for sheet in res["data"]["sheets"]: if sheet["title"] == name: return sheet["sheet_id"] return None def create_sheet(sp_token, name): exist = get_sheet_id_by_name(sp_token, name) if exist: return exist # create_sheet 仍然使用 .../sheets_batch_update (这没错, V2的批量更新) res = call_api("POST", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{sp_token}/sheets_batch_update", json_data={"requests": [{"addSheet": {"properties": {"title": name}}}]}) return res["data"]["replies"][0]["addSheet"]["properties"]["sheetId"] def read_range(sp_token, sheet_id, col, s_row, e_row): rng = f"{sheet_id}!{col}{s_row}:{col}{e_row}" # read_range 使用 .../values_batch_get (这也没错, V2的读取) res = call_api("GET", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{sp_token}/values_batch_get", params={"ranges": rng}) vals = res["data"]["valueRanges"][0]["values"] result = [] for i, row in enumerate(vals): val = "" if row: cell = row[0] if isinstance(cell, dict): val = cell.get("text", "") else: val = str(cell) result.append({"row": s_row + i, "val": val.strip()}) return result # === 3. 工具函数:(保持不变) === def _col_str_to_idx(col_str: str) -> int: idx = 0 for char in col_str: idx = idx * 26 + (ord(char) - ord('A')) + 1 return idx - 1 def num_to_col_char(n): string = "" while n > 0: n, remainder = divmod(n - 1, 26) string = chr(65 + remainder) + string return string ProjectData = Dict[str, Dict[str, Tuple[str, str]]] # This type is unused, but fine to leave def fetch_all_data(sp_token, sheets) -> Dict[str, Dict[str, Any]]: # ★ 优化: 添加返回类型 # ★ 优化: 为 aligned_data 添加明确的类型提示 aligned_data: Dict[str, Dict[str, Any]] = defaultdict(lambda: {"attr": "", "projects": {}}) for sheet in sheets: title, sid = sheet["title"], sheet["sheet_id"] print(f" - 读取项目: {title} ...") names = read_range(sp_token, sid, NAME_COL, START_ROW, END_ROW) attrs = read_range(sp_token, sid, ATTR_COL, START_ROW, END_ROW) s1_codes = read_range(sp_token, sid, S1_CODE_COL, START_ROW, END_ROW) s1_sups = read_range(sp_token, sid, S1_SUP_COL, START_ROW, END_ROW) s2_codes = read_range(sp_token, sid, S2_CODE_COL, START_ROW, END_ROW) s2_sups = read_range(sp_token, sid, S2_SUP_COL, START_ROW, END_ROW) for i in range(len(names)): name = names[i]["val"] if not name: continue attr = attrs[i]["val"] if i < len(attrs) else "" s1_c = s1_codes[i]["val"] if i < len(s1_codes) else "" s1_s = s1_sups[i]["val"] if i < len(s1_sups) else "" s2_c = s2_codes[i]["val"] if i < len(s2_codes) else "" s2_s = s2_sups[i]["val"] if i < len(s2_sups) else "" if not aligned_data[name]["attr"] and attr: aligned_data[name]["attr"] = attr aligned_data[name]["projects"][title] = { "s1": (s1_s, s1_c), # (供应商, 料号) "s2": (s2_s, s2_c) } return aligned_data def main(): print("=== 开始执行:多项目零部件比对与样式生成 ===") # 1. 获取所有 Sheet all_sheets_meta = call_api("GET", f"https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/{SPREADSHEET_TOKEN}/sheets/query")["data"]["sheets"] valid_sheets = [s for s in all_sheets_meta if s["title"] != SUMMARY_SHEET_NAME] print("发现以下项目:") for i, s in enumerate(valid_sheets): print(f" [{i+1}] {s['title']}") sel_idx = input("请输入要比对的项目序号 (如 1,2,3 或 all): ").strip() if sel_idx.lower() == "all": selected = valid_sheets else: selected = [valid_sheets[int(x)-1] for x in sel_idx.split(",") if x.strip().isdigit()] if len(selected) < 2: print("至少选择两个项目!"); return proj_names = [s["title"] for s in selected] # 2. 读取并对齐数据 timer = Timer() timer.start() data_map = fetch_all_data(SPREADSHEET_TOKEN, selected) timer.stop("数据读取与对齐") # 3. 准备入数据矩阵 sorted_names = sorted(data_map.keys()) matrix = [] # --- 构建表头行 --- row1 = ["项目", "属性"] for p in proj_names: row1.extend([p, "", "", ""]) matrix.append(row1) row2 = ["", ""] for _ in proj_names: row2.extend(["一供", "", "二供", ""]) matrix.append(row2) row3 = ["物料名称", ""] for _ in proj_names: row3.extend(["供应商", "物料料号", "供应商", "物料料号"]) matrix.append(row3) # --- 构建数据行与样式计算 --- COLOR_GREEN = "#b7e1cd" COLOR_RED = "#f4c7c3" # WELCOME_MSG_ROW_IDX = 0 <-- ★ 修复: 删除这一行 (第 278 行), 它的缩进错误导致了 "main" 函数中断 green_cells = [] red_cells = [] current_row_idx = 4 for name in sorted_names: item = data_map[name] attr = item["attr"] row_data = [name, attr] pair_counts = defaultdict(int) for p_name in proj_names: p_data = item["projects"].get(p_name, {"s1":("",""), "s2":("","")}) s1 = p_data["s1"] s2 = p_data["s2"] if s1[0] and s1[1]: pair_counts[s1] += 1 if s2[0] and s2[1]: pair_counts[s2] += 1 col_idx = 3 for p_name in proj_names: p_data = item["projects"].get(p_name, {"s1":("",""), "s2":("","")}) s1 = p_data["s1"] s2 = p_data["s2"] row_data.extend([s1[0], s1[1]]) if s1[0] and s1[1]: cell_sup = f"{num_to_col_char(col_idx)}{current_row_idx}" cell_code = f"{num_to_col_char(col_idx+1)}{current_row_idx}" if pair_counts[s1] > 1: green_cells.extend([cell_sup, cell_code]) else: red_cells.extend([cell_sup, cell_code]) col_idx += 2 row_data.extend([s2[0], s2[1]]) if s2[0] and s2[1]: cell_sup = f"{num_to_col_char(col_idx)}{current_row_idx}" cell_code = f"{num_to_col_char(col_idx+1)}{current_row_idx}" if pair_counts[s2] > 1: green_cells.extend([cell_sup, cell_code]) else: red_cells.extend([cell_sup, cell_code]) col_idx += 2 matrix.append(row_data) current_row_idx += 1 # 4. 入表格 timer.start() sum_sid = create_sheet(SPREADSHEET_TOKEN, SUMMARY_SHEET_NAME) print(f"目标Sheet: {SUMMARY_SHEET_NAME} (ID: {sum_sid})") if matrix and len(matrix) > 0: num_rows = len(matrix) num_cols = len(matrix[0]) end_col_letter = num_to_col_char(num_cols) full_range = f"{sum_sid}!A1:{end_col_letter}{num_rows}" print(f" - 正在入范围: {full_range} ...") call_api("PUT", f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values", json_data={"valueRange": {"range": full_range, "values": matrix}}) else: print(" - 警告: 没有数据需要入。") print(" - 数据入完成") # 5. 准备合并请求 print(" - 正在准备单元格合并 (表头)...") merge_list = [] merge_list.append(f"{sum_sid}!A1:A2") # 项目 (FIX: A1:A2) merge_list.append(f"{sum_sid}!B1:B3") # 属性 current_col = 3 # C列 for _ in proj_names: start = num_to_col_char(current_col) end = num_to_col_char(current_col + 3) merge_list.append(f"{sum_sid}!{start}1:{end}1") # Proj Name s1_start = num_to_col_char(current_col) s1_end = num_to_col_char(current_col + 1) merge_list.append(f"{sum_sid}!{s1_start}2:{s1_end}2") # 一供 s2_start = num_to_col_char(current_col + 2) s2_end = num_to_col_char(current_col + 3) merge_list.append(f"{sum_sid}!{s2_start}2:{s2_end}2") # 二供 current_col += 4 # ★★★ 使用专用的 .../merge_cells API (V2, 这个没问题) ★★★ API_V2_MERGE_URL = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/merge_cells" if merge_list: print(f" - 正在批量执行 {len(merge_list)} 个合并请求...") # 这个接口不是批量的,我们必须循环调用 for rng_str in merge_list: payload = { "range": rng_str, # A1 字符串格式,带 sheetId "mergeType": "MERGE_ALL" } try: call_api("POST", API_V2_MERGE_URL, json_data=payload) except Exception as e: print(f"WARN: 合并 {rng_str} 失败: {e}") print(" - 表头合并完成") # 6. 准备上色请求 print(f" - 正在准备应用样式 (红: {len(red_cells)/2}组, 绿: {len(green_cells)/2}组)...") # ★★★ 核心修复: 采用 V4 最终方案 ★★★ # 1. URL: 使用 V4 端点 ( .../styles/batch_update ) API_V4_STYLE_URL = f"https://open.feishu.cn/open-apis/sheets/v4/spreadsheets/{SPREADSHEET_TOKEN}/styles/batch_update" # 2. Payload: 构造 V4 'data' 列表 style_data_list = [] # 红色单元格 if red_cells: # 3. Range 格式: "sheetId!A1,B2,C3" (逗号分隔的单一字符串) red_range_string = f"{sum_sid}!{','.join(red_cells)}" style_data_list.append({ "range": red_range_string, "style": {"back_color": COLOR_RED} # 4. Style Key: back_color (snake_case) }) # 绿色单元格 if green_cells: # 3. Range 格式: "sheetId!A1,B2,C3" green_range_string = f"{sum_sid}!{','.join(green_cells)}" style_data_list.append({ "range": green_range_string, "style": {"back_color": COLOR_GREEN} # 4. Style Key: back_color (snake_case) }) if style_data_list: # 5. Payload: 最终 V4 payload 结构 payload = {"data": style_data_list} print(f" - 正在提交 {len(style_data_list)} 组样式更新请求 (V4接口)...") if(len(json.dumps(payload)) > 5000): print(" - [调试] Payload 过长,仅显示前 5000 字符: " + json.dumps(payload)[:5000] + "...") else: print(f" - [调试] Payload: {json.dumps(payload)}") try: # 6. Call: 调用 V4 API call_api("POST", API_V4_STYLE_URL, json_data=payload) print(" - 样式更新成功") except Exception as e: # call_api 函数现在会打印详细错误 print(f" - 样式更新失败: {e}") else: print(" - 没有样式需要更新") timer.stop("入、合并与上色") print("任务完成!请查看飞书文档。") if __name__ == "__main__": try: main() except Exception as e: import traceback traceback.print_exc() print(f"Error: {e}") 现在代码如上,报错如下: 请输入要比对的项目序号 (如 1,2,3 或 all): 7,8,12 - 读取项目: R510C超薄 ... - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - 读取项目: R520C半包 ... - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - 读取项目: R500C ... - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values_batch_get - [计时] 数据读取与对齐耗时: 5.0121s - [API 调用] GET https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/sheets/query - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/sheets_batch_update 目标Sheet: R500C&R510超薄&R520半包物料差异比对-2 (ID: IZtjq) - 正在入范围: IZtjq!A1:N72 ... - [API 调用] PUT https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/values - 数据入完成 - 正在准备单元格合并 (表头)... - 正在批量执行 11 个合并请求... - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/merge_cells - 表头合并完成 - 正在准备应用样式 (红: 87.0组, 绿: 227.0组)... - 正在提交 2 组样式更新请求 (V4接口)... - [调试] Payload: {"data": [{"range": "IZtjq!K4,L4,M4,N4,K6,L6,M6,N6,C7,D7,E7,F7,G11,H11,I11,J11,C16,D16,E16,F16,G16,H16,I16,J16,G20,H20,I20,J20,C22,D22,E22,F22,C28,D28,G28,H28,K30,L30,M30,N30,C31,D31,E31,F31,K31,L31,M31,N31,E32,F32,M32,N32,C33,D33,E33,F33,C34,D34,E34,F34,K35,L35,M35,N35,C36,D36,E36,F36,C40,D40,E40,F40,K41,L41,M41,N41,G43,H43,I43,J43,K44,L44,M44,N44,C47,D47,G47,H47,K47,L47,M47,N47,K49,L49,M49,N49,C50,D50,E50,F50,C52,D52,E52,F52,G52,H52,K52,L52,K53,L53,M53,N53,C60,D60,E60,F60,K62,L62,M62,N62,C63,D63,E63,F63,K63,L63,M63,N63,C64,D64,E64,F64,G64,H64,I64,J64,C65,D65,E65,F65,G65,H65,I65,J65,K65,L65,M65,N65,C66,D66,E66,F66,C67,D67,E67,F67,C68,D68,E68,F68,G69,H69,I69,J69,G70,H70,C72,D72,G72,H72,I72,J72,K72,L72", "style": {"back_color": "#f4c7c3"}}, {"range": "IZtjq!C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10,M10,N10,C11,D11,E11,F11,K11,L11,M11,N11,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12,M12,N12,C13,D13,E13,F13,G13,H13,I13,J13,K13,L13,M13,N13,C14,D14,E14,F14,G14,H14,I14,J14,K14,L14,M14,N14,G15,H15,I15,J15,K15,L15,M15,N15,C17,D17,E17,F17,G17,H17,I17,J17,K17,L17,M17,N17,C18,D18,E18,F18,G18,H18,I18,J18,K18,L18,M18,N18,C19,D19,E19,F19,G19,H19,I19,J19,K19,L19,M19,N19,C20,D20,E20,F20,K20,L20,M20,N20,C21,D21,E21,F21,G21,H21,I21,J21,K21,L21,M21,N21,C23,D23,E23,F23,G23,H23,I23,J23,K23,L23,M23,N23,C24,D24,E24,F24,G24,H24,I24,J24,K24,L24,M24,N24,C25,D25,E25,F25,G25,H25,I25,J25,K25,L25,M25,N25,C26,D26,E26,F26,G26,H26,I26,J26,K26,L26,M26,N26,C27,D27,E27,F27,G27,H27,I27,J27,K27,L27,M27,N27,E28,F28,I28,J28,C29,D29,E29,F29,G29,H29,I29,J29,K29,L29,M29,N29,C32,D32,K32,L32,G34,H34,I34,J34,C37,D37,E37,F37,G37,H37,I37,J37,K37,L37,M37,N37,C38,D38,E38,F38,G38,H38,I38,J38,K38,L38,M38,N38,C39,D39,E39,F39,G39,H39,I39,J39,K39,L39,M39,N39,C42,D42,E42,F42,G42,H42,I42,J42,K42,L42,M42,N42,C45,D45,E45,F45,G45,H45,I45,J45,K45,L45,M45,N45,C46,D46,E46,F46,G46,H46,I46,J46,K46,L46,M46,N46,E47,F47,I47,J47,C48,D48,E48,F48,G48,H48,I48,J48,K48,L48,M48,N48,C51,D51,E51,F51,G51,H51,I51,J51,K51,L51,M51,N51,I52,J52,M52,N52,C54,D54,E54,F54,G54,H54,I54,J54,K54,L54,M54,N54,C55,D55,E55,F55,G55,H55,I55,J55,K55,L55,M55,N55,C56,D56,E56,F56,G56,H56,I56,J56,K56,L56,M56,N56,C57,D57,E57,F57,G57,H57,I57,J57,K57,L57,M57,N57,C58,D58,E58,F58,G58,H58,I58,J58,K58,L58,M58,N58,C59,D59,E59,F59,G59,H59,I59,J59,K59,L59,M59,N59,C61,D61,E61,F61,G61,H61,I61,J61,K61,L61,M61,N61,C70,D70,E70,F70,I70,J70,K70,L70,M70,N70,C71,D71,E71,F71,G71,H71,I71,J71,K71,L71,M71,N71,E72,F72,M72,N72", "style": {"back_color": "#b7e1cd"}}]} - [API 调用] POST https://open.feishu.cn/open-apis/sheets/v4/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/styles/batch_update API 请求失败: 404 Client Error: Not Found for url: https://open.feishu.cn/open-apis/sheets/v4/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/styles/batch_update 错误详情 (text): 404 page not found - 样式更新失败: 404 Client Error: Not Found for url: https://open.feishu.cn/open-apis/sheets/v4/spreadsheets/EYRysBZWkhbA4vts3yLcwitNn1g/styles/batch_update - [计时] 入、合并与上色耗时: 6.6437s 任务完成!请查看飞书文档。 进程已结束,退出代码为 0
11-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值