文章目录[隐藏]
手把手教学:为你的网站集成智能合同模板与在线签署流程
引言:数字时代的企业合同管理变革
在当今数字化商业环境中,纸质合同的局限性日益凸显。传统合同签署流程不仅耗时耗力,还存在存储不便、安全性低、管理困难等问题。随着远程办公和电子商务的蓬勃发展,企业对高效、安全、便捷的在线合同签署解决方案的需求日益增长。
WordPress作为全球最流行的内容管理系统,为中小企业和自由职业者提供了强大的网站建设平台。通过代码二次开发,我们可以为WordPress网站集成智能合同模板与在线签署流程,将原本复杂的法律文件处理转化为简单、自动化的在线操作。
本教程将带领您一步步实现这一功能,无需昂贵的第三方服务,通过自主开发打造完全符合您业务需求的智能合同系统。
第一部分:准备工作与环境搭建
1.1 系统需求分析
在开始开发之前,我们需要明确系统的基本功能需求:
- 合同模板管理:创建、编辑、存储可重复使用的合同模板
- 变量替换系统:在模板中插入动态字段(如客户姓名、日期、金额等)
- 在线签署功能:支持多方电子签名,具备法律效力
- 合同状态跟踪:实时监控合同创建、发送、签署、完成等状态
- 安全存储与备份:加密存储已签署合同,防止篡改
- 通知系统:自动邮件通知合同相关方
1.2 开发环境配置
确保您的WordPress环境满足以下条件:
- WordPress 5.0或更高版本
- PHP 7.4或更高版本(推荐8.0+)
- MySQL 5.6或更高版本
- 启用HTTPS(电子签名必需)
- 安装并激活代码编辑器插件(如Code Snippets)
1.3 创建自定义插件
为了避免主题更新导致代码丢失,我们将创建一个独立的插件:
<?php
/**
* Plugin Name: 智能合同管理系统
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站添加智能合同模板与在线签署功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('SCM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SCM_PLUGIN_URL', plugin_dir_url(__FILE__));
define('SCM_VERSION', '1.0.0');
// 初始化插件
require_once SCM_PLUGIN_DIR . 'includes/class-contract-manager.php';
function scm_init() {
$contract_manager = new Contract_Manager();
$contract_manager->init();
}
add_action('plugins_loaded', 'scm_init');
第二部分:数据库设计与合同模板系统
2.1 创建数据库表
我们需要创建几个核心数据库表来存储合同相关数据:
// 在Contract_Manager类中添加数据库创建方法
public function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 合同模板表
$templates_table = $wpdb->prefix . 'scm_templates';
$sql1 = "CREATE TABLE IF NOT EXISTS $templates_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
title varchar(200) NOT NULL,
content longtext NOT NULL,
variables text,
created_by bigint(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
status varchar(20) DEFAULT 'active',
PRIMARY KEY (id)
) $charset_collate;";
// 合同实例表
$contracts_table = $wpdb->prefix . 'scm_contracts';
$sql2 = "CREATE TABLE IF NOT EXISTS $contracts_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
template_id mediumint(9) NOT NULL,
contract_number varchar(100) NOT NULL,
title varchar(200) NOT NULL,
content longtext NOT NULL,
parties text NOT NULL,
variables_values text,
status varchar(50) DEFAULT 'draft',
created_by bigint(20) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
expires_at datetime,
completed_at datetime,
PRIMARY KEY (id),
UNIQUE KEY contract_number (contract_number)
) $charset_collate;";
// 签署记录表
$signatures_table = $wpdb->prefix . 'scm_signatures';
$sql3 = "CREATE TABLE IF NOT EXISTS $signatures_table (
id mediumint(9) NOT NULL AUTO_INCREMENT,
contract_id mediumint(9) NOT NULL,
party_email varchar(200) NOT NULL,
party_name varchar(200) NOT NULL,
signature_data text,
signed_at datetime,
ip_address varchar(45),
user_agent text,
verification_hash varchar(255),
PRIMARY KEY (id),
KEY contract_id (contract_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql1);
dbDelta($sql2);
dbDelta($sql3);
}
2.2 合同模板编辑器
创建合同模板管理界面,允许用户通过可视化编辑器创建模板:
// 添加模板编辑器短代码
public function add_template_editor_shortcode() {
add_shortcode('contract_template_editor', array($this, 'render_template_editor'));
}
public function render_template_editor() {
// 检查用户权限
if (!current_user_can('manage_options')) {
return '<p>您没有权限访问此功能。</p>';
}
ob_start();
?>
<div class="scm-template-editor">
<h2>智能合同模板编辑器</h2>
<div class="scm-editor-container">
<div class="scm-sidebar">
<h3>可用变量</h3>
<div class="variable-list">
<div class="variable-item" data-variable="{client_name}">
<span class="variable-label">客户姓名</span>
<code>{client_name}</code>
</div>
<div class="variable-item" data-variable="{client_email}">
<span class="variable-label">客户邮箱</span>
<code>{client_email}</code>
</div>
<div class="variable-item" data-variable="{contract_date}">
<span class="variable-label">合同日期</span>
<code>{contract_date}</code>
</div>
<div class="variable-item" data-variable="{amount}">
<span class="variable-label">金额</span>
<code>{amount}</code>
</div>
<div class="variable-item" data-variable="{service_description}">
<span class="variable-label">服务描述</span>
<code>{service_description}</code>
</div>
<div class="variable-item" data-variable="{terms}">
<span class="variable-label">条款</span>
<code>{terms}</code>
</div>
</div>
<button type="button" class="button button-primary" id="add-custom-variable">
添加自定义变量
</button>
</div>
<div class="scm-editor-main">
<div class="form-group">
<label for="template-title">模板标题</label>
<input type="text" id="template-title" class="widefat" placeholder="输入模板标题">
</div>
<div class="form-group">
<label for="template-content">模板内容</label>
<?php
// 使用WordPress编辑器
wp_editor('', 'template-content', array(
'textarea_name' => 'template_content',
'editor_height' => 400,
'media_buttons' => false,
'tinymce' => array(
'toolbar1' => 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,undo,redo'
)
));
?>
</div>
<div class="form-actions">
<button type="button" class="button button-primary" id="save-template">
保存模板
</button>
<button type="button" class="button" id="preview-template">
预览合同
</button>
</div>
</div>
</div>
<div id="template-preview-modal" class="scm-modal" style="display:none;">
<div class="scm-modal-content">
<span class="scm-close-modal">×</span>
<h3>合同预览</h3>
<div id="preview-content"></div>
</div>
</div>
</div>
<style>
.scm-template-editor {
max-width: 1200px;
margin: 20px auto;
background: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.scm-editor-container {
display: flex;
gap: 20px;
margin-top: 20px;
}
.scm-sidebar {
width: 300px;
background: #f5f5f5;
padding: 15px;
border-radius: 5px;
}
.scm-editor-main {
flex: 1;
}
.variable-list {
margin-bottom: 20px;
}
.variable-item {
background: #fff;
padding: 10px;
margin-bottom: 8px;
border-radius: 4px;
border-left: 4px solid #0073aa;
cursor: pointer;
transition: all 0.3s;
}
.variable-item:hover {
background: #e3f2fd;
transform: translateX(5px);
}
.variable-item code {
display: block;
margin-top: 5px;
padding: 3px 6px;
background: #f1f1f1;
border-radius: 3px;
font-size: 12px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.scm-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.scm-modal-content {
background: #fff;
width: 80%;
max-width: 900px;
max-height: 80vh;
overflow-y: auto;
padding: 20px;
border-radius: 5px;
position: relative;
}
.scm-close-modal {
position: absolute;
top: 15px;
right: 20px;
font-size: 24px;
cursor: pointer;
}
</style>
<script>
jQuery(document).ready(function($) {
// 插入变量到编辑器
$('.variable-item').click(function() {
var variable = $(this).data('variable');
var editor = tinyMCE.get('template-content');
if (editor) {
editor.insertContent(variable);
} else {
var textarea = $('#template-content');
var currentVal = textarea.val();
var cursorPos = textarea.prop('selectionStart');
var newVal = currentVal.substring(0, cursorPos) + variable +
currentVal.substring(cursorPos);
textarea.val(newVal);
}
});
// 保存模板
$('#save-template').click(function() {
var title = $('#template-title').val();
var content = '';
if (tinyMCE.get('template-content')) {
content = tinyMCE.get('template-content').getContent();
} else {
content = $('#template-content').val();
}
if (!title || !content) {
alert('请填写模板标题和内容');
return;
}
// 提取变量
var variables = [];
var regex = /{([^}]+)}/g;
var match;
while ((match = regex.exec(content)) !== null) {
if (variables.indexOf(match[1]) === -1) {
variables.push(match[1]);
}
}
$.ajax({
url: '<?php echo admin_url("admin-ajax.php"); ?>',
type: 'POST',
data: {
action: 'scm_save_template',
title: title,
content: content,
variables: JSON.stringify(variables),
nonce: '<?php echo wp_create_nonce("scm_save_template_nonce"); ?>'
},
success: function(response) {
if (response.success) {
alert('模板保存成功!');
window.location.reload();
} else {
alert('保存失败:' + response.data);
}
}
});
});
// 预览合同
$('#preview-template').click(function() {
var content = '';
if (tinyMCE.get('template-content')) {
content = tinyMCE.get('template-content').getContent();
} else {
content = $('#template-content').val();
}
if (!content) {
alert('请先输入模板内容');
return;
}
// 替换变量为示例值
var previewContent = content
.replace(/{client_name}/g, '<span class="variable-example">张三</span>')
.replace(/{client_email}/g, '<span class="variable-example">zhangsan@example.com</span>')
.replace(/{contract_date}/g, '<span class="variable-example">' + new Date().toLocaleDateString() + '</span>')
.replace(/{amount}/g, '<span class="variable-example">¥5,000.00</span>')
.replace(/{service_description}/g, '<span class="variable-example">网站设计与开发服务</span>')
.replace(/{terms}/g, '<span class="variable-example">30天内完成所有工作</span>');
$('#preview-content').html(previewContent);
$('#template-preview-modal').show();
});
// 关闭模态框
$('.scm-close-modal').click(function() {
$('#template-preview-modal').hide();
});
// 点击模态框外部关闭
$(window).click(function(event) {
if ($(event.target).hasClass('scm-modal')) {
$('.scm-modal').hide();
}
});
});
</script>
<?php
return ob_get_clean();
}
第三部分:合同创建与变量替换系统
3.1 合同创建界面
创建用户友好的合同创建界面,允许用户选择模板并填写变量值:
// 添加合同创建短代码
public function add_contract_creator_shortcode() {
add_shortcode('create_contract', array($this, 'render_contract_creator'));
}
public function render_contract_creator() {
global $wpdb;
// 获取可用模板
$templates_table = $wpdb->prefix . 'scm_templates';
$templates = $wpdb->get_results(
"SELECT id, title FROM $templates_table WHERE status = 'active' ORDER BY title"
);
ob_start();
?>
<div class="scm-contract-creator">
<h2>创建新合同</h2>
<div class="scm-form-container">
<div class="form-step" id="step1">
<h3>步骤1:选择合同模板</h3>
<div class="template-grid">
<?php if ($templates): ?>
<?php foreach ($templates as $template): ?>
<div class="template-card" data-template-id="<?php echo $template->id; ?>">
<h4><?php echo esc_html($template->title); ?></h4>
<button type="button" class="button select-template"
data-template-id="<?php echo $template->id; ?>">
选择此模板
</button>
</div>
<?php endforeach; ?>
<?php else: ?>
<p>暂无可用模板。请先创建合同模板。</p>
<?php endif; ?>
</div>
</div>
<div class="form-step" id="step2" style="display:none;">
<h3>步骤2:填写合同信息</h3>
<form id="contract-details-form">
<div id="dynamic-fields-container">
<!-- 动态字段将在这里生成 -->
</div>
<div class="form-section">
<h4>签署方信息</h4>
<div class="party-section">
<h5>甲方(我方)</h5>
<div class="form-row">
<div class="form-group">
<label>公司/个人名称</label>
<input type="text" name="party_a_name" required
value="<?php echo get_bloginfo('name'); ?>">
</div>
<div class="form-group">
<label>电子邮箱</label>
<input type="email" name="party_a_email" required
value="<?php echo get_option('admin_email'); ?>">
</div>
</div>
</div>
<div class="party-section">
<h5>乙方(客户)</h5>
<div class="form-row">
<div class="form-group">
<label>客户姓名</label>
<input type="text" name="party_b_name" required>
</div>
<div class="form-group">
</div>
<div class="form-group">
<label>客户邮箱</label>
<input type="email" name="party_b_email" required>
</div>
</div>
<button type="button" class="button button-secondary" id="add-party">
添加更多签署方
</button>
</div>
</div>
<div class="form-actions">
<button type="button" class="button" id="back-to-step1">
返回上一步
</button>
<button type="submit" class="button button-primary">
生成合同并发送
</button>
</div>
</form>
</div>
<div class="form-step" id="step3" style="display:none;">
<h3>合同创建成功!</h3>
<div class="success-message">
<p>合同已成功创建并发送给相关签署方。</p>
<p>合同编号:<strong id="contract-number"></strong></p>
<p>您可以在 <a href="#" id="contract-management-link">合同管理页面</a> 跟踪签署状态。</p>
</div>
</div>
</div>
</div>
<style>
.scm-contract-creator {
max-width: 1000px;
margin: 20px auto;
background: #fff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
.template-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
margin-top: 20px;
}
.template-card {
background: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 8px;
padding: 20px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
}
.template-card:hover {
border-color: #0073aa;
transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,115,170,0.1);
}
.template-card h4 {
margin-top: 0;
color: #333;
min-height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.form-step {
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.form-section {
background: #f8f9fa;
padding: 20px;
border-radius: 6px;
margin: 25px 0;
}
.form-section h4 {
margin-top: 0;
color: #0073aa;
border-bottom: 2px solid #dee2e6;
padding-bottom: 10px;
}
.party-section {
margin-bottom: 25px;
}
.party-section h5 {
color: #495057;
margin-bottom: 15px;
font-size: 16px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #495057;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 14px;
transition: border-color 0.3s;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
border-color: #0073aa;
outline: none;
box-shadow: 0 0 0 3px rgba(0,115,170,0.1);
}
.form-actions {
display: flex;
justify-content: space-between;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #dee2e6;
}
.success-message {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
padding: 20px;
border-radius: 6px;
text-align: center;
}
.success-message p {
margin: 10px 0;
font-size: 16px;
}
.dynamic-field-group {
background: #fff;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 15px;
margin-bottom: 15px;
}
.dynamic-field-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #495057;
}
.dynamic-field-group .field-description {
font-size: 12px;
color: #6c757d;
margin-top: 5px;
font-style: italic;
}
</style>
<script>
jQuery(document).ready(function($) {
var selectedTemplateId = null;
var templateVariables = [];
// 选择模板
$('.select-template').click(function() {
selectedTemplateId = $(this).data('template-id');
// 获取模板变量
$.ajax({
url: '<?php echo admin_url("admin-ajax.php"); ?>',
type: 'POST',
data: {
action: 'scm_get_template_variables',
template_id: selectedTemplateId,
nonce: '<?php echo wp_create_nonce("scm_get_variables_nonce"); ?>'
},
success: function(response) {
if (response.success) {
templateVariables = response.data.variables;
renderDynamicFields(templateVariables);
$('#step1').hide();
$('#step2').show();
} else {
alert('获取模板信息失败');
}
}
});
});
// 渲染动态字段
function renderDynamicFields(variables) {
var container = $('#dynamic-fields-container');
container.empty();
if (variables.length === 0) {
container.html('<p>此模板没有需要填写的变量。</p>');
return;
}
container.html('<h4>合同变量填写</h4>');
variables.forEach(function(variable) {
var fieldHtml = `
<div class="dynamic-field-group">
<label for="var_${variable}">${formatVariableName(variable)}</label>
`;
// 根据变量名猜测字段类型
if (variable.includes('date') || variable.includes('Date')) {
fieldHtml += `
<input type="date" id="var_${variable}"
name="variables[${variable}]" required>
<div class="field-description">请选择日期</div>
`;
} else if (variable.includes('amount') || variable.includes('price') ||
variable.includes('金额') || variable.includes('价格')) {
fieldHtml += `
<input type="number" id="var_${variable}"
name="variables[${variable}]" step="0.01" min="0" required>
<div class="field-description">请输入金额(单位:元)</div>
`;
} else if (variable.includes('description') || variable.includes('content') ||
variable.includes('描述') || variable.includes('内容')) {
fieldHtml += `
<textarea id="var_${variable}" name="variables[${variable}]"
rows="3" required></textarea>
<div class="field-description">请详细描述</div>
`;
} else if (variable.includes('email') || variable.includes('邮箱')) {
fieldHtml += `
<input type="email" id="var_${variable}"
name="variables[${variable}]" required>
<div class="field-description">请输入有效的邮箱地址</div>
`;
} else {
fieldHtml += `
<input type="text" id="var_${variable}"
name="variables[${variable}]" required>
<div class="field-description">请填写${formatVariableName(variable)}</div>
`;
}
fieldHtml += '</div>';
container.append(fieldHtml);
});
}
// 格式化变量名显示
function formatVariableName(variable) {
// 移除花括号
var name = variable.replace(/[{}]/g, '');
// 将下划线或连字符转换为空格
name = name.replace(/[_-]/g, ' ');
// 首字母大写
return name.replace(/bw/g, function(l) { return l.toUpperCase(); });
}
// 返回上一步
$('#back-to-step1').click(function() {
$('#step2').hide();
$('#step1').show();
});
// 添加更多签署方
$('#add-party').click(function() {
var partyCount = $('.party-section').length - 2; // 减去甲方和乙方
if (partyCount >= 3) {
alert('最多支持5个签署方');
return;
}
var partyLetter = String.fromCharCode(67 + partyCount); // C, D, E...
var partyHtml = `
<div class="party-section additional-party">
<h5>${partyLetter}方</h5>
<div class="form-row">
<div class="form-group">
<label>签署方名称</label>
<input type="text" name="party_${partyLetter.toLowerCase()}_name" required>
</div>
<div class="form-group">
<label>签署方邮箱</label>
<input type="email" name="party_${partyLetter.toLowerCase()}_email" required>
</div>
</div>
<button type="button" class="button button-small remove-party">
移除此签署方
</button>
</div>
`;
$(this).before(partyHtml);
});
// 移除签署方
$(document).on('click', '.remove-party', function() {
$(this).closest('.party-section').remove();
});
// 提交合同表单
$('#contract-details-form').submit(function(e) {
e.preventDefault();
// 收集表单数据
var formData = $(this).serializeArray();
var variables = {};
// 提取变量数据
formData.forEach(function(item) {
if (item.name.startsWith('variables[')) {
var varName = item.name.match(/[(.*?)]/)[1];
variables[varName] = item.value;
}
});
// 收集签署方信息
var parties = [];
$('input[name^="party_"]').each(function() {
var name = $(this).attr('name');
var value = $(this).val();
if (name.endsWith('_name')) {
var partyKey = name.replace('_name', '');
var partyIndex = parties.findIndex(p => p.key === partyKey);
if (partyIndex === -1) {
parties.push({
key: partyKey,
name: value,
email: ''
});
} else {
parties[partyIndex].name = value;
}
} else if (name.endsWith('_email')) {
var partyKey = name.replace('_email', '');
var partyIndex = parties.findIndex(p => p.key === partyKey);
if (partyIndex === -1) {
parties.push({
key: partyKey,
name: '',
email: value
});
} else {
parties[partyIndex].email = value;
}
}
});
// 发送AJAX请求创建合同
$.ajax({
url: '<?php echo admin_url("admin-ajax.php"); ?>',
type: 'POST',
data: {
action: 'scm_create_contract',
template_id: selectedTemplateId,
variables: JSON.stringify(variables),
parties: JSON.stringify(parties),
nonce: '<?php echo wp_create_nonce("scm_create_contract_nonce"); ?>'
},
beforeSend: function() {
$('.form-actions button').prop('disabled', true).text('处理中...');
},
success: function(response) {
if (response.success) {
$('#contract-number').text(response.data.contract_number);
$('#contract-management-link').attr('href', response.data.management_url);
$('#step2').hide();
$('#step3').show();
} else {
alert('创建合同失败:' + response.data);
$('.form-actions button').prop('disabled', false).text('生成合同并发送');
}
},
error: function() {
alert('网络错误,请重试');
$('.form-actions button').prop('disabled', false).text('生成合同并发送');
}
});
});
});
</script>
<?php
return ob_get_clean();
}
### 3.2 变量替换与合同生成逻辑
实现合同内容的变量替换和最终合同生成:
// 处理AJAX请求:创建合同
public function ajax_create_contract() {
check_ajax_referer('scm_create_contract_nonce', 'nonce');
if (!current_user_can('edit_posts')) {
wp_die('权限不足');
}
global $wpdb;
$template_id = intval($_POST['template_id']);
$variables = json_decode(stripslashes($_POST['variables']), true);
$parties = json_decode(stripslashes($_POST['parties']), true);
// 获取模板内容
$templates_table = $wpdb->prefix . 'scm_templates';
$template = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $templates_table WHERE id = %d",
$template_id
));
if (!$template) {
wp_send_json_error('模板不存在');
}
// 生成合同编号
$contract_number = 'CONTRACT-' . date('Ymd') . '-' . strtoupper(wp_generate_password(6, false));
// 替换变量
$contract_content = $template->content;
foreach ($variables as $key => $value) {
$placeholder = '{' . $key . '}';
$contract_content = str_replace($placeholder, $value, $contract_content);
}
// 添加标准条款
$standard_terms = $this->get_standard_terms();
$contract_content .= $standard_terms;
// 保存合同到数据库
$contracts_table = $wpdb->prefix . 'scm_contracts';
$wpdb->insert(
$contracts_table,
array(
'template_id' => $template_id,
'contract_number' => $contract_number,
'title' => $template->title,
'content' => $contract_content,
'parties' => json_encode($parties, JSON_UNESCAPED_UNICODE),
'variables_values' => json_encode($variables, JSON_UNESCAPED_UNICODE),
'status' => 'pending',
'created_by' => get_current_user_id(),
'expires_at' => date('Y-m-d H:i:s', strtotime('+30 days'))
),
array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s')
);
$contract_id = $wpdb->insert_id;
// 创建签署记录
$signatures_table = $wpdb->prefix . 'scm_signatures';
foreach ($parties as $party) {
$wpdb->insert(
$signatures_table,
array(
'contract_id' => $contract_id,
'party_email' => $party['email'],
'party_name' => $party['name'],
'verification_hash' => wp_hash($contract_id . $party['email'] . time())
),
array('%d', '%s', '%s', '%s')
);
}
// 发送签署邀请邮件
$this->send_signature_invitations($contract_id);
// 返回成功响应
wp_send_json_success(array(
'contract_number' => $contract_number,
'contract_id' => $contract_id,
'management_url' => home_url('/contract-management/')
));
}
// 获取标准条款
private function get_standard_terms() {
return '
<div class="standard-terms">
<h3>标准条款与条件</h3>
<ol>
<li><strong>电子签名有效性</strong>:本文件使用电子签名,根据《中华人民共和国电子签名法》规定,可靠的电子签名与手写签名或者盖章具有同等的法律效力。</li>
<li><strong>合同生效</strong>:本合同自所有签署方完成电子签名之日起生效。</li>
<li><strong>合同修改</strong>:任何对本合同的修改必须以书面形式(包括电子形式)进行,并经所有签署方同意。</li>
<li><strong>争议解决</strong>:因本合同引起的或与本合同有关的任何争议,双方应友好协商解决;协商不成的,任何一方均有权向合同签订地有管辖权的人民法院提起诉讼。</li>
<li><strong>完整性</strong>:本合同构成双方就本合同标的达成的完整协议,取代所有先前口头或书面的沟通、陈述或协议。</li>
</ol>
<div class="signature-disclaimer">
<p><
