1、新建NTSC_ReqQua实体类,一切数据处理的基础
Class User.NTSCReqQua Extends %Persistent [ ClassType = persistent, SqlTableName = NTSC_ReqQua, StorageStrategy = SQLStorageStorage ]
{
/// 需求序号
Property ntscno As %String [ Required, SqlColumnNumber = 2, SqlFieldName = NTSC_NO ];
/// 需求标题
Property ntsctitle As %String(MAXLEN = 1800) [ Required, SqlColumnNumber = 3, SqlFieldName = NTSC_Title ];
/// 质控类型
Property ntsctype As %String(MAXLEN = 1800) [ SqlColumnNumber = 4, SqlFieldName = NTSC_Type ];
/// 投诉类型
Property ntsctstype As %String(MAXLEN = 1800) [ SqlColumnNumber = 5, SqlFieldName = NTSC_TSType ];
/// 投诉内容
Property ntsctstext As %String(MAXLEN = 1800) [ SqlColumnNumber = 6, SqlFieldName = NTSC_TSText ];
/// 质量分级
Property ntsclevel As %String [ SqlColumnNumber = 7, SqlFieldName = NTSC_Level ];
/// 质量问题类型
Property ntsclevreq As %String(MAXLEN = 1800) [ SqlColumnNumber = 8, SqlFieldName = NTSC_LevReq ];
/// 质量问题描述
Property ntsclevreqdesc As %String(MAXLEN = 1800) [ SqlColumnNumber = 9, SqlFieldName = NTSC_LevReqDesc ];
/// 质检状态
Property ntscstratus As %String [ SqlColumnNumber = 10, SqlFieldName = NTSC_LevStratus ];
/// 案例需求
Property ntscmearn As %String(MAXLEN = 1800) [ SqlColumnNumber = 11, SqlFieldName = NTSC_Meran ];
/// 改进意见
Property ntsctrans As %String(MAXLEN = 1800) [ SqlColumnNumber = 12, SqlFieldName = NTSC_Trans ];
/// 交付中心
Property ntscdelcenter As %String [ SqlColumnNumber = 13, SqlFieldName = NTSC_DelCenter ];
/// 所属分区
Property ntscaffi As %String [ SqlColumnNumber = 14, SqlFieldName = NTSC_Affil ];
/// 发起人
Property ntscsponsor As %String [ SqlColumnNumber = 15, SqlFieldName = NTSC_Sponsor ];
/// 发起组
Property ntscsponsorgroup As %String [ SqlColumnNumber = 16, SqlFieldName = NTSC_SpoGroup ];
/// 接收人
Property ntscrecpient As %String [ SqlColumnNumber = 17, SqlFieldName = NTSC_Recipient ];
/// 接收组
Property ntscrecpgroup As %String [ SqlColumnNumber = 18, SqlFieldName = NTSC_RecGroup ];
/// 分配人
Property ntscassigner As %String [ SqlColumnNumber = 19, SqlFieldName = NTSC_Assigner ];
/// 需求当前人
Property ntsccueernt As %String [ SqlColumnNumber = 20, SqlFieldName = NTSC_Current ];
/// 公示截止日期
Property ntscpubdate As %Date [ SqlColumnNumber = 21, SqlFieldName = NTSC_PublicityDaye ];
/// 发布日期
Property ntscreledate As %Date [ SqlColumnNumber = 22, SqlFieldName = NTSC_ReleaseDate ];
/// 质检期数
Property ntscquaily As %String [ SqlColumnNumber = 23, SqlFieldName = NTSC_Quality ];
/// 当前组
Property ntsccurrgroup As %String [ SqlColumnNumber = 24, SqlFieldName = NTSC_CurrentGroup ];
/// 创建人
Property ntsccreatuser As %String [ SqlColumnNumber = 25, SqlFieldName = NTSC_CeartUser ];
/// 当前人
Property ntsccurruser As %String [ SqlColumnNumber = 26, SqlFieldName = NTSC_CurrentUser ];
/// 创建日期
Property ntsccreatdate As %Date [ SqlColumnNumber = 27, SqlFieldName = NTSC_CeartDate ];
/// 数据操作mac地址
Property ntscmac As %String [ SqlColumnNumber = 28, SqlFieldName = NTSC_Mac ];
/// 数据操作人
Property ntscopera As BSP.Lic.AccessMac [ SqlColumnNumber = 29, SqlFieldName = NTSC_opera ];
Index ntsccreatno On ntscno [ Unique ];
Storage SQLStorageStorage
{
<SqlIdExpression>$i(^NTSCReqQua(0))</SqlIdExpression>
<SQLMap name="NoNtscIndex">
<Global>^NTSCReqQuaI</Global>
<PopulationType>nonnull</PopulationType>
<RowIdSpec name="1">
<Expression>{L3}</Expression>
<Field>NTSC_RowID</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>"NO"</Expression>
</Subscript>
<Subscript name="2">
<Expression>{NTSC_NO}</Expression>
</Subscript>
<Subscript name="3">
<Expression>{NTSC_RowID}</Expression>
</Subscript>
<Type>index</Type>
</SQLMap>
<SQLMap name="data">
<Data name="NTSC_Affil">
<Delimiter>"^"</Delimiter>
<Piece>13</Piece>
</Data>
<Data name="NTSC_Assigner">
<Delimiter>"^"</Delimiter>
<Piece>18</Piece>
</Data>
<Data name="NTSC_CeartDate">
<Delimiter>"^"</Delimiter>
<Piece>26</Piece>
</Data>
<Data name="NTSC_CeartUser">
<Delimiter>"^"</Delimiter>
<Piece>24</Piece>
</Data>
<Data name="NTSC_Current">
<Delimiter>"^"</Delimiter>
<Piece>19</Piece>
</Data>
<Data name="NTSC_CurrentGroup">
<Delimiter>"^"</Delimiter>
<Piece>23</Piece>
</Data>
<Data name="NTSC_CurrentUser">
<Delimiter>"^"</Delimiter>
<Piece>25</Piece>
</Data>
<Data name="NTSC_DelCenter">
<Delimiter>"^"</Delimiter>
<Piece>12</Piece>
</Data>
<Data name="NTSC_LevReq">
<Delimiter>"^"</Delimiter>
<Piece>7</Piece>
</Data>
<Data name="NTSC_LevReqDesc">
<Delimiter>"^"</Delimiter>
<Piece>8</Piece>
</Data>
<Data name="NTSC_LevStratus">
<Delimiter>"^"</Delimiter>
<Piece>9</Piece>
</Data>
<Data name="NTSC_Level">
<Delimiter>"^"</Delimiter>
<Piece>6</Piece>
</Data>
<Data name="NTSC_Mac">
<Delimiter>"^"</Delimiter>
<Piece>27</Piece>
</Data>
<Data name="NTSC_Meran">
<Delimiter>"^"</Delimiter>
<Piece>10</Piece>
</Data>
<Data name="NTSC_NO">
<Delimiter>"^"</Delimiter>
<Piece>1</Piece>
</Data>
<Data name="NTSC_PublicityDaye">
<Delimiter>"^"</Delimiter>
<Piece>20</Piece>
</Data>
<Data name="NTSC_Quality">
<Delimiter>"^"</Delimiter>
<Piece>22</Piece>
</Data>
<Data name="NTSC_RecGroup">
<Delimiter>"^"</Delimiter>
<Piece>17</Piece>
</Data>
<Data name="NTSC_Recipient">
<Delimiter>"^"</Delimiter>
<Piece>16</Piece>
</Data>
<Data name="NTSC_ReleaseDate">
<Delimiter>"^"</Delimiter>
<Piece>21</Piece>
</Data>
<Data name="NTSC_SpoGroup">
<Delimiter>"^"</Delimiter>
<Piece>15</Piece>
</Data>
<Data name="NTSC_Sponsor">
<Delimiter>"^"</Delimiter>
<Piece>14</Piece>
</Data>
<Data name="NTSC_TSText">
<Delimiter>"^"</Delimiter>
<Piece>5</Piece>
</Data>
<Data name="NTSC_TSType">
<Delimiter>"^"</Delimiter>
<Piece>4</Piece>
</Data>
<Data name="NTSC_Title">
<Delimiter>"^"</Delimiter>
<Piece>2</Piece>
</Data>
<Data name="NTSC_Trans">
<Delimiter>"^"</Delimiter>
<Piece>11</Piece>
</Data>
<Data name="NTSC_Type">
<Delimiter>"^"</Delimiter>
<Piece>3</Piece>
</Data>
<Data name="NTSC_opera">
<Delimiter>"^"</Delimiter>
<Piece>28</Piece>
</Data>
<Global>^NTSCReqQua</Global>
<PopulationType>nonnull</PopulationType>
<RowIdSpec name="1">
<Expression>{L1}</Expression>
<Field>NTSC_RowID</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>{NTSC_RowID}</Expression>
<StartValue>1</StartValue>
</Subscript>
<Type>data</Type>
</SQLMap>
<SqlRowIdName>NTSC_RowID</SqlRowIdName>
<StreamLocation>^User.NTSCReqQuaS</StreamLocation>
<Type>%Storage.SQL</Type>
}
}2、页面设置
首先需要再 demo 安全组中放开列编辑按钮

新版 9.0 版本,不在后台书写列名,在前台界面可快读编辑


3、对于需求页面样式引用的编写
<!DOCTYPE html>
<!--
需求质控列表
csp: csp/NTSC/NTSCReqQuaCont.csp
js: scripts/NTSC/NTSCReqQuaCont.js
-->
<html>
<!-- 验证session过期 -->
<csp:method name=OnPreHTTP arguments="" returntype=%Boolean>
d ##Class(websys.SessionEvents).SessionExpired() q $$$OK
</csp:method>
<head>
<!-- iMedical版本标题 -->
<title>
<TRAK:TRANSLATE id=title>##(%session.Get("TITLE"))##</TRAK:TRANSLATE>
</title>
<TRAK:HEAD></TRAK:HEAD>
<HISUI />
<PHALIBV1 />
<PHAPRINTCOM />
<style>
.pha-plan-create-hide {
display: none;
}
.messager-popover .content {
height: auto
}
#qCondition a{
min-width:90px;
}
</style>
</head>
<body>
<div class="hisui-layout" fit="true" id="lyMainView">
<div data-options="region:'center',border:false" class="pha-body">
<div class="hisui-layout" fit="true">
<div data-options = "region:'center',border:false,split:true">
<div class = "hisui-panel" data-options="region:'center',title:'需求质控列表'" id="layout-plan-create-panel">
<table id="gridItm"></table>
</div>
</div>
</div>
</div>
</div>
<!-- 表格工具栏 -->
<div id="gridItmBar">
<table id="qCondition" class="pha-con-table">
<tr>
<td class="r-label">
<label for="startDate-merge">#(..Get("开始日期"))#</label>
</td>
<td class="r-label">
<input type="text" id="startDate-merge" data-pha="class:'hisui-datebox',clear:true,save:true,query:true,required:true">
</td>
<td class="r-label">
<label for="Level">#(..Get("质检分级"))#</label>
</td>
<td class="r-label">
<input type="text" id="ntsclevel" data-pha="class:'hisui-combobox',clear:true,save:true,query:true,required:true">
</td>
<td class="r-label">
<a data-pha-btn class="hisui-linkbutton" id="btnFind" data-options="iconCls:'icon-w-find'">查询</a>
</td>
<td style="padding-left:10px"><a id="btnImportWin" data-options="iconCls:'icon-w-import'" class="hisui-linkbutton button-width" >导入Excel</a></td>
</tr>
<tr>
<td class="r-label" >
<label for="endDate-merge">#(..Get("结束日期"))#</label>
</td>
<td class="r-label">
<input type="text" id="endDate-merge" data-pha="class:'hisui-datebox',clear:true,save:true,query:true,required:true">
</td>
<td class="r-label">
<label for="remarks">#(..Get("需求序号"))#</label>
</td>
<td class="r-label">
<input type="text" id="remarNo" data-pha="class:'hisui-validatebox',clear:true,save:true,query:true">
</td>
<td class="r-label">
<a data-pha-btn class="hisui-linkbutton" id="btnClean" data-options="iconCls:'icon-w-clean'">清屏</a>
</td>
<td class="r-label">
<a data-pha-btn class="hisui-linkbutton" id="btnSave" data-options="iconCls:'icon-w-save'">保存</a>
</td>
</tr>
</table>
<!-- 页面展示的横线-->
<div class="pha-line"></div>
</div>
<div id="winMergePlan" class="js-pha-com-window-sign">
<div class="hisui-layout" fit="true">
<div data-options="region:'center',border:false" class="pha-body pha-body-white">
<div class="hisui-layout" fit="true" border="false">
<div data-options="headerCls:'panel-header-gray',iconCls:'icon-paper',region:'north',height:350,split:true,title:'需求质控列表',collapsible:true,showCollapsedTitle:true">
<table id="gridMain-merge"></table>
</div>
<div data-options="headerCls:'panel-header-gray',iconCls:'icon-paper',region:'center',title:'明细'">
<table id="gridItm-merge"></table>
</div>
</div>
</div>
</div>
</div>
<!--导出弹框-->
<div id="ImportWin" class="hisui-dialog" data-options="closed:'true',modal:true" title=#(..Get("导入准备的需求列表"))# style="width:340px;height:145px;">
<table class="pha-con-table">
<tr>
<td class="r-label"><label for="conFileBox">#(..Get("文件选择"))#</label></td>
<td><input id='conFileBox' data-pha /></td>
</tr>
</table>
<div data-options="region:'south'" border="false" style="text-align:center;padding-bottom:10px">
<a id='btnImportFile' class="hisui-linkbutton" >导入</a>
<a id='btnExportFile' class="hisui-linkbutton" style="margin-left:10px;">导入模版下载</a>
</div>
</div>
<!-- 加载本页面js -->
<script type="text/javascript" src="../scripts/NTSC/ReqQuaCont/loading.js"></script>
<script type="text/javascript" src="../scripts/NTSC/ReqQuaCont/com.js"></script>
<script type="text/javascript" src="../scripts/NTSC/ReqQuaCont/compent.js"></script>
<script type="text/javascript" src="../scripts/NTSC/NTSCReqQuaCont.js"></script>
<!-- 导入excel文件读取插件 -->
<script type="text/javascript" src="../scripts/pha/plugins/xlsx/xlsx.full.min.js"></script>
</body>
</html>4、对于页面操作的主js
//需求质控列表
//csp: csp/NTSC/NTSCReqQuaCont.csp
//js: scripts/NTSC/NTSCReqQuaCont.js
//为了不用写重复代码,将数据验证列表和数据库查询等方法集成在一起,纯手搓的,只用做需求列表质量验证
var tipFlag = "";
$(function () {
var biz = {
data: {
ntscID: '',
status: 'SAVE',
handleStatus: '',
keepInputFields: ['Level', 'Remarks'],
keepInputFlag: true,
defaultData: [
{
'Level': '',
'startDate-merge': 't - 30',
'endDate-merge': 't',
'Remarks': ''
}
]
},
getData: function (key) {
switch (key) {
case 'mouldFlag':
return $('#mouldFlag').checkbox('getValue');
default:
break;
}
return this.data[key];
},
setData: function (key, data) {
this.data[key] = data;
switch (key) {
case 'ntscID':
break;
}
}
};
/**
* 初始化
*/
var components = PLAN_COMPONENTS();
var com = PLAN_COM;
var settings = com.GetSettings();
components('Level', 'ntsclevel');
components('Remarks', 'remarNo');
components('Date', 'startDate-merge');
components('Date', 'endDate-merge');
components('MainGrid', 'gridMain-merge', {
toolbar: '#gridMain-mergeBar',
singleSelect: false
});
var rebuildColumns = PHA_COM.RebuildColumns(components('ItmGridColmuns', 'gridItm-merge'), {
hiddenFields: ['gCheck']
});
components('ItmGrid', 'gridItm-merge', {
toolbar: '#gridItm-mergeBar',
columns: rebuildColumns.columns,
frozenColumns: rebuildColumns.frozenColumns
});
PHA_EVENT.Bind('#btnFind', 'click', function (){QueryMain();});
// 为了不用写重复代码,将数据验证列表和数据库查询方法集成在一起,纯手搓的
function QueryMain(){
let ntscnoStr = '';
var rows = [];
com.GetChangedRows('gridItm').forEach(function (it) {
var rowData = $.extend({}, it);
rows.push(rowData);
});
const ntsctstypeList = Array.isArray(rows)
? rows.map(item => {
return (item && item.ntsctype !== undefined)
? item.ntsctype
: '';
})
: [];
const ntscnoList = rows
.filter(item => item.ntscno !== '' && item.ntscno !== null && item.ntscno !== undefined)
.map(item => item.ntscno);
if (ntscnoList.length > 0) {
console.log("执行 join 前的 ntscnoList:", ntscnoList);
ntscnoStr = ntscnoList.join(',');
console.log("拼接后的 ntscnoStr:", ntscnoStr);
// 后续逻辑...
// 这里可以使用ntscnoStr进行后续操作,比如发送请求等
}
var $grid = $("#gridItm");
var stDate = $("#startDate-merge").datebox("getValue") || "";
var endDate = $("#endDate-merge").datebox("getValue") || "";
var Level = $("#ntsclevel").combobox("getValue") || "";
var remarNo = ntsctstypeList.some(type => type === "")
? ntscnoStr // 此时能拿到拼接后的值(或空字符串)
: ($("#remarNo").val() || "");
var instFlag = "";
var pJson = {};
pJson.stDate = stDate;
pJson.endDate = endDate;
pJson.Level = Level;
pJson.remarNo = remarNo;
$grid.datagrid('options').url = PHA.$URL;
$grid.datagrid('query',{
pClassName:'NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont' ,
pMethodName:'GetMainDataRows',
pPlug:'datagrid',
pJson: JSON.stringify(pJson)
});
}
components('ItmGrid', 'gridItm', {
toolbar: '#gridItmBar',
pagination: false,
showFooter: true,
isAutoShowPanel: false,
rownumbers: true,
data: {
rows: [],
footer: [],
total: 0
},
singleSelect: true,
shiftCheck: true,
singleSelect: true,
checkOnSelect: false
});
$('#conFileBox').filebox({
prompt: $g('请选择文件...'),
buttonText: $g('选择'),
width: 250,
accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel'
})
PHA_EVENT.Bind('#btnClean', 'click', function () {
$('#gridItm').datagrid('clear');
biz.setData('Level', '');
biz.setData('Remarks', '');
});
PHA_EVENT.Bind('#btnSave', 'click', function () {
biz.setData('handleStatus', 'Save');
Save();
});
PHA_EVENT.Bind('#btnImportWin', 'click', function(){ImportWin();});
PHA_EVENT.Bind('#btnImportFile', 'click', function(){ImportFile();});
PHA_EVENT.Bind('#btnExportFile', 'click', function () { ExportFile(); });
function Save() {
var rows = [];
com.GetChangedRows('gridItm').forEach(function (it) {
var rowData = $.extend({}, it);
rows.push(rowData);
});
const ntsctstypeList = Array.isArray(rows)
? rows.map(item => (item && item.ntsctype !== undefined) ? item.ntsctype : '')
: [];
if (ntsctstypeList.every(type => type === "")) {
showProgressMessage("验证数据不要点保存, Are you OK!!!");
return;
}
var apiMethod = com.Fmt2ApiMethod(biz.getData('handleStatus'));
if (apiMethod === '') return;
tipFlag = "1";
PHA_GridEditor.DeleteNullRow('#gridItm', ['ntscno']);
if (ValidateEditGrid() === false || ValidateSave() === false) return;
createProgressBar();
const batchSize = 3;
const totalCount = rows.length;
const totalBatches = Math.ceil(totalCount / batchSize);
let currentBatch = 0;
// 立即启动第一批保存
processNextBatch();
function processNextBatch() {
if (currentBatch >= totalBatches) {
completeSave();
return;
}
const startIndex = currentBatch * batchSize;
const endIndex = Math.min(startIndex + batchSize, totalCount);
const currentBatchData = rows.slice(startIndex, endIndex);
updateProgressBar(currentBatch + 1, totalBatches);
showProgressMessage(`正在处理第 ${currentBatch + 1} 批数据(共 ${totalBatches} 批)`);
var data4save = { rows: currentBatchData };
PHA.Loading('Show');
com.Invoke(apiMethod, data4save,
function (retData) {
PHA.Loading('Hide');
let msg = '';
if (typeof retData === 'string') {
const shortMsg = retData.length > 100 ? retData.substring(0, 100) + '...' : retData;
msg = `第${currentBatch + 1}批保存失败\n原因: ${shortMsg}\n(继续处理下一批)`;
} else {
biz.setData('ntscID', retData.data);
msg = `第${currentBatch + 1}批保存成功`;
}
showProgressMessage(msg);
// 处理完当前批,立即处理下一批
currentBatch++;
processNextBatch();
},
function(error) {
PHA.Loading('Hide');
let errorMsg = `第${currentBatch + 1}批请求错误\n`;
if (error.message) errorMsg += `错误类型: ${error.message}\n`;
if (error.responseText) {
const shortResponse = error.responseText.length > 100
? error.responseText.substring(0, 100) + '...'
: error.responseText;
errorMsg += `响应内容: ${shortResponse}`;
}
errorMsg += `\n(继续处理下一批)`;
showProgressMessage(errorMsg);
// 即使出错,也处理下一批
currentBatch++;
processNextBatch();
}
);
}
function completeSave() {
showProgressMessage(`全部保存完成!共处理 ${totalCount} 条数据,分为 ${totalBatches} 批`);
setTimeout(hideProgressBar, 3000);
}
function createProgressBar() {
let progressContainer = document.getElementById('saveProgressContainer');
if (!progressContainer) {
progressContainer = document.createElement('div');
progressContainer.id = 'saveProgressContainer';
progressContainer.style.cssText = `
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 300px; background-color: white; border: 1px solid #ccc;
border-radius: 5px; padding: 15px; z-index: 9999;
`;
const title = document.createElement('div');
title.style.cssText = 'margin-bottom: 10px; font-weight: bold;';
title.textContent = '数据保存进度';
progressContainer.appendChild(title);
const messageArea = document.createElement('div');
messageArea.id = 'progressMessage';
messageArea.style.cssText = 'margin-bottom: 10px; height: auto; white-space: pre-wrap; word-break: break-all;';
progressContainer.appendChild(messageArea);
const progressBarContainer = document.createElement('div');
progressBarContainer.style.cssText = 'height: 10px; background-color: #eee; border-radius: 5px; overflow: hidden;';
const progressBar = document.createElement('div');
progressBar.id = 'progressBar';
progressBar.style.cssText = 'height: 100%; width: 0%; background-color: #4CAF50; transition: width 0.3s ease;';
progressBarContainer.appendChild(progressBar);
progressContainer.appendChild(progressBarContainer);
const progressText = document.createElement('div');
progressText.id = 'progressText';
progressText.style.cssText = 'text-align: center; font-size: 12px; margin-top: 5px;';
progressText.textContent = '0%';
progressContainer.appendChild(progressText);
document.body.appendChild(progressContainer);
}
}
function updateProgressBar(current, total) {
const progress = (current / total) * 100;
document.getElementById('progressBar').style.width = `${progress}%`;
document.getElementById('progressText').textContent = `${Math.round(progress)}% (${current}/${total} 批)`;
}
function showProgressMessage(message) {
document.getElementById('progressMessage').textContent = message;
}
function hideProgressBar() {
const container = document.getElementById('saveProgressContainer');
if (container) container.style.display = 'none';
}
}
function ValidateEditGrid() {
var val = true;
var msg = '';
try {
// 验证必填
if (!PHA_GridEditor.EndCheck('gridItm')) {
throw '';
}
if ($('#gridItm').datagrid('getRows').length == 0) {
throw '没有需要操作的数据';
}
} catch (error) {
val = false;
msg = error;
} finally {
if (msg !== '' && typeof msg === 'string') {
components('Pop', msg);
}
return val;
}
}
/// 验证单行不做提示, 故与保存的alert|pop不存在冲突
function ValidateSave(rowData, rowIndex) {
var mainObj = com.Condition('#qCondition', 'get', { dotype: 'save' });
if (mainObj === undefined) {
return;
}
mainObj.planID = biz.getData('planID');
mainObj.mainRowID = biz.getData('planID');
var rows = [];
if (rowData === undefined) {
var forRows = $('#gridItm').datagrid('getRows');
forRows.forEach(function (it) {
var forRow = $.extend({}, it);
rows.push(forRow);
});
} else {
rowData.rowIndex = rowIndex;
if ((rowData.inciCode || '') === '') {
return true;
}
rows.push(rowData);
}
// 异步只是稍微好那么一点, 但是感受不出来
var valRet = PLAN_COM.InvokeSyn('ValidateSave', {
// main: mainObj,
rows: rows
});
if (valRet.type !== '') {
if (rowIndex === undefined) {
// 点击保存的提醒
PHA.ShowWarn({ warnInfo: valRet });
if (valRet.type === 'terminate') {
return false;
}
}else{
PHA.Warn2Grid('#gridItm', { warnInfo: valRet });
return false;
}
}
return true;
}
function ControlOperation() {
com.ControlOperation({
'#btnExport': {
disabled: biz.getData('planID') === ''
},
'#btnSave': {
disabled: biz.getData('status') !== 'SAVE'
}
});
}
function SetDefaults() {
PHA.SetVals(biz.getData('defaultData'));
$('#Level').combobox('reload');
$('#Remarks').combobox('reload');
}
setTimeout(function () {
if (settings.Com.StkCatSet === 'Y') {
}
$.extend(biz.getData('defaultData')[0], settings.DefaultData);
SetDefaults();
ControlOperation();
$('body').on('click', function () {
$('.tooltip').hide();
});
// 引用其他已经写好页面的css样式,不用在自己写一遍了
com.SetPage('pha.in.v3.plan.create.csp');
var topPlanID = com.Top.Get('ntscID', true);
if (topPlanID !== '') {
// 此处不延迟夹加载会导致采购科室不能正确加载
setTimeout(function () { biz.setData('ntscID', topPlanID); }, 300);
}
else{
}
}, 0);
function ImportWin(){
PHA.DomData('#ExportWin', {doType: 'clear'});
$('#ImportWin')
.dialog({
iconCls: 'icon-w-import',
modal: true,
onBeforeClose: function () {},
}).dialog('open');
$('#conFileBox').filebox('clear');
}
function ImportHandler() {
$('#conFileBox').filebox({
prompt: $g('请选择文件...'),
buttonText: $g('选择'),
width: 250,
accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel'
})
}
// 分片处理数据(避免UI阻塞,每批处理10条导入的数据,并将加载的动画集成在导入列表,这个动画太难搞了,头发都薅秃了)
function processDataInChunks(xlsData, loading, totalLength) {
let processed = 0;
const chunkSize = 20;
function processChunk() {
const end = Math.min(processed + chunkSize, totalLength);
for (let i = processed; i < end; i++) {
try {
var row = xlsData[i];
if (row['#公示截止日期#']) {
var pubdate = excelDateToJsDate(row['#公示截止日期#']);
if (pubdate instanceof Date && !isNaN(pubdate.getTime())) {
row['#公示截止日期#'] = formatDate(pubdate);
}
}
if (row['#创建日期#']) {
var creatdate = excelDateToJsDate(row['#创建日期#']);
if (creatdate instanceof Date && !isNaN(creatdate.getTime())) {
row['#创建日期#'] = formatDate(creatdate);
}
}
row = ReplaceTitle(row);
var fullDataObj = PLAN_COM.InvokeSyn('GetDataImport', row);
if (!fullDataObj) {
components('Pop', '数据处理错误', 'alert');
loading.destroy();
return;
}
if (fullDataObj.msgData) {
components('Pop', fullDataObj.msgData, 'alert');
loading.destroy();
return;
}
PHA_GridEditor.Add({
gridID: 'gridItm',
field: 'ntscno',
rowData: fullDataObj.rowData,
checkRow: false,
firstRow: false
});
loading.update(i + 1);
} catch (error) {
components('Pop', '单条数据处理失败', 'alert');
loading.destroy();
return;
}
}
processed = end;
if (processed < totalLength) {
setTimeout(processChunk, 0); // 让出UI线程,保证动画更新
} else {
loading.destroy(); // 全部处理完,销毁动画
$('#ImportWin').dialog('close');
var rows = [];
com.GetChangedRows('gridItm').forEach(function (it) {
var rowData = $.extend({}, it);
rows.push(rowData);
});
const ntsctstypeList = Array.isArray(rows)
? rows.map(item => {
return (item && item.ntsctype !== undefined)
? item.ntsctype
: '';
})
: [];
if (ntsctstypeList.every(type => type === "")) {
QueryMain();
}
}
}
processChunk();
}
// 全局可访问的Excel导入函数(确保事件绑定能找到)
window.ImportFile = function() {
try {
PHA_GridEditor.End('gridItm');
var rows = $('#gridItm').datagrid('getRows');
if (rows && rows.length > 0) {
PHA.Msg('info', '导入时请保持明细列表为空!');
return;
}
var filelist = $('#conFileBox').filebox('files');
if (!filelist || filelist.length === 0) {
PHA.Msg('alert', '请先选择文件!');
return;
}
const loading = createLoadingAnimation();
loading.update(0);
var file = filelist[0];
PHA_COM.ReadExcel(file, function(xlsData) {
try {
if (!xlsData || xlsData.length === 0) {
PHA.Msg('alert', 'excel中无有效明细!');
loading.destroy();
return;
}
const length = xlsData.length;
loading.setTotal(length);
processDataInChunks(xlsData, loading, length);
} catch (error) {
loading.destroy();
components('Pop', '数据处理异常,请重试', 'alert');
}
});
} catch (error) {
console.error('导入初始化异常:', error);
components('Pop', '导入失败,请重试', 'alert');
}
};
function ReplaceTitle(obj){
var objStr = JSON.stringify(obj);
var objStr = objStr.replace(/#需求序号#/g, 'ntscno');
var objStr = objStr.replace(/#需求标题#/g, 'ntsctitle');
var objStr = objStr.replace(/#质控类型#/g, 'ntsctype');
var objStr = objStr.replace(/#投诉类型#/g, 'ntsctstype');
var objStr = objStr.replace(/#投诉内容#/g, 'ntsctstext');
var objStr = objStr.replace(/#质量分级#/g, 'ntsclevel');
var objStr = objStr.replace(/#质量问题类型#/g, 'ntsclevreq');
var objStr = objStr.replace(/#质量问题描述#/g, 'ntsclevreqdesc');
var objStr = objStr.replace(/#质检状态#/g, 'ntscstratus');
var objStr = objStr.replace(/#案例需求#/g, 'ntscmearn');
var objStr = objStr.replace(/#改进意见#/g, 'ntsctrans');
var objStr = objStr.replace(/#交付中心#/g, 'ntscdelcenter');
var objStr = objStr.replace(/#所属分区#/g, 'ntscaffi');
var objStr = objStr.replace(/#发起人#/g, 'ntscsponsor');
var objStr = objStr.replace(/#发起组#/g, 'ntscsponsorgroup');
var objStr = objStr.replace(/#接收人#/g, 'ntscrecpient');
var objStr = objStr.replace(/#接收组#/g, 'ntscrecpgroup');
var objStr = objStr.replace(/#分配人#/g, 'ntscassigner');
var objStr = objStr.replace(/#需求当前人#/g, 'ntsccueernt');
var objStr = objStr.replace(/#公示截止日期#/g, 'ntscpubdate');
var objStr = objStr.replace(/#发布日期#/g, 'ntscreledate');
var objStr = objStr.replace(/#质检期数#/g, 'ntscquaily');
var objStr = objStr.replace(/#当前组#/g, 'ntsccurrgroup');
var objStr = objStr.replace(/#创建人#/g, 'ntsccreatuser');
var objStr = objStr.replace(/#当前人#/g, 'ntsccurruser');
var objStr = objStr.replace(/#创建日期#/g, 'ntsccreatdate');
return JSON.parse(objStr);
}
function ExportFile(){
var title={
ntscno : '#需求序号#',
ntsctitle : '#需求标题#',
}
var data = [
{
ntscno : '6138414',
ntsctitle : '门诊病历打印提示检查Web-Print打印插件,请稍后,需核查',
},
{
ntscno : '6139799',
ntsctitle : '医嘱录入过滤无库存医嘱',
}
]
var fileName='需求验证列表导入模版.xlsx'
PHA_COM.ExportFile(title, data, fileName);
}
});6、针对页面产生的后台类方法处理
/// 需求质控列表后台类
Class NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont Extends (PHA.IN.COM.Base, PHA.IN.PLAN.Filter, PHA.COM.SQL.Json) [ Abstract ]
{
/// Debug: w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).GetDataImport({"ntscno": 6138414,"ntsctitle": "门诊病历打印提示“检查Web-Print打印插件,请稍后”,需核查","ntsctype": "质量检查-质检小组","ntsclevel": "中","ntsclevreq": "需求内容不清晰","ntsclevreqdesc": "使用环境应该描述具体菜单、安全组","ntscstratus": "公示中","ntscdelcenter": "甘青交付中心","ntscaffi": "青海组","ntscsponsor": "韩文清","ntscsponsorgroup": "青海德令哈市中医","ntscrecpient": "周玉玲","ntscrecpgroup": "电子病历技术支持","ntscassigner": "","ntsccueernt": "韩文清","ntscpubdate": 45930,"ntsccurrgroup": "青海德令哈市中医","ntsccreatuser": "王乾瞩", "ntsccurruser": "董富强","ntsccreatdate": 45908.493368055555}).%ToJSON()
ClassMethod GetDataImport(pJson As %DynamicObject) As %DynamicObject
{
;s ^sdf("dassad")=$LB(pJson)
#dim retObj as %DynamicObject = {
"rowData": {},
"msgData": ""
}
;s inci = ##class(Data).GetInciByCode(pJson.inciCode, pJson.inciDesc, pJson.loc)
s ntscno = pJson.ntscno
;s ntscpubdate = $zd(pJson.ntscpubdate,3)
;s ntsccreatdate =$zd($p(pJson.ntsccreatdate,".",1),3)
b ;1
i (+ntscno = 0) {
s retObj.msgData = ntscno
s retObj.rowData = []
q retObj
}
s row = {
"ntscno" : (ntscno),
"ntsctitle" : (pJson.ntsctitle),
"ntsctype" : (pJson.ntsctype),
"ntsctstype" : (pJson.ntsctstype),
"ntsctstext" : (pJson.ntsctstext),
"ntsclevel" : (pJson.ntsclevel),
"ntsclevreq" : (pJson.ntsclevreq),
"ntsclevreqdesc" : (pJson.ntsclevreqdesc),
"ntscstratus" : (pJson.ntscstratus),
"ntscmearn" : (pJson.ntscmearn),
"ntsctrans" : (pJson.ntsctrans),
"ntscdelcenter" : (pJson.ntscdelcenter),
"ntscaffi" : (pJson.ntscaffi),
"ntscsponsor" : (pJson.ntscsponsor),
"ntscsponsorgroup" : (pJson.ntscsponsorgroup),
"ntscrecpient" : (pJson.ntscrecpient),
"ntscrecpgroup" : (pJson.ntscrecpgroup),
"ntscassigner" : (pJson.ntscassigner),
"ntsccueernt" : (pJson.ntsccueernt),
"ntscpubdate" : (pJson.ntscpubdate),
"ntscreledate" : (pJson.ntscreledate),
"ntscquaily" : (pJson.ntscquaily),
"ntsccurrgroup" : (pJson.ntsccurrgroup),
"ntsccreatuser" : (pJson.ntsccreatuser),
"ntsccurruser" : (pJson.ntsccurruser),
"ntsccreatdate" : (pJson.ntsccreatdate)
}
b ;23
;s rowData = ..GetDataInput(row)
s retObj.rowData = row
#; 一些提醒信息等
q retObj
}
/// Description: 校验前台传过来的数据
/// Debug: w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).ValidateSave({"rows":[{"ntscno": 6138414,"ntsctitle": "门诊病历打印提示“检查Web-Print打印插件,请稍后”,需核查","ntsctype": "质量检查-质检小组","ntsclevel": "中","ntsclevreq": "需求内容不清晰","ntsclevreqdesc": "使用环境应该描述具体菜单、安全组","ntscstratus": "公示中","ntscdelcenter": "甘青交付中心","ntscaffi": "青海组","ntscsponsor": "韩文清","ntscsponsorgroup": "青海德令哈市中医","ntscrecpient": "周玉玲","ntscrecpgroup": "电子病历技术支持","ntscassigner": "","ntsccueernt": "韩文清","ntscpubdate": 45930,"ntsccurrgroup": "青海德令哈市中医","ntsccreatuser": "王乾瞩", "ntsccurruser": "董富强","ntsccreatdate": 45908.493368055555}]})
ClassMethod ValidateSave(pJson As %DynamicObject)
{
;s ^wsh("dsad")=$lb(pJson)
;b ;22
s typeList = $lb("pop", "alert", "confirm", "terminate")
#dim currentType as %String = ""
#dim ret As %DynamicObject = {
"type": "",
"rows": []
}
s msgRowsArr = []
#dim tmpData
s rows = pJson.rows
s len = rows.%Size() - 1
for i = 0 : 1 : len {
s msgRows = []
s rowData = rows.%Get(i)
s rowIndex = rowData.rowIndex
i (rowIndex = ""){
s rowIndex = i
}
s ntscno = rowData.ntscno
i (ntscno = ""){
d PushMsg("需求序号","为空", "ntscno", "terminate")
d msgRowsArr.%Push({"rowIndex": (rowIndex + 1),"rowMsgs": (msgRows)})
continue
}
#; 唯一性
s distinctData = $lb(ntscno)
i ($d(tmpData("distntsc", distinctData), tmpI)){
d PushMsg("", "重复数据: 需求序号 不能完全相同", "ntscno", "terminate")
}
s tmpData("distntsc", distinctData) = rowIndex
i (msgRows.%Size() > 0){
d msgRowsArr.%Push({"rowIndex": (rowIndex + 1),"rowMsgs": (msgRows)})
}
}
s ret.type = currentType
s ret.rows = msgRowsArr
q ret
PushMsg(fieldDesc, info, field, type = "alert")
d msgRows.%Push({
"fieldDesc": (fieldDesc),
"type": (type),
"info":(info),
"index": (rowIndex),
"field": (field)
})
i (currentType = ""){
s currentType = type
}else{
i ($lf(typeList, type) > $lf(typeList, currentType)){
s currentType = type
}
}
q $$$OK
}
/// 保存方法,处理保存前的数据格式
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).HandleSave({"rows":[{"ntscno":355376,"ntsctitle":"住院工作月报台帐(1)","ntsctype":"质量检查-质检小组","ntsctstype":"","ntsctstext":"","ntsclevel":"","ntsclevreq":"","ntsclevreqdesc":"","ntscstratus":"创建","ntscmearn":"","ntsctrans":"","ntscdelcenter":"湖北交付中心","ntscaffi":"湖北西北组","ntscsponsor":"时培超","ntscsponsorgroup":"湖北东风集团医院","ntscrecpient":"陈乙","ntscrecpgroup":"综合查询","ntscassigner":"","ntsccueernt":"时培超","ntscpubdate":"","ntscreledate":"","ntscquaily":"","ntsccurrgroup":"湖北东风集团医院","ntsccreatuser":"苑思琦","ntsccurruser":"","ntsccreatdate":"2023-06-11"},{"ntscno":2427384,"ntsctitle":"部分退费后,本次医嘱的数量不对,已撤销的数量也不对","ntsctype":"质量检查-质检小组","ntsctstype":"","ntsctstext":"","ntsclevel":"低","ntsclevreq":"需求内容不清晰","ntsclevreqdesc":"需求各项描述都一样","ntscstratus":"创建","ntscmearn":"","ntsctrans":"","ntscdelcenter":"四川交付中心","ntscaffi":"粤北组","ntscsponsor":"朱亮","ntscsponsorgroup":"广东韶关曲江妇幼","ntscrecpient":"刘英勇","ntscrecpgroup":"医生站","ntscassigner":"","ntsccueernt":"朱亮","ntscpubdate":"","ntscreledate":"","ntscquaily":"","ntsccurrgroup":"广东韶关曲江妇幼","ntsccreatuser":"王乾瞩","ntsccurruser":"","ntsccreatdate":"2022-11-23"},{"ntscno":2922218,"ntsctitle":"检查、病理接口:报告完成检查状态未改变,需要调用产品组方法,产品组方法已经提供,需要的方案已经和王工沟通过","ntsctype":"质量检查-质检小组","ntsctstype":"","ntsctstext":"","ntsclevel":"中","ntsclevreq":"需求内容不清晰,需求格式不规范","ntsclevreqdesc":"“王工”是哪位?“按照标准版无需调用产品组方法,都是存入平台表内。”这个信息项目交付同学是否知晓或有咨询途径。","ntscstratus":"创建","ntscmearn":"","ntsctrans":"","ntscdelcenter":"安徽交付中心","ntscaffi":"安徽蚌淮组","ntscsponsor":"施方正","ntscsponsorgroup":"安徽蚌埠第二","ntscrecpient":"韩宏利","ntscrecpgroup":"数据中心技术支持","ntscassigner":"","ntsccueernt":"施方正","ntscpubdate":"","ntscreledate":"","ntscquaily":"","ntsccurrgroup":"安徽蚌埠第二","ntsccreatuser":"丁静","ntsccurruser":"","ntsccreatdate":"2023-06-21"},{"ntscno":3066467,"ntsctitle":"新增一个统计报表,报表内容如图","ntsctype":"质量检查-质检小组","ntsctstype":"","ntsctstext":"","ntsclevel":"低","ntsclevreq":"统计口径-描述不清晰,需求格式不规范","ntsclevreqdesc":"1、各项内容均一样,使用背景和环境没有说明\r\r\n2、缺少统计口径,及入参说明","ntscstratus":"创建","ntscmearn":"","ntsctrans":"","ntscdelcenter":"江西交付中心","ntscaffi":"江西赣南组","ntscsponsor":"滕辉","ntscsponsorgroup":"江西宜春丰城人民","ntscrecpient":"陈乙","ntscrecpgroup":"综合查询","ntscassigner":"","ntsccueernt":"滕辉","ntscpubdate":"","ntscreledate":"","ntscquaily":"","ntsccurrgroup":"江西宜春丰城人民","ntsccreatuser":"王乾瞩","ntsccurruser":"","ntsccreatdate":"2022-12-10"},{"ntscno":3066586,"ntsctitle":"国家抗肿瘤报表中,病理检查记录病案号部分数据取值错误,并且将门诊类型的住院号、住院次数置空;住院类型的门诊号、就诊次数置空,不要特殊字符填充","ntsctype":"质量检查-质检小组","ntsctstype":"","ntsctstext":"","ntsclevel":"低","ntsclevreq":"无附件/附件不匹配,需求格式不规范","ntsclevreqdesc":"","ntscstratus":"创建","ntscmearn":"","ntsctrans":"","ntscdelcenter":"安徽交付中心","ntscaffi":"安徽皖北组","ntscsponsor":"方浩宇","ntscsponsorgroup":"安徽颍上县人民","ntscrecpient":"潘磊1205","ntscrecpgroup":"综合查询","ntscassigner":"","ntsccueernt":"方浩宇","ntscpubdate":"","ntscreledate":"","ntscquaily":"","ntsccurrgroup":"安徽颍上县人民","ntsccreatuser":"林坤辉","ntsccurruser":"","ntsccreatdate":"2022-12-08"}],"logonUser":"20667","logonLoc":"181","logonHosp":"2","logonGroup":"33"})
ClassMethod HandleSave(pJson As %DynamicObject) As %DynamicObject
{
#dim retsult as %String = ""
ts
try {
s dataArr = pJson.rows
s dataLen = dataArr.%Size()-1
for i = 0 : 1 : dataLen {
s rowData = dataArr.%Get(i)
s result = ..SaveMainData(rowData)
q:($$$phaIsError(result))
s mainItmRowID = result
q:($$$phaIsError(result))
b ;11
}
}
catch e {
s result = ##class(PHA.COM.Err).LogErrors(e)
}
i ($$$phaIsError(result)){
tro
q ..Msg(-1, result)
}
tc:($tl > 0)
b ;22
q ..Msg(0, result, mainItmRowID)
}
/// Description: 保存
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).SaveMainData({"ntscno":6138415,"ntsctitle":"门诊病历打印提示“检查Web-Print打印插件,请稍后”,需核查","ntsctype":"质量检查-质检小组","ntsclevel":"中","ntsclevreq":"需求内容不清晰","ntsclevreqdesc":"使用环境应该描述具体菜单、安全组","ntscstratus":"公示中","ntscdelcenter":"甘青交付中心","ntscaffi":"青海组","ntscsponsor":"韩文清","ntscsponsorgroup":"青海德令哈市中医","ntscrecpient":"周玉玲","ntscrecpgroup":"电子病历技术支持","ntscassigner":"","ntsccueernt":"韩文清","ntscpubdate":45930,"ntsccurrgroup":"青海德令哈市中医","ntsccreatuser":"王乾瞩","ntsccurruser":"董富强","ntsccreatdate":45908.493368055555})
ClassMethod SaveMainData(dataObj As %DynamicObject) As %String
{
If dataObj = "" Quit "错误:参数为空"
If '$IsObject(dataObj) Quit "错误:参数不是有效对象"
Set ntscnoVal = dataObj.ntscno
If ntscnoVal = "" Quit "错误:ntscno不能为空"
Set obj = ##class(User.NTSCReqQua).%New()
s (publiy,ceart)=""
s pubdate = dataObj.ntscpubdate
s cpubdate = dataObj.ntsccreatdate
s:pubdate'="" publiy = $zdh(pubdate,3)
s:cpubdate'="" ceart = $zdh(cpubdate,3)
s obj.ntscno = dataObj.ntscno
s obj.ntsctitle = dataObj.ntsctitle
s obj.ntsctype = dataObj.ntsctype
s obj.ntsctstype = dataObj.ntsctstype
s obj.ntsctstext = dataObj.ntsctstext
s obj.ntsclevel = dataObj.ntsclevel
s obj.ntsclevreq = dataObj.ntsclevreq
s obj.ntsclevreqdesc = dataObj.ntsclevreqdesc
s obj.ntscstratus = dataObj.ntscstratus
s obj.ntscmearn = dataObj.ntscmearn
s obj.ntsctrans = dataObj.ntsctrans
s obj.ntscdelcenter = dataObj.ntscdelcenter
s obj.ntscaffi = dataObj.ntscaffi
s obj.ntscsponsor = dataObj.ntscsponsor
s obj.ntscsponsorgroup = dataObj.ntscsponsorgroup
s obj.ntscrecpient = dataObj.ntscrecpient
s obj.ntscrecpgroup = dataObj.ntscrecpgroup
s obj.ntscassigner = dataObj.ntscassigner
s obj.ntsccueernt = dataObj.ntsccueernt
s obj.ntscpubdate = publiy
s obj.ntscreledate = dataObj.ntscreledate
s obj.ntscquaily = dataObj.ntscquaily
s obj.ntsccurrgroup = dataObj.ntsccurrgroup
s obj.ntsccreatuser = dataObj.ntsccreatuser
s obj.ntsccurruser = dataObj.ntsccurruser
s obj.ntsccreatdate = ceart
b ;555
Set sc = obj.%Save()
If $$$ISERR(sc) {
Do $System.Status.DisplayError(sc)
Quit "错误:保存失败"
}
b ;666
Quit obj.%Id()
}
/// 辅助方法:回滚事务并返回错误信息
ClassMethod RollbackAndReturn(msg As %String) As %String
{
tro
Quit msg
}
/// Description: 基本数据转换成数据库可存储的类型
ClassMethod Data2Logical4Itm(dataObj)
{
q $$$OK
}
ClassMethod ValidateInputMainData(inputRow)
{
#dim result as %String = ""
try {
i (inputRow.ntscno = "") {
s result = "需求序号不能为空"
}
}
catch e {
s result = $$$phaZE
}
q:(result '= "") $$$phaError(result)
q $$$OK
}
/// Description: 基本数据转换成数据库可存储的类型
ClassMethod Data2Logical(dataObj)
{
d ..sDefinedKeyVal(dataObj, "createDate", $$$zdh(dataObj.createDate))
d ..sDefinedKeyVal(dataObj, "createTime", $$$zth(dataObj.createTime))
d ..sDefinedKeyVal(dataObj, "finishDate", $$$zdh(dataObj.finishDate))
d ..sDefinedKeyVal(dataObj, "finishTime", $$$zth(dataObj.finishTime))
d ..sDefinedKeyVal(dataObj, "auditDate", $$$zdh(dataObj.auditDate))
d ..sDefinedKeyVal(dataObj, "auditTime", $$$zth(dataObj.auditTime))
d ..sDefinedKeyVal(dataObj, "needDate", $$$zdh(dataObj.needDate))
d ..sDefinedKeyVal(dataObj, "remarks", $lfs(dataObj.remarks, ","))
d ..sDefinedKeyVal(dataObj, "mouldFlag", $$$zboolean(dataObj.mouldFlag, "Y|N"))
q $$$OK
}
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).GetMainDataRows({"stDate":"2025-09-11","endDate":"2025-10-11","Level":"","remarNo":"6138414,6139799,6216078,6215756,6216047,6215807,6215780,6215850,6216074,6215819,6215853,6215874,6215931,6216054,6115700,6122162,6139609,6147662,6148216"})
/// 为了不写重复代码,将验证列表和数据库查询集成在一个方法里
ClassMethod GetMainDataRows(pJson As %DynamicObject = "") As %DynamicArray
{
#dim retArr as %DynamicArray = []
s (pStartDate,pEndDate,pLevel,premarNo,preleth)=""
i pJson'="" s pStartDate = $$$zdh(pJson.stDate)
i pJson'="" s pEndDate = $$$zdh(pJson.endDate)
i pJson'="" s pLevel = pJson.Level
i pJson'="" s premar = pJson.remarNo
s seenNtscno = ""
s:premar'="" preleth = $l(premar,",")
i $L(premar) > 1 {
s pre = ..getJoin(premar)
s sqlCode($i(sqlCode)) = " SELECT %ID ntscID"
s sqlCode($i(sqlCode)) = " FROM NTSC_ReqQua"
s sqlCode($i(sqlCode)) = " WHERE NTSC_NO in " _ pre
}else{
/// 动态sql与global结合依然最靠谱, sql用于选择索引 SELECT * FROM NTSC_ReqQua
s sqlCode($i(sqlCode)) = " SELECT %ID ntscID"
s sqlCode($i(sqlCode)) = " FROM NTSC_ReqQua"
if (pStartDate '= ""){
s sqlCode($i(sqlCode)) = " WHERE (NTSC_CeartDate BETWEEN " _ pStartDate _ " AND " _ pEndDate _")"
}
if (pStartDate="")&&(pLevel '= ""){
s sqlCode($i(sqlCode)) = " WHERE NTSC_Level = " _ $$$quotes(pLevel)
}
if (pStartDate'="")&&(pLevel '= ""){
s sqlCode($i(sqlCode)) = " AND NTSC_Level = " _ $$$quotes(pLevel)
}
if (pStartDate="")&&(pLevel '= "")&&(premarNo '= "")&&($d(^NTSCReqQuaI("NO", $SYSTEM.SQL.Functions.ALPHAUP(premarNo)))) {
s sqlCode($i(sqlCode)) = " AND NTSC_NO = " _ $$$quotes(premarNo)
}
if (pStartDate="")&&(pLevel = "")&&(premarNo '= "")&&($d(^NTSCReqQuaI("NO", $SYSTEM.SQL.Functions.ALPHAUP(premarNo)))) {
s sqlCode($i(sqlCode)) = " WHERE NTSC_NO = " _ $$$quotes(premarNo)
}
if (pStartDate'="")&&(pLevel = "")&&(premarNo '= "")&&($d(^NTSCReqQuaI("NO", $SYSTEM.SQL.Functions.ALPHAUP(premarNo)))) {
s sqlCode($i(sqlCode)) = " AND NTSC_NO = " _ $$$quotes(premarNo)
}
if (pStartDate'="")&&(pLevel '= "")&&(premarNo '= "")&&($d(^NTSCReqQuaI("NO", $SYSTEM.SQL.Functions.ALPHAUP(premarNo)))) {
s sqlCode($i(sqlCode)) = " AND NTSC_NO = " _ $$$quotes(premarNo)
}
}
s sqlStatement = ##class(%SQL.Statement).%New()
s sqlStatus = sqlStatement.%Prepare(.sqlCode)
s sqlResult = sqlStatement.%Execute()
for {
q:('sqlResult.%Next())
s ntscID = sqlResult.%Get("ntscID")
s ntscData = $g(^NTSCReqQua(ntscID))
s rowData = ..GetMainData(ntscID)
q:(rowData.ntscno="")
s currentNtscno = rowData.ntscno
if $d(seenNtscno(currentNtscno))=0 { // 若未记录过该ntscno
d retArr.%Push(rowData)
s seenNtscno(currentNtscno) = 1 // 标记为已出现
}
}
q retArr
}
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).GetMainData("1").%ToJSON()
/// NTSCReqQuaCont实体类map集合映射处理成可识别json
ClassMethod GetMainData(ntscID) As %DynamicObject [ SqlProc ]
{
s ret = ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaContObj).reqQuaObj(ntscID)
#; 转换数据
s ret.ntscno = ret.ntscno
s ret.ntsctitle = ret.ntsctitle
s ret.ntsctype = ret.ntsctype
s ret.ntsctstype = ret.ntsctstype
s ret.ntsctstext = ret.ntsctstext
s ret.ntsclevel = ret.ntsclevel
s ret.ntsclevreq = ret.ntsclevreq
s ret.ntsclevreqdesc = ret.ntsclevreqdesc
s ret.ntscstratus = ret.ntscstratus
s ret.ntscmearn = ret.ntscmearn
s ret.ntsctrans = ret.ntsctrans
s ret.ntscdelcenter = ret.ntscdelcenter
s ret.ntscaffi = ret.ntscaffi
s ret.ntscsponsor = ret.ntscsponsor
s ret.ntscsponsorgroup = ret.ntscsponsorgroup
s ret.ntscrecpient = ret.ntscrecpient
s ret.ntscrecpgroup = ret.ntscrecpgroup
s ret.ntscassigner = ret.ntscassigner
s ret.ntsccueernt = ret.ntsccueernt
s ret.ntscpubdate = $zd(ret.ntscpubdate,3)
s ret.ntscreledate = ret.ntscreledate
s ret.ntscquaily = ret.ntscquaily
s ret.ntsccurrgroup = ret.ntsccurrgroup
s ret.ntsccreatuser = ret.ntsccreatuser
s ret.ntsccurruser = ret.ntsccurruser
s ret.ntsccreatdate = $zd(ret.ntsccreatdate,3)
q ret
}
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont).getJoin("6138414,6139799,6139044,6129854,6216078,6215756,6216047,6215807,6215780,6215850,6216074,6215819,6215853,6215874,6215931,6216054,6216057")
/// 为了不写重复代码,将验证列表id拼接成可查询字符串
ClassMethod getJoin(tempStr)
{
;s tempStr = "6138414,6139799,6139044,6129854,6216078,6215756,6216047,6215807,6215780,6215850,6216074,6215819,6215853,6215874,6215931,6216054,6216057"
s inClause = "("
while $L(tempStr) > 0 {
s currentVal = $P(tempStr, ",", 1)
s inClause = inClause _ $CHAR(34) _ currentVal _ $CHAR(34)
s tempStr = $P(tempStr, ",", 2, $L(tempStr))
i $L(tempStr) > 0 {
s inClause = inClause _ ","
}
}
s inClause = inClause _ ")"
q inClause
}
}7、保存方法的map映射类
Class NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaContObj Extends %RegisteredObject
{
/// w ##class(NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaContObj).reqQuaObj("1").%ToJSON()
ClassMethod reqQuaObj(rowID = "") [ CodeMode = objectgenerator ]
{
s dataMap = {
"ntscno": "NTSC_NO",
"ntsctitle": "NTSC_Title",
"ntsctype": "NTSC_Type",
"ntsctstype": "NTSC_TSType",
"ntsctstext": "NTSC_TSText",
"ntsclevel": "NTSC_Level",
"ntsclevreq": "NTSC_LevReq",
"ntsclevreqdesc": "NTSC_LevReqDesc",
"ntscstratus": "NTSC_LevStratus",
"ntscmearn": "NTSC_Meran",
"ntsctrans": "NTSC_Trans",
"ntscdelcenter": "NTSC_DelCenter",
"ntscaffi": "NTSC_Affil",
"ntscsponsor": "NTSC_Sponsor",
"ntscsponsorgroup": "NTSC_SpoGroup",
"ntscrecpient": "NTSC_Recipient",
"ntscrecpgroup": "NTSC_RecGroup",
"ntscassigner": "NTSC_Assigner",
"ntsccueernt": "NTSC_Current",
"ntscpubdate": "NTSC_PublicityDaye",
"ntscreledate": "NTSC_ReleaseDate",
"ntscquaily": "NTSC_Quality",
"ntsccurrgroup": "NTSC_CurrentGroup",
"ntsccreatuser": "NTSC_CeartUser",
"ntsccurruser": "NTSC_CurrentUser",
"ntsccreatdate": "NTSC_CeartDate"
}
d %code.WriteLine(" q:(rowID = """") " _ dataMap.%ToJSON())
s selectInto = ##class(PHA.COM.SQL.Json).MapJson2SelectInto(dataMap)
s sqlStr = "SELECT " _ $lts(selectInto, " INTO ") _ " FROM SQLUSER.NTSC_ReqQua where %ID = :rowID"
d %code.WriteLine(##class(PHA.COM.SQL.Generator).Select2JsonData(sqlStr))
q $$$OK
}
}8、csp页面引用的其他js方法,不能放在同一个文件中,太过庞大,excel导入插件使用公共的即可
8.1、scripts/NTSC/ReqQuaCont/loading.js 这个js主要是用于导入数据和验证的时候弹出过度动画和excel导入的日期处理。
// Excel日期转JavaScript Date(处理1900年闰年bug)
// wangsheng
// 2025-09-30
// 可以在其他页面调用的公共组件并初始化动态加载数据框
function excelDateToJsDate(excelDate) {
if (typeof excelDate !== 'number') {
const date = new Date(excelDate);
if (!isNaN(date.getTime())) return date;
return excelDate;
}
let jsDate;
if (excelDate < 60) {
jsDate = new Date(1900, 0, excelDate);
} else {
jsDate = new Date(1900, 0, excelDate - 1);
}
jsDate.setMinutes(jsDate.getMinutes() - jsDate.getTimezoneOffset());
return jsDate;
}
// 日期格式化为 “YYYY-MM-DD”
function formatDate(date) {
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}
// 创建简洁炫酷的加载动画(纯CSS实现,性能更优)
function createLoadingAnimation() {
// 清理已有加载层,避免重复
const existing = document.getElementById('loadingOverlay');
if (existing) document.body.removeChild(existing);
// 1. 遮罩层(半透明+背景模糊)
const overlay = document.createElement('div');
overlay.id = 'loadingOverlay';
overlay.style.cssText = `
position: fixed; top: 0; left: 0;
width: 100%; height: 100%;
background-color: rgba(0, 0, 0, 0.6);
display: flex; justify-content: center; align-items: center;
z-index: 9999;
backdrop-filter: blur(2px); /* 背景模糊增强质感 */
`;
// 2. 加载容器(卡片式设计+阴影)
const container = document.createElement('div');
container.style.cssText = `
background: white; padding: 24px 32px;
border-radius: 10px; text-align: center;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
min-width: 300px;
`;
// 3. 旋转动画(CSS关键帧实现)
const loader = document.createElement('div');
loader.style.cssText = `
width: 48px; height: 48px;
margin: 0 auto 16px;
border: 4px solid #f3f3f3;
border-top: 4px solid #409eff;
border-radius: 50%;
animation: spin 1s linear infinite;
`;
// 4. 进度文本(实时更新百分比)
const text = document.createElement('p');
text.id = 'loadingText';
text.textContent = '正在加载中... 0%';
text.style.cssText = `
margin: 8px 0; font-size: 16px;
color: #333; font-weight: 500;
`;
// 5. 进度条(渐变填充+平滑过渡)
const progressBar = document.createElement('div');
progressBar.style.cssText = `
height: 6px; width: 100%;
background: #eaeaea; border-radius: 3px;
overflow: hidden; margin-top: 12px;
`;
const barFill = document.createElement('div');
barFill.id = 'loadingBarFill';
barFill.style.cssText = `
height: 100%; width: 0%;
background: linear-gradient(90deg, #409eff, #67c23a);
transition: width 0.3s ease;
`;
progressBar.appendChild(barFill);
// 6. 动画样式(旋转关键帧)
const style = document.createElement('style');
style.textContent = `
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
`;
// 组合元素并插入页面
container.appendChild(loader);
container.appendChild(text);
container.appendChild(progressBar);
overlay.appendChild(container);
document.head.appendChild(style);
document.body.appendChild(overlay);
// 返回控制方法(更新、销毁)
return {
setTotal: function(total) {
this.total = total;
},
update: function(current) {
if (!this.total) return;
const percent = Math.min(Math.round((current / this.total) * 100), 100);
document.getElementById('loadingText').textContent = `正在加载中... ${percent}%`;
document.getElementById('loadingBarFill').style.width = `${percent}%`;
},
destroy: function() {
overlay.style.opacity = '0';
setTimeout(() => {
if (document.body.contains(overlay)) {
document.body.removeChild(overlay);
}
}, 300);
}
};
}8.2、scripts/NTSC/ReqQuaCont/com.js 这个js是公共组件封装,部分代码用其他页面已经写好的,不然重新写太费时间。
/**
* 需求质控列表 - 通用
* csp: csp/NTSC/NTSCReqQuaCont.csp
* js: scripts/NTSC/ReqQuaCont/com.js
*/
//
var PLAN_COM = {
ApiClass: 'NTSC.Pharmacy.ReqQuaCont.NTSCReqQuaCont',
AppCode: 'DHCSTPURPLANAUDIT',
AppComCode: 'DHCSTCOMMON',
GetChangedRows: function (domID) {
return PHA_GridEditor.GetChangedRows(domID);
},
Invoke: function (apiMethod, pJson, callback) {
// 仅仅用于处理保存等操作
this.AppendLogonData(pJson);
PHA.CM(
{
pClassName: PLAN_COM.ApiClass,
pMethodName: apiMethod,
pJson: JSON.stringify(pJson)
},
function (retData) {
callback(PLAN_COM.FmtApiReturn(retData));
},
function () {
callback('访问错误');
}
);
},
InvokeSyn: function (apiMethod, pJson) {
this.AppendLogonData(pJson);
var retData = PHA.CM(
{
pClassName: PLAN_COM.ApiClass,
pMethodName: apiMethod,
pJson: JSON.stringify(pJson)
},
false
);
var apiRet = PLAN_COM.FmtApiReturn(retData);
if (typeof apiRet === 'string') {
PHA.Alert('提示', apiRet, 'error');
}
return apiRet;
},
ApiMethods: {
Save: 'HandleSave',
SaveAsMould: 'HandleSaveAsMould',
Delete: 'HandleDeleteMain',
Finish: 'HandleFinish',
FinishCancel: 'HandleFinishCancel',
Audit: 'HandleAudit',
AuditCancel: 'HandleAuditCancel',
AuditRefuse: 'HandleAuditRefuse',
DeleteItm: 'HandleDeleteItm',
DeleteItms: 'HandleDeleteItms',
Merge: 'HandleMerge'
},
Fmt2ApiMethod: function (pHandleCode) {
var apiMethod = this.ApiMethods[pHandleCode];
if (apiMethod === '') {
PHA.Alert('致命错误', pHandleCode + '没有可供调用的程序');
}
return apiMethod;
},
GetMainData: function (planID) {
return this.InvokeSyn('GetMainData', { planID: planID });
},
GetItmData: function (planItmID) {
return this.InvokeSyn('GetMainData', { planItmID: planItmID });
},
QueryMainGrid: function (domID, pJson) {
var $grid = $('#' + domID);
//if(!pJson || pJson == undefined) return;
if(pJson != undefined)
{var pJsonStr = JSON.stringify(pJson).replace(/(-q)|(-merge)/g, '');
}
$grid.datagrid('options').url = PHA.$URL;
$grid.datagrid('query', {
pClassName: PLAN_COM.ApiClass,
pMethodName: 'GetMainDataRows',
pJson: pJsonStr,
pPlug: 'datagrid'
});
},
QueryItmGrid: function (domID, pJson) {
var $grid = $('#' + domID);
var pJsonStr = JSON.stringify(pJson).replace(/-q/g, '');
$grid.datagrid('options').url = PHA.$URL;
$grid.datagrid('query', {
pClassName: PLAN_COM.ApiClass,
pMethodName: 'GetItmDataRows',
pJson: pJsonStr,
pPlug: 'datagrid'
});
},
QueryGrid: function (domID, pMethodName, pJson) {
var $grid = $('#' + domID);
var pJsonStr = JSON.stringify(pJson).replace(/-q/g, '');
$grid.datagrid('options').url = PHA.$URL;
$grid.datagrid('query', {
pClassName: PLAN_COM.ApiClass,
pMethodName: pMethodName,
pJson: pJsonStr,
pPlug: 'datagrid'
});
},
LoadData: function (domID, qJson) {
qJson.pClassName = PLAN_COM.ApiClass;
PHA_COM.LoadData(domID, qJson);
},
/**
* 模块参数
*/
GetSettings: function () {
// 单例模式就需要全局变量控
var planSettings = PHA_COM.ParamProp('DHCSTPURPLANAUDIT');
var comSettings = PHA_COM.ParamProp('DHCSTCOMMON');
return {
App: planSettings,
Com: comSettings,
DefaultData: {
startDate: PHA_UTIL.GetDate('t' + planSettings.DefaStartDate),
endDate: PHA_UTIL.GetDate('t' + planSettings.DefaEndDate),
loc: session['LOGON.CTLOCID']
}
};
},
TrimDelim: function (str) {
return str.replace(/-\d*\^/g, '');
},
FmtApiReturn: function (retData) {
if (retData.success === 0 || retData.code < 0) {
return PLAN_COM.TrimDelim(retData.msg);
}
return retData;
},
FmtApiInput: function (retData) {},
ValidateGridData: function (data) {
if (data.success === 0) {
PHA.Alert('提示', data.msg, 'error');
return false;
}
return true;
},
/**
* 校验返回值, 如果错误则提醒, 此类为异常报错, 需要为alert形式
* @param {*} data 后台的原始返回值
* @returns
*/
ValidateApiReturn: function (data) {
var ret = this.FmtApiReturn(data);
if (typeof ret === 'string') {
PHA.Alert('提示', ret, 'error');
return false;
}
return true;
},
/**
* 给传到后台的程序追加session信息, 建议取不到session时, 以此为准
* @param {} jsonObj
*/
AppendLogonData: function (jsonObj) {
return PHA_COM.AppendLogonData(jsonObj);
},
Top: {
Const: ['PHA_IN_PLAN_ID'],
Set: function (key, value) {
if (!top.PHA_IN_PLAN) {
top.PHA_IN_PLAN = {};
}
top.PHA_IN_PLAN[key] = value;
},
Get: function (key, clearFlag) {
if (top.PHA_IN_PLAN) {
var ret = top.PHA_IN_PLAN[key] || ''; // 对象需要深拷贝
if (clearFlag === true) {
delete top.PHA_IN_PLAN[key];
}
return ret;
}
return '';
}
},
GetSelectedRow: function (target, field) {
return PHA_COM.GetSelectedRow(target, field);
},
GetSelectedRowIndex: function (target) {
return PHA_COM.GetSelectedRowIndex(target);
},
Condition: function (target, type, options) {
return PHA_COM.Condition(target, type, options);
},
UpdateRow: function (target, rowIndex, pJson) {
var rowData = this.InvokeSyn('GetMainData', pJson);
$(target).datagrid('updateRow', {
index: rowIndex,
row: rowData
});
},
/**
* 集成处理某个模块的页面相关控制, 有些改动不需要每个界面都调试, 如面板高度等
* @param {} cspName 页面csp全称
*/
SetPage: function (cspName) {
cspName = cspName || App_MenuCsp;
switch (cspName) {
case 'pha.in.v3.plan.audit.csp':
PHA_COM.ResizePanel({
layoutId: 'layout-plan-audit',
region: 'north',
height: 0.5
});
break;
case 'pha.in.v3.plan.query.csp':
PHA_COM.ResizePanel({
layoutId: 'layout-plan-query',
region: 'north',
height: 0.5
});
break;
case 'pha.in.v3.plan.create.csp':
PHA_COM.SetPanel('#layout-plan-create-panel', $('#layout-plan-create-panel').panel('options').title);
// $('#btnPrint-q').parent().hide()
break;
case 'pha.in.v3.plan.createbystock.csp':
PHA_COM.SetPanel('#layout-plan-createbystock-panel', $('#layout-plan-createbystock-panel').panel('options').title);
break;
case 'pha.in.v3.plan.createbyconsume.csp':
PHA_COM.SetPanel('#layout-plan-createbyconsume-panel', $('#layout-plan-createbyconsume-panel').panel('options').title);
break;
case 'pha.in.v3.plan.createbyreq.csp':
PHA_COM.ResizePanel({
layoutId: 'layout-plan-createbyreq',
region: 'north',
height: 0.5
});
break;
default:
break;
}
/**
* 通用快捷键, 模块内的至少应该一致
* @fix 药品下拉弹窗清除了原注册的快捷键
* @fix 如何按按dom区域绑定, 如弹出框与原界面有类似操作
*/
PHA_EVENT.Key([
// ['btnClean', 'alt+c'], // clean
// [$('#btnSelect').length > 0 ? 'btnSelect' : 'btnFind', 'alt+f'], // find
['btnAddItm', 'alt+a'], // add
['btnDeleteItm', 'alt+d'], // delete
['btnAddItm', 'alt+='], // +
['btnDeleteItm', 'alt+-'], // -
['btnDelete', 'alt+shift+d'], // 上档delete, 加强版
['btnSave', 'ctrl+s'],
['btnClean', 'alt+c'],
['btnFind', 'alt+f']
]);
$('[id^=qCondition] a').width('100%');
PHA.SetRequired($('[id^=qCondition] [data-pha]'));
},
ControlOperation: function (handleObj) {
PHA_COM.ControlOperation(handleObj);
},
ValidatePrice: function (val) {
var msg = '请输入大于或等于0的数字';
if (_.isLikeNumber(val) === false) {
return msg;
}
if (parseFloat(val) < 0) {
return msg;
}
return true;
},
ValidateQty: function (val) {
var msg = '请输入大于0的数字';
if (_.isLikeNumber(val) === false) {
return msg;
}
if (parseFloat(val) <= 0) {
return msg;
}
return true;
},
Calc: function () {},
SumGridData: function (target, fieldArr) {
return PHA_COM.SumGridData(target, fieldArr);
},
SumGridFooter: function (target, fieldArr) {
PHA_COM.SumGridFooter(target, fieldArr);
},
HandleCheckStyle: function (target, method, rowIndex) {
PHA_COM.HandleCheckStyle(target, method, rowIndex);
},
GridFinalDone: function (target) {
PHA_GridEditor.GridFinalDone(target, 'inciCode');
},
Print: function (planID) {
planID = planID || '';
if (planID === '') {
PHA.Popover({
msg: '请先选择需要打印的单据',
type: 'info'
});
return;
}
PLAN_PRINT.Print(planID);
return;
// 如下是xml模板形式, 但调整格式还不如直接那代码来的快
var printStyle = PHA_COM.PrintStyle;
PRINTCOM.XML({
printBy: 'lodop',
XMLTemplate: 'PHAINPLAN',
dataOptions: {
ClassName: 'PHA.IN.PLAN.Api',
MethodName: 'GetPrintData',
pJsonStr: JSON.stringify({
planID: planID,
printUserName: session['LOGON.USERNAME']
})
},
// 分页位置
page: $.extend(printStyle.page, {}),
// 边框样式
listBorder: $.extend(printStyle.listBorder, {}),
// 金额居右
listColAlign: $.extend(printStyle.listColAlign, {}),
// 自适应底部签名
aptListFields: printStyle.FixListFields(['printInfo', 'createUserName', 'auditUserName']) //,
// 结束页签名
// endPageFields: printStyle.FixListFields(['printInfo', 'createUserName', 'auditUserName'])
});
},
Copy: function (pJson, callback) {
PLAN_COM.Invoke('HandleCopy', pJson, function (retData) {
callback(retData);
});
},
GetWindowId4Event: function () {
return $(window.event.target).closest('.js-pha-com-window-sign').attr('id') || '';
},
DeleteJsonKeys: function (dataObj, delFields) {
for (var i = 0, length = delFields.length; i < length; i++) {
delete dataObj[delFields[i]];
}
},
SetKeyValue2Null: function (dataObj, delFields) {
for (var i = 0, length = delFields.length; i < length; i++) {
dataObj[delFields[i]] = '';
}
}
};
// 集成
$.extend($.fn.validatebox.defaults.rules, {
planQty: {
message: '请输入大于0的数字',
validator: function (value) {
if (_.isLikeNumber(value) === false) {
return false;
}
if (parseFloat(value) < 0) {
return false;
}
return true;
}
},
planPrice: {
message: '请输入大于等于0的数字',
validator: function (value) {
if (_.isLikeNumber(value) === false) {
return false;
}
if (parseFloat(value) < 0) {
return false;
}
return true;
}
}
});8.3、scripts/NTSC/ReqQuaCont/compent.js 这个js是页面表头查询条件的封装
/**
* 需求质控列表通用组件
* scripts/NTSC/ReqQuaCont/compent.js
*/
var PLAN_COMPONENTS = function () {
var components = {
Level: function (domID, options) {
options = options || {};
this.LevelStatus(domID, options);
},
LevelStatus : function(domId, des){
PHA.ComboBox(domId, {
width: 155,
panelHeight: 'auto',
data: [
{ RowId: '高', Description: $g('高') },
{ RowId: '中', Description: $g('中') },
{ RowId: '低', Description: $g('低') },
]
});
},
Date: function (domID) {
PHA.DateBox(domID, {});
$('#' + domID).datebox('setValue', 't');
},
Remarks: function (domID) {
PHA.ValidateBox(domID, {});
$('#' + domID).attr('data-pha', ['class: "hisui-validatebox"', 'clear: true', 'query: true'].join(','));
},
ItmGrid: function (domID, opts) {
var columnsObj = this.ItmGridColmuns(domID);
var dataGridOption = {
url: '',
exportXls: false,
columns: opts.columns ? opts.columns : columnsObj.columns,
frozenColumns: opts.frozenColumns ? opts.frozenColumns : columnsObj.frozenColumns,
toolbar: [],
pageNumber: 1,
pageSize: 100,
rownumbers: true,
pagination: false,
autoSizeColumn: true,
shiftCheck: true,
singleSelect: true,
checkOnSelect: false, // 互不干扰, 应保持输入与勾选分开, 但是勾选还需要能分出信息
selectOnCheck: false,
showFooter: true,
showComCol: true,
footerSumFields: ['rpAmt', 'spAmt'],
editFieldSort: ['inci', 'qty', 'vendor', 'carrier', 'reqLoc', 'rp'],
onLoadSuccess: function (data) {
PHA_GridEditor.End(this.id);
PLAN_COM.SumGridFooter('#' + this.id, ['rpAmt', 'spAmt']);
}
};
PHA.Grid(domID, $.extend(dataGridOption, opts));
var eventClassArr = ['pha-grid-a js-grid-inciCode','pha-grid-a js-grid-hospQty'];
PHA.GridEvent(domID, 'click', eventClassArr, function (rowIndex, rowData, className) {
if (className.indexOf('js-grid-inciCode') >= 0) {
//PHA_UX.DrugDetail({}, { inci: rowData.inci });
PHA_UX.InciRecList({}, { inci: rowData.inci });
return;
}
else if(className.indexOf('js-grid-hospQty') >= 0) {
//PHA_UX.DrugDetail({}, { inci: rowData.inci });
PHA_UX.HospInciStock({},{
inci: rowData.inci,
inclb: rowData.inclb,
inciDesc: rowData.inciDesc
});
return;
}
},
function(){PHA_UX.HospInciStock({},{},"close")}
);
},
ItmGridColmuns: function (gridID) {
gridID = gridID || 'gridItm';
// 解决editor内this不统一无法正常获取表格属性的问题
function GridOptions() {
return {
gridID: gridID,
$grid: $('#' + gridID)
};
}
var frozenColumns = [[ ] ];
var columns = [[ ]];
return {
frozenColumns: frozenColumns,
columns: columns
};
},
MainGrid: function (domID, opts) {
var singleSelect = ('singleSelect' in opts) ? opts.singleSelect : true;
var columnsObj = this.MainGridColmuns(singleSelect);
var dataGridOption = {
url: '',
exportXls: false,
columns: columnsObj.columns,
frozenColumns: columnsObj.frozenColumns,
toolbar: [],
pageNumber: 1,
pageSize: 100,
autoSizeColumn: true,
isAutoShowPanel: false,
rownumbers: true,
loadFilter: function (data) {
if (data.success === 0) {
PHA.Alert('提示', data.msg, 'warning');
} else {
if (data.rows.length > 0) {
if (typeof data.rows[0] === 'string') {
PHA.Alert('提示', data.rows[0], 'warning');
}
}
}
return data;
}
};
PHA.Grid(domID, $.extend(dataGridOption, opts));
// 时间轴
PHA.GridEvent(domID, 'click', ['pha-grid-a js-grid-planNo'], function (rowIndex, rowData, className) {
if (className === 'pha-grid-a js-grid-planNo') {
PHA_UX.BusiTimeLine(
{},
{
busiCode: 'PLAN',
pointer: rowData.planID
}
);
}
},
function(){
PHA_UX.BusiTimeLine({},{},"close")
});
},
MainGridColmuns: function (singleSelect) {
var frozenColumns = [[ ]];
if (!singleSelect) { // 不是单行选择,则为多选
frozenColumns[0].unshift({
field: 'tSelect',
checkbox: true
})
}
var columns = [[ ]];
return {
frozenColumns: frozenColumns,
columns: columns
};
},
PlanInfo: function () {},
Pop: function (msg, type) {
type = type || 'info';
PHA.Popover({
msg: msg,
type: type
});
}
};
return function (type) {
var pParams = [].slice.call(arguments, 1, arguments.length);
// 注意apply 第一个参数this的变化, 此处默认this指window, 因此做改动
return components[type].apply(components, pParams);
};
};
评论