1. 【新增】售后单售后原因类型支持搜索

2. 【新增】手工创建订单折扣可输入正数

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

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

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

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

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

8. 【修复】基础物料分类管理问题
This commit is contained in:
chenping
2026-04-01 11:59:17 +08:00
parent 9341122827
commit 61783b7d01
754 changed files with 46179 additions and 5700 deletions

View File

@@ -14,15 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class desktop_ctl_export extends desktop_controller{
/**
* __construct
* @param mixed $app app
* @return mixed 返回值
*/
public function __construct($app)
{
parent::__construct($app);
@@ -33,6 +27,7 @@ class desktop_ctl_export extends desktop_controller{
$exptempObj = app::get('desktop')->model('export_template');
$temps =$exptempObj->getList('et_id,et_name',array('et_type'=>$type),0,-1);
$this->pagedata['temps'] = $temps;
$this->pagedata['type'] = $type;
return $this->display("export/template.html");
}
@@ -74,4 +69,27 @@ class desktop_ctl_export extends desktop_controller{
$this->pagedata['need_detail'] = $curr_filter['need_detail'];
return $this->display("export/templatedetail.html");
}
}
/**
* 删除指定的导出模板
*
* @return void
*/
function deleteTemp(){
$this->begin('javascript:location.reload();');
$et_id = $_POST['et_id'];
if(empty($et_id)){
$this->end(false, '模板ID不能为空');
}
$exptempObj = app::get('desktop')->model('export_template');
$result = $exptempObj->delete(array('et_id'=>$et_id));
if($result){
$this->end(true, '删除成功');
}else{
$this->end(false, '删除失败');
}
}
}

View File

@@ -35,10 +35,17 @@ class desktop_ctl_rpcnotify extends desktop_controller{
}//End Function
function index(){
// 清除三个月前的通知直接用SQL执行
$threeMonthsAgo = strtotime('-3 months');
$db = kernel::database();
$table = app::get('base')->model('rpcnotify')->table_name(true);
$sql = "DELETE FROM {$table} WHERE notifytime < {$threeMonthsAgo}";
$db->exec($sql);
$this->finder('base_mdl_rpcnotify',array(
'title'=>app::get('desktop')->_('消息通知'),
'actions'=>array(
array('label'=>app::get('desktop')->_('标记为未读'), 'id'=>'id-rpcynotify-submit', 'submit'=>'index.php?ctl=rpcnotify&act=unread'),
array('label'=>app::get('desktop')->_('标记为已读'), 'id'=>'id-rpcynotify-submit', 'submit'=>'index.php?ctl=rpcnotify&act=read'),
),
'use_buildin_recycle' => false,
@@ -80,12 +87,45 @@ class desktop_ctl_rpcnotify extends desktop_controller{
$cacheInfo[$infoKey]['status'] = 'true';
cachecore::store('system_notice_data', $cacheInfo, 1800);
}
$data = array('status'=>'true','id'=>$val);
$data = array('status'=>'true','id'=>$val,'read_user'=>kernel::single('desktop_user')->get_login_name());
$flag = app::get('base')->model('rpcnotify')->save( $data );
if( $flag == false ) break;
}
}else {
$data = array('status'=>'true');
$data = array('status'=>'true','read_user'=>kernel::single('desktop_user')->get_login_name());
$filter = array();
$flag = app::get('base')->model('rpcnotify')->update( $data, $filter );
}
$this->end( $flag, ($flag ? app::get('desktop')->_('操作成功') : app::get('desktop')->_('操作失败')) );
}
public function unread() {
if (!$_POST['from']) {
$this->begin( kernel::router()->gen_url( array('app'=>'desktop','ctl'=>'rpcnotify','act'=>'index') ) );
}else{
$this->begin( kernel::router()->gen_url( array('app'=>'desktop','ctl'=>'dashboard','act'=>'index') ) );
}
$id = $_POST['id'];
$is_selected_all = $_POST['isSelectedAll'];
if( !$id && !$is_selected_all)
$this->end( false, app::get('desktop')->_('操作失败') );
if ($id) {
//桌面消息缓存
$cacheInfo = cachecore::fetch('system_notice_data');
foreach( (array)$id as $val ) {
if ($cacheInfo) {
$infoKey = array_search($val, array_column($cacheInfo, 'id'));
$cacheInfo[$infoKey]['status'] = 'false';
cachecore::store('system_notice_data', $cacheInfo, 1800);
}
$data = array('status'=>'false','id'=>$val,'read_user'=>'');
$flag = app::get('base')->model('rpcnotify')->save( $data );
if( $flag == false ) break;
}
}else {
$data = array('status'=>'false','read_user'=>'');
$filter = array();
$flag = app::get('base')->model('rpcnotify')->update( $data, $filter );
}

View File

@@ -14,8 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
$db['menus']=array (
'columns' =>
array (
@@ -78,7 +76,7 @@ $db['menus']=array (
'comment'=>'额外信息',
),
'target'=>array(
'type'=>'varchar(10)',
'type'=>'varchar(255)',
'default'=>'',
'comment'=>'跳转'
),

View File

@@ -51,7 +51,7 @@
<adminpanel group="desktop_other" permission="performance" controller="cachemgr" action="optimize" display='false'>优化缓存</adminpanel>
<adminpanel group="desktop_other" permission="performance" controller="cachemgr" action="clean" display='false'>清空缓存</adminpanel>
<adminpanel group="desktop_setting" permission="shopsetting" controller="appmgr" display='true' order="20">应用中心</adminpanel>
<adminpanel group="desktop_other" permission="other" controller="rpcnotify" display='true'>通知</adminpanel>
<!-- <adminpanel group="desktop_other" permission="other" controller="rpcnotify" display='true'>通知</adminpanel> -->
<adminpanel group="desktop_other" permission="other" controller="shoprelation" display='false'>网店邻居</adminpanel>
@@ -67,6 +67,7 @@
<permission id="user_roles_edit" display='true'>角色编辑</permission>
<permission id="user_roles_add" display='true'>角色新增</permission>
<permission id="page_config_setting" display='true'>页面配置项</permission>
<permission id="message_notify" display='true'>消息通知</permission>
</permissions>
<workground name="控制面板" id="adminpanel" order="1800" icon="icon-kongzhimianban-01">
@@ -87,7 +88,7 @@
</workground>
<menugroup name="其他" en="other">
<menu controller='rpcnotify' permission='other' display='true'>消息通知</menu>
<menu controller='rpcnotify' permission='message_notify' display='true'>消息通知</menu>
<menu controller='queue' permission='performance' display='true'>队列列表</menu>
</menugroup>
</workground>

View File

@@ -838,19 +838,14 @@ JS;
}
/**
* returnJson
* @param array $data 数据
* @param mixed $status status
* @param mixed $msg msg
* @return mixed 返回值
*/
public function returnJson(array $data,$status = true,$msg = '')
public function returnJson(array $data,$status = true,$msg = '',$code = 200)
{
$params = [
'rsp' => $status ? 'succ' : 'fail',
'msg' => $msg ? $msg : $status,
'data' => $data
'rsp' => $status ? 'succ' : 'fail',
'msg' => $msg ? $msg : $status,
'data' => $data,
'code' => $code,
'message' => $msg ? $msg : $status,
];
$this->splash($status ? 'success' : 'fail', null, $msg, 'redirect', $params);
}
@@ -874,11 +869,15 @@ JS;
* 订单单切片导入页面
* @date 2024-10-11 4:05 下午
*/
public function displayImportV2($type='')
public function displayImportV2($type='', $extraParams=[])
{
$finder_id = $_GET['_finder']['finder_id'];
$this->pagedata['type'] = $type;
$this->pagedata['download_url'] = sprintf('index.php?app=%s&ctl=%s&act=exportTemplateV2&finder_id=%s', $_GET['app'], $_GET['ctl'], $finder_id);
// 传递额外参数到模板
$this->pagedata['extra_hidden_fields'] = $extraParams;
$this->display('admin/order/order_import.html', 'ome');
}

View File

@@ -337,7 +337,7 @@ class desktop_io_type_csv extends desktop_io_io{
if(function_exists('iconv')){
//excel 2007 读取utf8乱码bug。
$string = iconv('UTF-8', 'GB2312//IGNORE', $rs)."\n";
$string = iconv('UTF-8', 'GBK//IGNORE', $rs)."\n";
}else{
$string = $this->charset->utf2local( $rs )."\n";
}

View File

@@ -41,8 +41,12 @@ class desktop_router implements base_interface_router{
$arrMethods = get_class_methods($controller);
if (in_array($_GET['act'], $arrMethods))
call_user_func_array(array(&$controller,$_GET['act']),(array)$query_args);
else
call_user_func_array(array(&$controller,'index'),(array)$query_args);
else{
header("HTTP/1.1 404 Not Found");
echo '<h1>404 - Page Not Found</h1>';
echo '<p>请求的页面不存在</p>';
exit;
}
}
/**

View File

@@ -338,7 +338,14 @@ class desktop_user{
}
$finderId = app::get('desktop')->router()->getFinderVid($menu['menu_path'].$query);
$menu['menu_path'] = $menu['menu_path'].$query.'&finder_vid='.$finderId;
$menu['route_path'] = '/m-'.str_replace('_','',$menu['workground']).'/'.$menu['en'].'/'.$menu['menu_id'];
// 如果target有值且以"/"开头使用target作为route_path/audit-template-list审批流模板列表
if(!empty($menu['target']) && strpos($menu['target'], '/') === 0){
$menu['route_path'] = $menu['target'];
} else {
$menu['route_path'] = '/m-'.str_replace('_','',$menu['workground']).'/'.$menu['en'].'/'.$menu['menu_id'];
}
$aData['menu'][$k1][$k2][$k3] = $menu;
}
}

View File

@@ -108,4 +108,4 @@ window.addEvent('domready', function(){
<{button type="submit" label=$___desktop="导出"|t:'desktop' app="desktop" icon="btn_get_world.gif"}>
<{toinput from=$env.post}>
</div></div>
</form>
</form>

View File

@@ -13,19 +13,36 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<div style="margin:5px 0;">
<{foreach from=$temps item=item name="_s"}>
<input type="radio" name="extemp_id" class="extemp_id" vtype="requiredradio" value="<{$item.et_id}>" <{if $smarty.foreach._s.first}>checked="checked"<{/if}> /><label><{$item.et_name}></label>
<input type="radio" name="extemp_id" class="extemp_id" vtype="requiredradio" value="<{$item.et_id}>" <{if $smarty.foreach._s.first}>checked="checked"<{/if}> />
<label style="display:inline;margin-left:3px;"><{$item.et_name}></label>
<a href="javascript:void(0);" class="delete-temp-btn" data-et-id="<{$item.et_id}>" title="删除此模板" style="margin-left:5px;display:inline-block;"><{img src="bundle/delete.gif" app="desktop" class="pointer btn-delete-item"}></a>
<{/foreach}>
</div>
<div id="expmbdetail">
</div>
<script>
// 获取 type 参数
var exportType = '<{$type}>' || '<{$smarty.get.type}>';
if(!exportType){
// 如果模板变量中没有,尝试从 URL 中获取
var urlParams = window.location.search.substring(1).split('&');
for(var i = 0; i < urlParams.length; i++){
var param = urlParams[i].split('=');
if(param[0] == 'type'){
exportType = decodeURIComponent(param[1]);
break;
}
}
}
$ES('.extemp_id').each(function(e){
if(e.checked){
var extemp_id = e.value;
new Request.HTML({
update:'expmbdetail',
url:'index.php?index.php?app=desktop&ctl=export&act=getTempDetail&tp_id='+extemp_id,
url:'index.php?app=desktop&ctl=export&act=getTempDetail&tp_id='+extemp_id,
}).send();
}
@@ -33,8 +50,68 @@
var extemp_id = this.value;
new Request.HTML({
update:'expmbdetail',
url:'index.php?index.php?app=desktop&ctl=export&act=getTempDetail&tp_id='+extemp_id,
url:'index.php?app=desktop&ctl=export&act=getTempDetail&tp_id='+extemp_id,
}).send();
})
});
</script>
// 删除模板功能
if($ES('.delete-temp-btn')){
$ES('.delete-temp-btn').each(function(btn){
btn.addEvent('click', function(e){
e.stop();
if(!confirm('确定要删除该模板吗?')){
return;
}
var et_id = this.get('data-et-id');
var _this = this;
new Request({
url: 'index.php?app=desktop&ctl=export&act=deleteTemp',
method: 'post',
data: {
et_id: et_id
},
onComplete: function(response){
try{
var result = JSON.decode(response);
// 检查删除是否成功splash() 方法返回格式为 {success: "...", redirect: "...", splash: true}
if(result.success || result.splash === true || result.rsp == 'succ'){
// 删除成功,刷新模板列表
if(exportType){
var url = 'index.php?app=desktop&ctl=export&act=getTemps&type=' + exportType;
// 查找父容器 expmbnormal当前内容被加载到这个容器中
var parentContainer = $('expmbnormal');
if(parentContainer){
new Request.HTML({
update: parentContainer,
url: url,
onComplete: function(){
// 清空详情区域
if($('expmbdetail')){
$('expmbdetail').set('html', '');
}
}
}).send();
} else {
// 如果找不到父容器,刷新当前页面
location.reload();
}
} else {
location.reload();
}
} else {
// 失败情况:可能有 error 字段或 msg 字段
var errorMsg = result.error || result.msg || result.message || '删除失败';
alert(errorMsg);
}
} catch(e){
alert('删除失败:' + e.message);
}
}
}).send();
});
});
}
</script>

View File

@@ -41,20 +41,52 @@
</div>
</div>
<script>
$$('#finder-header-<{$name}> .col-select-opt').addEvents({
'click':function(e){
if(e.target.match('input'))return;
var menu = this.retrieve('dropmenu',this.getElement('.x-drop-menu'));
menu.setStyles({
top:(this.getPosition('workground').y+this.offsetHeight.toInt()),
left:this.getPosition('workground').x
});
menu.style.display= (menu.style.display=="block"?'none':'block');
},
'mouseleave':function(){
this.retrieve('dropmenu',this.getElement('.x-drop-menu')).hide();
(function(){
var trigger = $$('#finder-header-<{$name}> .col-select-opt')[0];
if(!trigger) return;
var menu = trigger.getElement('.x-drop-menu');
if(!menu) return;
trigger.store('dropmenu', menu);
// 显示时注入到 body避免被 finder-header-wrapper 的 overflow:hidden 裁剪
function showMenu(){
if(menu.getParent() !== document.body){
menu.inject(document.body);
}
var top, left;
if(trigger.getBoundingClientRect){
var rect = trigger.getBoundingClientRect();
top = (rect.bottom != null ? rect.bottom : rect.top + trigger.offsetHeight);
left = (rect.left != null ? rect.left : rect.x);
} else {
var scroll = window.getScroll();
var pos = trigger.getPosition();
top = pos.y + trigger.offsetHeight - scroll.y;
left = pos.x - scroll.x;
}
menu.setStyle('position', 'fixed');
menu.setStyles({ top: top + 'px', left: left + 'px', zIndex: 9999 });
menu.style.display = 'block';
}
});
function hideMenu(){ menu.style.display = 'none'; }
function bindDocClose(){
var docClick = function(e){
var t = e.target;
if(trigger.contains(t)) return;
hideMenu();
document.removeEvent('click', docClick);
};
setTimeout(function(){ document.addEvent('click', docClick); }, 0);
}
trigger.addEvent('click', function(e){
if(e.target && e.target.match && e.target.match('input')) return;
if(menu.style.display === 'block'){
hideMenu();
return;
}
showMenu();
bindDocClose();
});
})();
</script>
<{/if}>
</td>