Files
OMS/app/financebase/view/admin/bill/import.html
chenping 61783b7d01 1. 【新增】售后单售后原因类型支持搜索
2. 【新增】手工创建订单折扣可输入正数

3. 【优化】盘点申请单确认

4. 【修复】采购退货单模拟出库失败问题

5. 【新增】订单金额客户实付与结算金额

6. 【优化】仓库发货统计报表物料名称显示

7. 【优化】自有仓储虚拟发货逻辑

8. 【修复】基础物料分类管理问题
2026-04-01 11:59:17 +08:00

790 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
Copyright 2012-2026 ShopeX (https://www.shopex.cn)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<style>
/* 卡片布局样式 */
.import-cards-container {
padding: 20px;
}
.cards-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.import-card {
border: 1px solid #ddd;
border-radius: 4px;
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
transition: all 0.3s ease;
cursor: pointer;
position: relative;
overflow: hidden;
height: 170px;
display: flex;
flex-direction: column;
}
.import-card:hover {
box-shadow: 0 12px 30px rgba(0,0,0,0.15);
transform: translateY(-8px);
border-color: #155ead;
background: linear-gradient(135deg, #fafbfc 0%, #ffffff 100%);
}
.import-card:hover .card-header {
background: linear-gradient(135deg, #f0f4f8 0%, #f8f9fa 100%);
}
.import-card:hover .platform-icon {
color: #0d47a1;
transform: scale(1.15);
}
.card-header {
padding: 8px 12px;
border-bottom: 1px solid #eee;
background: #f8f9fa;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
height: 30px;
}
.card-header h3 {
margin: 0;
font-size: 12px;
color: #333;
text-align: center;
font-weight: 500;
line-height: 1.2;
}
.card-body {
padding: 16px 20px;
text-align: center;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
height: 110px;
}
.platform-icon {
font-size: 28px;
margin-bottom: 0;
color: #155ead;
transition: all 0.3s ease;
font-weight: 600;
letter-spacing: 0.5px;
}
.card-footer {
padding: 8px 12px;
text-align: left;
border-top: none;
background: transparent;
flex-shrink: 0;
min-height: 30px;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
}
.download-btn {
background: none;
color: #6c757d;
border: none;
padding: 0;
cursor: pointer;
font-size: 11px;
text-decoration: none;
display: inline-block;
transition: color 0.3s ease;
font-weight: 400;
line-height: 1.2;
}
.download-btn:hover {
color: #0056b3;
text-decoration: underline;
}
.download-btn:visited {
color: #6f42c1;
}
.download-btn:active {
color: #0056b3;
}
.template-fields-info {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 12px;
margin: 10px 0;
font-size: 13px;
color: #495057;
line-height: 1.4;
}
.division h4 {
white-space: nowrap;
margin: 0;
}
/* 模态框样式 - 使用系统预设样式 */
.modal {
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 0;
border: 1px solid #888;
width: 90%;
max-width: 800px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.modal-header {
padding: 15px 20px;
background: #fff;
border-bottom: 1px solid #dee2e6;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3 {
margin: 0;
color: #333;
}
.close {
color: #aaa;
font-size: 28px;
font-weight: bold;
cursor: pointer;
line-height: 1;
}
.close:hover {
color: #000;
}
.modal-body {
padding: 20px;
}
/* 自定义文件上传组件样式 */
.custom-file-upload {
position: relative;
display: inline-block;
width: 100%;
max-width: 300px;
}
.custom-file-upload input[type="file"] {
position: absolute;
left: -9999px;
opacity: 0;
width: 0;
height: 0;
}
.custom-file-upload .file-upload-button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
background: #f8f9fa;
border: 2px dashed #dee2e6;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
color: #495057;
text-decoration: none;
min-height: 36px;
width: 100%;
box-sizing: border-box;
}
.custom-file-upload .file-upload-button:hover {
background: #e9ecef;
border-color: #155ead;
color: #155ead;
}
.custom-file-upload .file-upload-button:active {
background: #dee2e6;
transform: translateY(1px);
}
.custom-file-upload .file-upload-icon {
margin-right: 8px;
font-size: 16px;
}
.custom-file-upload .file-upload-text {
flex: 1;
text-align: center;
}
.custom-file-upload .file-name {
margin-top: 8px;
padding: 4px 8px;
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 3px;
font-size: 12px;
color: #6c757d;
text-align: center;
word-break: break-all;
min-height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.custom-file-upload .file-name.has-file {
background: #d4edda;
border-color: #c3e6cb;
color: #155724;
}
.custom-file-upload .file-name.has-file::before {
content: "✓ ";
color: #28a745;
font-weight: bold;
}
/* 账期设置提示样式 */
.period-setting-notice {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 4px;
padding: 12px 16px;
margin-bottom: 20px;
display: flex;
align-items: center;
font-size: 14px;
color: #856404;
}
/* 账期未设置时的卡片样式 */
.period-not-set .import-card {
cursor: pointer;
position: relative;
}
.period-not-set .import-card::after {
content: "点击设置账期";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(220, 53, 69, 0.9);
color: white;
padding: 8px 16px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
z-index: 10;
}
.period-not-set .import-card:hover::after {
opacity: 1;
}
.period-setting-notice .notice-icon {
font-size: 16px;
margin-right: 8px;
}
.period-setting-notice .notice-text {
color: #856404;
}
.period-setting-notice .notice-link {
color: #dc3545;
text-decoration: none;
font-weight: 500;
margin: 0 4px;
padding: 2px 6px;
border-radius: 3px;
transition: all 0.3s ease;
}
.period-setting-notice .notice-link:hover {
background: #dc3545;
color: white;
text-decoration: none;
}
</style>
<!-- ===========================================
HTML结构
=========================================== -->
<div class="import-cards-container">
<!-- 账期设置提示 -->
<{if !$init_time}>
<div class="period-setting-notice">
<span class="notice-icon">⚠️</span>
<span class="notice-text">请先完成</span>
<a href="index.php?app=finance&ctl=setting_init&act=index" target="dialog::{width:550,height:500,resizeable:false,title:'账期设置'}" class="notice-link">账期设置</a>
<span class="notice-text">,然后才能进行账单导入操作</span>
</div>
<{/if}>
<div class="cards-grid <{if !$init_time}>period-not-set<{/if}>">
<{foreach from=$settingTabs item=item}>
<div class="import-card" data-type="<{$item.type}>" data-order="<{$item.order}>">
<div class="card-header">
<h3><{$item.name}></h3>
</div>
<div class="card-body">
<div class="platform-icon"><{$item.icon}></div>
</div>
<div class="card-footer">
<{if is_array($item.template_file)}>
<{foreach from=$item.template_file item=file_path key=link_text}>
<a href="/app/financebase/statics/import/<{$file_path}>" target="_blank" class="download-btn"><{$link_text}></a>
<{/foreach}>
<{else}>
<a href="/app/financebase/statics/import/<{$item.template_file}>" target="_blank" class="download-btn">下载模版</a>
<{/if}>
</div>
</div>
<{/foreach}>
</div>
</div>
<!-- 模态框 -->
<div id="import-modal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<h3 id="modal-title">导入账单</h3>
<span class="close">&times;</span>
</div>
<div class="modal-body">
<div id="import-form-container"></div>
</div>
</div>
</div>
<!-- 隐藏的iframe用于表单提交 -->
<div style="display:none;height:0;overflow:hidden;">
<iframe src='about.html' name='upload' id='uploadframe' class='hide'></iframe>
</div>
<!-- tail.select 库 -->
<link rel="stylesheet" href="/app/desktop/statics/css/tail.select.css">
<script src="/app/desktop/statics/js/tail.select.js"></script>
<script type="text/javascript">
// 平台配置数据
window.platformConfigData = <{$platformConfigJs}>;
// 全局变量
var platformConfig = window.platformConfigData;
var modal = document.getElementById('import-modal');
// ===========================================
// 工具函数
// ===========================================
// 显示错误信息
function showError(message) {
var errorDiv = document.getElementById('allocation-error');
if (errorDiv) {
errorDiv.innerHTML = message;
errorDiv.style.display = 'block';
}
}
// 处理表单提交
function handleFormSubmit(event) {
event.preventDefault();
var form = event.target;
// 检查店铺选择
var shopSelect = form.querySelector('#shop-select');
if (!shopSelect || !shopSelect.value) {
showError('请选择店铺');
return false;
}
// 检查文件选择
var fileInput = form.querySelector('#import-file');
if (!fileInput || !fileInput.value) {
showError('请选择导入文件');
return false;
}
// 清除错误信息
var errorDiv = document.getElementById('allocation-error');
if (errorDiv) {
errorDiv.style.display = 'none';
}
// 创建隐藏的iframe
var iframe = document.createElement('iframe');
iframe.name = 'uploadframe';
iframe.style.display = 'none';
document.body.appendChild(iframe);
// 监听iframe加载完成
iframe.onload = function() {
try {
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
var responseText = iframeDoc.body.innerHTML;
// 解析响应
var response = JSON.parse(responseText);
if (response.error) {
// 显示错误信息
showError(response.error);
} else {
// 成功,关闭模态框
modal.style.display = 'none';
// 可以添加成功提示
alert('导入成功!');
}
} catch (e) {
console.error('解析响应失败:', e);
}
// 清理iframe
document.body.removeChild(iframe);
};
// 设置表单的target并提交
form.target = 'uploadframe';
form.submit();
return false;
};
// ===========================================
// 核心功能函数
// ===========================================
// 生成导入表单
function generateImportForm(type, config, container) {
// 获取文件格式提示
var fileFormat = config.file_format || '.csv、 .xls、 .xlsx';
// 根据文件格式生成accept属性
var acceptTypes = [];
if (fileFormat.includes('.csv')) acceptTypes.push('.csv');
if (fileFormat.includes('.xls')) acceptTypes.push('.xls');
if (fileFormat.includes('.xlsx')) acceptTypes.push('.xlsx');
var acceptAttr = acceptTypes.length > 0 ? 'accept="' + acceptTypes.join(',') + '"' : '';
var formHtml = `
<div id="allocation-error" class="error" style="display:none;"></div>
<form action='index.php?app=financebase&ctl=admin_shop_settlement_import&act=treat' method='post' target="uploadframe" enctype="multipart/form-data" class="tableform modal-form" id="import-form" onsubmit="return handleFormSubmit(event)">
<div class="tableform" id="upload">
<!-- 模板字段说明 -->
${config.template_fields ? '<div class="division"><div class="template-fields-info">' + config.template_fields + '</div></div>' : ''}
<!-- 店铺选择区域 -->
<div class="division">
<table border="0" cellpadding="0" cellspacing="0" class="">
<tr>
<th>选择店铺:</th>
<td style="text-align:left;">
<select name="shop_id" id="shop-select" issearch="fuzzy-search">
<option value="">请选择店铺...</option>
</select>
</td>
</tr>
</table>
</div>
<!-- 文件上传区域 -->
<div class="division">
<table border="0" cellpadding="0" cellspacing="0" class="">
<tr>
<th>导入文件:</th>
<td style="text-align:left;">
<div class="custom-file-upload">
<input type="file" name="import_file" id="import-file" ${acceptAttr}>
<label for="import-file" class="file-upload-button">
<span class="file-upload-icon">[文件]</span>
<span class="file-upload-text">点击选择文件</span>
</label>
<div class="file-name" id="file-name-display">未选择任何文件</div>
</div>
</td>
<td width="">
<h4>上传文件,支持(
<span style='color:red;font-size:16px;'>${fileFormat}</span>
)格式!
</h4>
</td>
</tr>
</table>
</div>
</div>
<!-- 操作按钮 -->
<div class="table-action">
<input type='hidden' name='type' value="${type}"/>
<{if $init_time}>
<button type="submit" id="ImportBtn" class="btn-primary">导入</button>
<{else}>
<a href="index.php?app=finance&ctl=setting_init&act=index" target="dialog::{width:550,height:400,resizeable:false,title:'账期设置'}" class="btn btn-primary" style="margin-right:10px;">请先账单设置</a>
<{/if}>
<button type="button" id="stopBtn" class="btn-secondary">关闭</button>
</div>
<div class="notice-inline">
<span id="iMsg" style="color:red;"></span>
</div>
<div class="error" style="display: none;"></div>
</form>
`;
container.innerHTML = formHtml;
// 重新绑定导入表单事件
bindImportEvents();
// 绑定文件选择事件
bindFileUploadEvents(container);
loadShopList(type, container);
}
// 加载店铺列表
function loadShopList(type, container) {
var config = platformConfig[type];
if (!config) return;
var shopSelect = container.querySelector('#shop-select');
if (!shopSelect) return;
// 发送AJAX请求获取店铺列表
var xhr = new XMLHttpRequest();
var finderId = '<{$finder_id}>' || '';
xhr.open('GET', 'index.php?app=financebase&ctl=admin_shop_settlement_bill&act=getShopList&finder_id=' + finderId + '&type=' + type, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
shopSelect.innerHTML = '<option value="">请选择店铺...</option>' + xhr.responseText;
// 初始化tail.select使用系统默认配置
if (typeof tail !== 'undefined' && tail.select) {
tail.select(shopSelect, {
search: true,
width: 150,
height: 660,
searchMinLength: 0
});
}
}
};
xhr.send();
}
// ===========================================
// 事件绑定
// ===========================================
// 绑定卡片点击事件
function bindCardEvents() {
var cards = document.querySelectorAll('.import-card');
cards.forEach(function(card) {
card.addEventListener('click', function(e) {
// 如果点击的是下载按钮,不触发卡片点击事件
if (e.target.classList.contains('download-btn') || e.target.closest('.download-btn')) {
return;
}
e.preventDefault();
// 检查账期是否已设置
var initTime = <{if $init_time}>true<{else}>false<{/if}>;
console.log('[DEBUG] 检查账期设置状态:', initTime);
if (!initTime) {
console.log('[DEBUG] 账期未设置,准备打开账期设置弹窗...');
// 账期未设置,跳转到账期设置页面
var link = document.createElement('a');
link.href = 'index.php?app=finance&ctl=setting_init&act=index';
link.target = 'dialog::{width:550,height:500,resizeable:false,title:\'账期设置\'}';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
console.log('[DEBUG] 账期设置弹窗已打开');
return;
}
// 账期已设置,正常打开导入弹窗
var type = this.getAttribute('data-type');
var config = platformConfig[type];
if (config) {
document.getElementById('modal-title').textContent = config.name;
generateImportForm(type, config, document.getElementById('import-form-container'));
modal.style.display = 'block';
} else {
console.error('未找到平台配置:', type);
}
});
});
}
// 绑定模态框事件
function bindModalEvents() {
var closeBtn = document.querySelector('.close');
if (closeBtn) {
closeBtn.addEventListener('click', function() {
closeModal();
});
}
// 点击模态框外部关闭
window.addEventListener('click', function(event) {
if (event.target === modal) {
closeModal();
}
});
}
// 关闭模态框
function closeModal() {
modal.style.display = 'none';
}
// 绑定文件上传事件
function bindFileUploadEvents(container) {
var fileInput = container.querySelector('#import-file');
var fileNameDisplay = container.querySelector('#file-name-display');
if (fileInput && fileNameDisplay) {
fileInput.addEventListener('change', function(e) {
var file = e.target.files[0];
if (file) {
// 京东钱包特殊验证
if (fileInput.closest('form').querySelector('input[name="type"]').value === 'jdwallet') {
var fileName = file.name;
var fileExt = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
if (fileExt !== 'xlsx') {
alert('请选择.xlsx格式的Excel文件');
e.target.value = '';
return false;
}
// 检查文件大小限制为50MB
if (file.size > 50 * 1024 * 1024) {
alert('文件大小不能超过50MB');
e.target.value = '';
return false;
}
}
fileNameDisplay.textContent = file.name;
fileNameDisplay.classList.add('has-file');
} else {
fileNameDisplay.textContent = '未选择任何文件';
fileNameDisplay.classList.remove('has-file');
}
});
}
}
// 绑定导入表单事件
function bindImportEvents() {
var stopBtn = document.getElementById('stopBtn');
var importBtn = document.getElementById('ImportBtn');
var importFile = document.getElementById('import-file');
// 取消按钮
if (stopBtn) {
stopBtn.removeEventListener('click', stopBtn.clickHandler);
stopBtn.clickHandler = function() {
try{
var _dialogIns = this.getParent('.dialog').retrieve('instance');
}catch(e){}
if(_dialogIns){
_dialogIns.close();
} else {
closeModal();
}
};
stopBtn.addEventListener('click', stopBtn.clickHandler);
}
// 导入按钮状态管理
if (importBtn && importFile) {
var state = false;
importBtn.addEventListener('click', function(e) {
if (state || !importFile.value.length) return false;
state = true;
this.style.cursor = 'not-allowed';
});
importFile.addEventListener('change', function(e) {
state = false;
importBtn.style.cursor = 'pointer';
});
}
}
// ===========================================
// 初始化
// ===========================================
function init() {
bindCardEvents();
bindModalEvents();
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
</script>