api-workflow-builder / api-functions.js
kenken999's picture
Upload folder using huggingface_hub
69996c8 verified
// Shop11 API Functions
// ページビルダーで作成したページで使用するAPI呼び出し関数
document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Shop11 API Functions loaded');
// すべてのAPIボタンにイベントリスナーを追加
document.addEventListener('click', function(e) {
const action = e.target.getAttribute('data-action');
if (!action) return;
switch(action) {
case 'goldCheckDelete':
goldCheckDelete(e.target);
break;
case 'createSateiTitle':
createSateiTitle(e.target);
break;
case 'sendNotification':
sendNotification(e.target);
break;
case 'searchProduct':
searchProduct(e.target);
break;
case 'loadProductTable':
loadProductTable(e.target);
break;
case 'clearProductTable':
clearProductTable(e.target);
break;
case 'loadCustomerTable':
loadCustomerTable(e.target);
break;
case 'clearCustomerTable':
clearCustomerTable(e.target);
break;
case 'loadSateiTable':
loadSateiTable(e.target);
break;
case 'clearSateiTable':
clearSateiTable(e.target);
break;
case 'registerProduct':
registerProduct(e.target);
break;
}
});
});
// 地金チェック削除
function goldCheckDelete(button) {
const block = button.closest('.shop11-api-block');
const productId = block.querySelector('.gold-product-id').value;
const resultDiv = block.querySelector('.gold-check-result');
if (!productId) {
alert('商品IDを入力してください');
return;
}
resultDiv.style.display = 'block';
resultDiv.innerHTML = '処理中...';
const requestData = { product_id: productId };
fetch('/api/shouhin/gold_check_id_delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || ''
},
body: JSON.stringify(requestData)
})
.then(res => res.json())
.then(data => {
resultDiv.innerHTML = '<pre>' + JSON.stringify(data, null, 2) + '</pre>';
// Supabaseにログ保存
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase(
'地金チェック削除',
'/api/shouhin/gold_check_id_delete',
requestData,
data,
'success'
);
}
})
.catch(err => {
resultDiv.innerHTML = '<span style="color:red;">エラー: ' + err.message + '</span>';
// Supabaseにエラーログ保存
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase(
'地金チェック削除',
'/api/shouhin/gold_check_id_delete',
requestData,
{ error: err.message },
'error'
);
}
});
}
// 査定タイトル生成
function createSateiTitle(button) {
const block = button.closest('.shop11-api-block');
const productId = block.querySelector('.satei-product-id').value;
const resultDiv = block.querySelector('.satei-title-result');
if (!productId) {
alert('商品IDを入力してください');
return;
}
resultDiv.style.display = 'block';
resultDiv.innerHTML = '生成中...';
const endpoint = '/api/satei_func/create_title/' + productId;
const requestData = { product_id: productId };
fetch(endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(data => {
resultDiv.innerHTML = '<strong>タイトル:</strong><br>' + (data.title || JSON.stringify(data, null, 2));
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('査定タイトル生成', endpoint, requestData, data, 'success');
}
})
.catch(err => {
resultDiv.innerHTML = '<span style="color:red;">エラー: ' + err.message + '</span>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('査定タイトル生成', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// メール送信
function sendNotification(button) {
const block = button.closest('.shop11-api-block');
const to = block.querySelector('.mail-to').value;
const subject = block.querySelector('.mail-subject').value;
const body = block.querySelector('.mail-body').value;
const resultDiv = block.querySelector('.mail-result');
if (!to || !subject || !body) {
alert('すべての項目を入力してください');
return;
}
resultDiv.style.display = 'block';
resultDiv.innerHTML = '送信中...';
const endpoint = '/api/notification/mail';
const requestData = { to, subject, body };
fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || ''
},
body: JSON.stringify(requestData)
})
.then(res => res.json())
.then(data => {
resultDiv.innerHTML = '<span style="color:green;">✅ 送信完了</span><br><pre>' + JSON.stringify(data, null, 2) + '</pre>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('メール送信', endpoint, requestData, data, 'success');
}
})
.catch(err => {
resultDiv.innerHTML = '<span style="color:red;">❌ エラー: ' + err.message + '</span>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('メール送信', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// 商品検索
function searchProduct(button) {
const block = button.closest('.shop11-api-block');
const keyword = block.querySelector('.search-keyword').value;
const resultDiv = block.querySelector('.search-result');
if (!keyword) {
alert('検索キーワードを入力してください');
return;
}
resultDiv.style.display = 'block';
resultDiv.innerHTML = '検索中...';
const endpoint = '/api/auto_complete_refasta/ResultSearch?q=' + encodeURIComponent(keyword);
const requestData = { keyword };
fetch(endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(data => {
if (Array.isArray(data) && data.length > 0) {
let html = '<ul style="list-style:none; padding:0;">';
data.forEach(item => {
html += '<li style="padding:10px; border-bottom:1px solid #eee;">' +
(item.label || item.name || JSON.stringify(item)) + '</li>';
});
html += '</ul>';
resultDiv.innerHTML = html;
} else {
resultDiv.innerHTML = '検索結果なし';
}
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品検索', endpoint, requestData, data, 'success');
}
})
.catch(err => {
resultDiv.innerHTML = '<span style="color:red;">エラー: ' + err.message + '</span>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品検索', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// 商品データテーブル読込
function loadProductTable(button) {
const block = button.closest('.shop11-api-block');
const keyword = block.querySelector('.product-search-keyword').value;
const tableBody = block.querySelector('.product-table-body');
const infoDiv = block.querySelector('.product-table-info');
if (!keyword) {
alert('検索キーワードを入力してください');
return;
}
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">🔍 検索中...</td></tr>';
const endpoint = '/api/auto_complete_refasta/ResultSearch?q=' + encodeURIComponent(keyword);
const requestData = { keyword };
fetch(endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(data => {
if (Array.isArray(data) && data.length > 0) {
let html = '';
data.forEach((item, index) => {
html += '<tr>';
html += '<td>' + (item.product_id || item.id || index + 1) + '</td>';
html += '<td>' + (item.label || item.name || item.title || '-') + '</td>';
html += '<td>' + (item.brand || item.maker || '-') + '</td>';
html += '<td>' + (item.category || item.category_name || '-') + '</td>';
html += '<td class="text-right">' + (item.price ? '¥' + parseInt(item.price).toLocaleString() : '-') + '</td>';
html += '<td>' + getStatusBadge(item.status) + '</td>';
html += '<td>' +
'<button class="btn btn-sm btn-info mr-1" onclick="alert(\'商品ID: ' + (item.product_id || item.id) + '\')">📝 詳細</button>' +
'<button class="btn btn-sm btn-warning" onclick="alert(\'編集機能は準備中です\')">✏️ 編集</button>' +
'</td>';
html += '</tr>';
});
tableBody.innerHTML = html;
infoDiv.innerHTML = '<small>✅ ' + data.length + '件の商品が見つかりました</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品データテーブル読込', endpoint, requestData, { count: data.length }, 'success');
}
} else {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-muted">📭 検索結果なし</td></tr>';
infoDiv.innerHTML = '<small>検索結果: 0件</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品データテーブル読込', endpoint, requestData, { count: 0 }, 'success');
}
}
})
.catch(err => {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-danger">❌ エラー: ' + err.message + '</td></tr>';
infoDiv.innerHTML = '<small class="text-danger">データ読込エラー</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品データテーブル読込', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// 商品テーブルクリア
function clearProductTable(button) {
const block = button.closest('.shop11-api-block');
const keyword = block.querySelector('.product-search-keyword');
const tableBody = block.querySelector('.product-table-body');
const infoDiv = block.querySelector('.product-table-info');
keyword.value = '';
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-muted">検索キーワードを入力して検索してください</td></tr>';
infoDiv.innerHTML = '';
}
// ステータスバッジ生成
function getStatusBadge(status) {
if (!status) return '<span class="badge badge-secondary">-</span>';
const statusMap = {
'1': { label: '在庫あり', color: 'success' },
'2': { label: '予約中', color: 'warning' },
'3': { label: '売約済', color: 'danger' },
'4': { label: '出品中', color: 'info' },
'5': { label: '取り下げ', color: 'secondary' }
};
const statusInfo = statusMap[status] || { label: status, color: 'secondary' };
return '<span class="badge badge-' + statusInfo.color + '">' + statusInfo.label + '</span>';
}
// 顧客データテーブル読込
function loadCustomerTable(button) {
const block = button.closest('.shop11-api-block');
const keyword = block.querySelector('.customer-search-keyword').value;
const tableBody = block.querySelector('.customer-table-body');
const infoDiv = block.querySelector('.customer-table-info');
if (!keyword) {
alert('検索キーワードを入力してください');
return;
}
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">🔍 検索中...</td></tr>';
const endpoint = '/api/Eoc/search?keyword=' + encodeURIComponent(keyword);
const requestData = { keyword };
fetch(endpoint, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(data => {
const customers = Array.isArray(data) ? data : (data.data || []);
if (customers.length > 0) {
let html = '';
customers.forEach(customer => {
html += '<tr>';
html += '<td>' + (customer.ecc_id || customer.id || '-') + '</td>';
html += '<td>' + (customer.name1 || customer.name || '-') + '</td>';
html += '<td>' + (customer.tel || customer.phone || '-') + '</td>';
html += '<td>' + (customer.mail1 || customer.email || '-') + '</td>';
html += '<td>' + (customer.zip1 || customer.zip || '-') + '</td>';
html += '<td>' + (customer.address1 || customer.address || '-') + '</td>';
html += '<td>' +
'<button class="btn btn-sm btn-info mr-1" onclick="alert(\'顧客ID: ' + (customer.ecc_id || customer.id) + '\')">📋 詳細</button>' +
'<button class="btn btn-sm btn-primary" onclick="alert(\'編集機能は準備中です\')">✏️ 編集</button>' +
'</td>';
html += '</tr>';
});
tableBody.innerHTML = html;
infoDiv.innerHTML = '<small>✅ ' + customers.length + '件の顧客が見つかりました</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('顧客検索テーブル', endpoint, requestData, { count: customers.length }, 'success');
}
} else {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-muted">📭 検索結果なし</td></tr>';
infoDiv.innerHTML = '<small>検索結果: 0件</small>';
}
})
.catch(err => {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-danger">❌ エラー: ' + err.message + '</td></tr>';
infoDiv.innerHTML = '<small class="text-danger">データ読込エラー</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('顧客検索テーブル', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// 顧客テーブルクリア
function clearCustomerTable(button) {
const block = button.closest('.shop11-api-block');
block.querySelector('.customer-search-keyword').value = '';
block.querySelector('.customer-table-body').innerHTML = '<tr><td colspan="7" class="text-center text-muted">検索キーワードを入力して検索してください</td></tr>';
block.querySelector('.customer-table-info').innerHTML = '';
}
// 査定データテーブル読込
function loadSateiTable(button) {
const block = button.closest('.shop11-api-block');
const keyword = block.querySelector('.satei-search-keyword').value;
const tableBody = block.querySelector('.satei-table-body');
const infoDiv = block.querySelector('.satei-table-info');
if (!keyword) {
alert('検索キーワードを入力してください');
return;
}
tableBody.innerHTML = '<tr><td colspan="7" class="text-center">🔍 検索中...</td></tr>';
const endpoint = '/api/satei/search?keyword=' + encodeURIComponent(keyword);
const requestData = { keyword };
fetch(endpoint, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(data => {
const sateiList = Array.isArray(data) ? data : (data.data || []);
if (sateiList.length > 0) {
let html = '';
sateiList.forEach(satei => {
html += '<tr>';
html += '<td>' + (satei.id || '-') + '</td>';
html += '<td>' + (satei.product_name || satei.title || '-') + '</td>';
html += '<td>' + (satei.customer_name || satei.ecc_name || '-') + '</td>';
html += '<td class="text-right">' + (satei.price ? '¥' + parseInt(satei.price).toLocaleString() : '-') + '</td>';
html += '<td>' + (satei.satei_date || satei.created_at || '-') + '</td>';
html += '<td>' + getSateiStatusBadge(satei.status) + '</td>';
html += '<td>' +
'<button class="btn btn-sm btn-info mr-1" onclick="alert(\'査定ID: ' + (satei.id) + '\')">📋 詳細</button>' +
'<button class="btn btn-sm btn-warning" onclick="alert(\'編集機能は準備中です\')">✏️ 編集</button>' +
'</td>';
html += '</tr>';
});
tableBody.innerHTML = html;
infoDiv.innerHTML = '<small>✅ ' + sateiList.length + '件の査定が見つかりました</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('査定検索テーブル', endpoint, requestData, { count: sateiList.length }, 'success');
}
} else {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-muted">📭 検索結果なし</td></tr>';
infoDiv.innerHTML = '<small>検索結果: 0件</small>';
}
})
.catch(err => {
tableBody.innerHTML = '<tr><td colspan="7" class="text-center text-danger">❌ エラー: ' + err.message + '</td></tr>';
infoDiv.innerHTML = '<small class="text-danger">データ読込エラー</small>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('査定検索テーブル', endpoint, requestData, { error: err.message }, 'error');
}
});
}
// 査定テーブルクリア
function clearSateiTable(button) {
const block = button.closest('.shop11-api-block');
block.querySelector('.satei-search-keyword').value = '';
block.querySelector('.satei-table-body').innerHTML = '<tr><td colspan="7" class="text-center text-muted">検索キーワードを入力して検索してください</td></tr>';
block.querySelector('.satei-table-info').innerHTML = '';
}
// 査定ステータスバッジ
function getSateiStatusBadge(status) {
const statusMap = {
'1': { label: '査定中', color: 'info' },
'2': { label: '査定完了', color: 'success' },
'3': { label: '買取完了', color: 'primary' },
'4': { label: 'キャンセル', color: 'danger' }
};
const statusInfo = statusMap[status] || { label: status || '-', color: 'secondary' };
return '<span class="badge badge-' + statusInfo.color + '">' + statusInfo.label + '</span>';
}
// 商品登録
function registerProduct(button) {
const block = button.closest('.shop11-api-block');
const form = block.querySelector('.product-register-form');
const resultDiv = block.querySelector('.register-result');
const name = block.querySelector('.product-name').value;
const brand = block.querySelector('.product-brand').value;
const category = block.querySelector('.product-category').value;
const price = block.querySelector('.product-price').value;
const description = block.querySelector('.product-description').value;
const status = block.querySelector('.product-status').value;
if (!name || !price) {
alert('商品名と価格は必須です');
return;
}
resultDiv.style.display = 'block';
resultDiv.innerHTML = '💾 登録中...';
const endpoint = '/api/shouhin/register';
const requestData = {
name: name,
brand: brand,
category: category,
price: price,
description: description,
status: status
};
fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || ''
},
body: JSON.stringify(requestData)
})
.then(res => res.json())
.then(data => {
resultDiv.innerHTML = '<div class="alert alert-success">✅ 商品を登録しました!<br>商品ID: ' + (data.product_id || data.id || '不明') + '</div>';
form.reset();
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品登録', endpoint, requestData, data, 'success');
}
})
.catch(err => {
resultDiv.innerHTML = '<div class="alert alert-danger">❌ エラー: ' + err.message + '</div>';
if (window.saveApiLogToSupabase) {
saveApiLogToSupabase('商品登録', endpoint, requestData, { error: err.message }, 'error');
}
});
}