소스 정보
- 저장소
- nagucc/rdb2wedoc
- 최근 소스 활동
- 2026년 2월 1일 06:32
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 0
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/nagucc/rdb2wedoc --skill wecom-smartsheet-add-records명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | wecom-smartsheet-add-records |
| description | 提供企业微信智能表格添加记录的正确操作方法,包括不同数据类型的处理格式。当需要与企业微信智能表格进行数据同步时调用。 |
本skill提供了企业微信智能表格添加记录的正确操作方法,确保不同数据类型(数字、日期、文本等)都能按照企业微信API的要求正确处理。
import axios, { AxiosInstance } from 'axios';
import { WeComDocument, DocumentSheet, DocumentField, WeComAccount } from '@/types';
import { getWeComAccountById } from '@/lib/config/storage';
import { Logger } from '../utils/helpers';
export class WeComDocumentService {
private client: AxiosInstance;
constructor() {
this.client = axios.create({
baseURL: 'https://qyapi.weixin.qq.com',
timeout: 60000,
headers: {
'Content-Type': 'application/json'
}
});
}
async getAccessToken(corpid: string, corpsecret: string): Promise<string> {
try {
const response = await this.client.get('/cgi-bin/gettoken', {
params: {
corpid,
corpsecret
}
});
if (response.data.errcode !== 0) {
throw new Error(`获取access_token失败: ${response.data.errmsg}`);
}
return response.data.access_token;
} catch (error) {
Logger.error('获取企业微信access_token失败', { error: (error as Error).message });
throw error;
}
}
async writeSheetData(
accessToken: string,
documentId: string,
sheetId: string,
data: any[],
fieldTypeMap?: Map<string, string>
): Promise<boolean> {
try {
const records = data.map(row => {
const values: any = {};
Object.keys(row).forEach(key => {
const value = row[key];
if (value !== null && value !== undefined) {
// 根据目标字段类型设置正确的数据类型
const fieldType = fieldTypeMap?.get(key);
if (fieldType === 'number' || fieldType === 'currency' || fieldType === 'percentage') {
// 数字类型直接使用数值
values[key] = Number(value);
} else if (fieldType === 'boolean') {
// 布尔类型直接使用布尔值
values[key] = Boolean(value);
} else if (fieldType === 'datetime') {
// 日期类型使用毫秒时间戳
values[key] = new Date(value).getTime().toString();
} else if (fieldType === 'text' || fieldType === 'url' || fieldType === 'phone' || fieldType === 'email' || fieldType === 'select' || fieldType === 'multi_select' || fieldType === 'user' || fieldType === 'group' || fieldType === 'location' || fieldType === 'formula' || fieldType === 'reference' || fieldType === 'barcode') {
// 文本类型使用对象数组形式
values[key] = [{
type: 'text',
text: String(value)
}];
} else {
// 其他类型默认使用文本形式
values[key] = [{
type: 'text',
text: String(value)
}];
}
}
});
return { values };
});
const response = await this.client.post('/cgi-bin/wedoc/smartsheet/add_records', {
docid: documentId,
sheet_id: sheetId,
key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',
records: records
}, {
params: {
access_token: accessToken
}
});
if (response.data.errcode !== 0) {
throw new Error(`写入Sheet数据失败: ${response.data.errmsg}`);
}
return true;
} catch (error) {
Logger.error('写入Sheet数据失败', { error: (error as Error).message });
throw error;
}
}
async appendSheetData(
accessToken: string,
documentId: string,
sheetId: string,
data: any[],
fieldTypeMap?: Map<string, string>
): Promise<boolean> {
try {
const records = data.map(row => {
const values: any = {};
Object.keys(row).forEach(key => {
const value = row[key];
if (value !== null && value !== undefined) {
// 根据目标字段类型设置正确的数据类型
const fieldType = fieldTypeMap?.get(key);
if (fieldType === 'number' || fieldType === 'currency' || fieldType === 'percentage') {
// 数字类型直接使用数值
values[key] = Number(value);
} else if (fieldType === 'boolean') {
// 布尔类型直接使用布尔值
values[key] = Boolean(value);
} else if (fieldType === 'datetime') {
// 日期类型使用毫秒时间戳
values[key] = new Date(value).getTime().toString();
} else if (fieldType === 'text' || fieldType === 'url' || fieldType === 'phone' || fieldType === 'email' || fieldType === 'select' || fieldType === 'multi_select' || fieldType === 'user' || fieldType === 'group' || fieldType === 'location' || fieldType === 'formula' || fieldType === 'reference' || fieldType === 'barcode') {
// 文本类型使用对象数组形式
values[key] = [{
type: 'text',
text: String(value)
}];
} else {
// 其他类型默认使用文本形式
values[key] = [{
type: 'text',
text: String(value)
}];
}
}
});
return { values };
});
const response = await this.client.post('/cgi-bin/wedoc/smartsheet/add_records', {
docid: documentId,
sheet_id: sheetId,
key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',
records: records
}, {
params: {
access_token: accessToken
}
});
if (response.data.errcode !== 0) {
throw new Error(`追加Sheet数据失败: ${response.data.errmsg}`);
}
return true;
} catch (error) {
Logger.error('追加Sheet数据失败', { error: (error as Error).message });
throw error;
}
}
// 其他方法...
}
// 单例模式
export const weComDocumentService = new WeComDocumentService();
private mapFieldType(fieldType: string): string {
const typeMap: Record<string, string> = {
'FIELD_TYPE_TEXT': 'text',
'FIELD_TYPE_NUMBER': 'number',
'FIELD_TYPE_CHECKBOX': 'boolean',
'FIELD_TYPE_DATE_TIME': 'datetime',
'FIELD_TYPE_IMAGE': 'image',
'FIELD_TYPE_ATTACHMENT': 'file',
'FIELD_TYPE_USER': 'user',
'FIELD_TYPE_URL': 'url',
'FIELD_TYPE_SELECT': 'multi_select',
'FIELD_TYPE_CREATED_USER': 'user',
'FIELD_TYPE_MODIFIED_USER': 'user',
'FIELD_TYPE_CREATED_TIME': 'datetime',
'FIELD_TYPE_MODIFIED_TIME': 'datetime',
'FIELD_TYPE_PROGRESS': 'number',
'FIELD_TYPE_PHONE_NUMBER': 'phone',
'FIELD_TYPE_EMAIL': 'email',
'FIELD_TYPE_SINGLE_SELECT': 'select',
'FIELD_TYPE_REFERENCE': 'reference',
'FIELD_TYPE_LOCATION': 'location',
'FIELD_TYPE_FORMULA': ,
: ,
: ,
: ,
: ,
:
};
typeMap[fieldType] || ;
}
| 字段类型 | 处理方式 | 示例 |
|---|---|---|
| number, currency, percentage | 直接使用数值 | 123.45 |
| boolean | 直接使用布尔值 | true |
| datetime | 使用毫秒时间戳字符串 | 1674835200000 |
| text, url, phone, email, select, multi_select, user, group, location, formula, reference, barcode | 使用对象数组形式 | [{ type: 'text', text: 'Hello' }] |
| 其他类型 | 默认使用文本形式 | [{ type: 'text', text: 'Other' }] |
import { weComDocumentService } from '@/lib/services/wecom-document.service';
// 获取access token
const accessToken = await weComDocumentService.getAccessToken(corpId, corpSecret);
// 准备数据
const data = [
{
'姓名': '张三',
'年龄': 25,
'入职日期': '2023-01-01',
'是否在职': true,
'邮箱': 'zhangsan@example.com'
},
{
'姓名': '李四',
'年龄': 30,
'入职日期': '2022-06-01',
'是否在职': true,
'邮箱': 'lisi@example.com'
}
];
// 准备字段类型映射
const fieldTypeMap = new Map<string, string>();
fieldTypeMap.set('姓名', 'text');
fieldTypeMap.set('年龄', 'number');
fieldTypeMap.set('入职日期', 'datetime');
fieldTypeMap.set('是否在职', 'boolean');
fieldTypeMap.set('邮箱', 'email');
// 写入数据
weComDocumentService.(
accessToken,
documentId,
sheetId,
data,
fieldTypeMap
);
private async overwriteToDocument(document: WeComDocument, sheetId: string, data: any[], fieldTypeMap?: Map<string, string>): Promise<void> {
const account = getWeComAccountById(document.accountId);
if (!account) {
throw new Error(`关联的企业微信账号不存在,accountId: ${document.accountId}`);
}
const accessToken = await weComDocumentService.getAccessToken(account.corpId, account.corpSecret);
if (!accessToken) {
throw new Error(`获取企业微信access token失败, corpId: ${account.corpId}`);
}
await weComDocumentService.clearSheetData(accessToken, document.id, sheetId);
await weComDocumentService.writeSheetData(accessToken, document.id, sheetId, data, fieldTypeMap);
}
private async appendToDocument(document: , : , : [], ?: <, >): <> {
account = (.);
(!account) {
();
}
accessToken = weComDocumentService.(account., account.);
(!accessToken) {
();
}
weComDocumentService.(accessToken, ., sheetId, data, fieldTypeMap);
}
字段类型映射:确保正确获取目标表格的字段类型,并使用fieldTypeMap传递给写入方法。
空值处理:代码会自动跳过null和undefined值,避免向智能表格写入空值。
日期处理:日期类型需要转换为毫秒时间戳字符串,确保企业微信能正确识别。
文本类型:文本类型必须使用对象数组形式[{ type: 'text', text: 'value' }],这是企业微信API的要求。
数字类型:数字类型直接使用数值,不需要转换为字符串。
布尔类型:布尔类型直接使用布尔值,不需要转换。
API参数:使用add_records接口时,需要设置key_type: 'CELL_VALUE_KEY_TYPE_FIELD_TITLE',表示使用字段标题作为键。
错误处理:添加适当的错误处理,捕获并记录API调用失败的情况。
文本字段同步失败:检查是否使用了正确的对象数组形式。
日期字段显示不正确:确保日期值已转换为毫秒时间戳字符串。
数字字段不显示:检查是否直接使用了数值,而不是字符串。
API调用失败:检查access token是否有效,文档和表格ID是否正确。
预获取字段类型:在同步前先获取目标表格的字段类型,确保数据类型处理正确。
批量操作:对于大量数据,使用批量添加接口,减少API调用次数。
错误重试:添加错误重试机制,提高同步的可靠性。
日志记录:记录同步过程中的关键信息和错误,便于排查问题。
数据验证:在同步前验证数据格式,确保数据符合目标字段的要求。
类型转换:根据目标字段类型自动转换数据格式,提高同步的准确性。
边界情况处理:处理空值、特殊字符等边界情况,确保同步过程稳定。
性能优化:对于大数据量的同步,考虑分批处理,避免超时或内存溢出。