{"Message":"1. 增加项目负荷页面;\r\n2. 增加任务详情页的折叠功能;","MessageType":2,"Modules":[{"State":1,"Type":1,"Name":"PCPage/任务-任务信息"},{"State":1,"Type":1,"Name":"PCPage/任务-侧栏"},{"State":1,"Type":1,"Name":"PCPage/任务-关联资源"},{"State":1,"Type":1,"Name":"PCPage/任务-基本信息"},{"State":1,"Type":1,"Name":"PCPage/任务-子任务列表"},{"State":1,"Type":1,"Name":"PCPage/任务-工时"},{"State":1,"Type":1,"Name":"PCPage/任务-进展"},{"State":1,"Type":1,"Name":"PCPage/任务首页"},{"State":1,"Type":1,"Name":"PCPage/MD编辑器"},{"State":1,"Type":1,"Name":"PCPage/项目概况"},{"State":1,"Type":9,"Name":"Theme"},{"State":1,"Type":12,"Name":"CustomLibrary"},{"State":1,"Type":40,"Name":"Plugin"},{"State":3,"Type":7,"Name":"Table/任务评论表"},{"State":3,"Type":31,"Name":"UserControlPage/评论组件"},{"State":3,"Type":31,"Name":"UserControlPage/发表评论组件"},{"State":3,"Type":38,"Name":"Image/清空.svg"},{"State":3,"Type":1,"Name":"PCPage/任务部分"},{"State":3,"Type":15,"Name":"ServerCommand/提交任务评论"},{"State":3,"Type":38,"Name":"Image/图片.svg"},{"State":3,"Type":38,"Name":"Image/成功.svg"},{"State":3,"Type":38,"Name":"Image/垃圾桶.svg"},{"State":3,"Type":38,"Name":"Image/成功1.svg"},{"State":3,"Type":38,"Name":"Image/展开1.svg"},{"State":3,"Type":38,"Name":"Image/错误.svg"},{"State":3,"Type":38,"Name":"Image/收起.svg"},{"State":3,"Type":38,"Name":"Image/项目1.svg"},{"State":3,"Type":38,"Name":"Image/简介.svg"},{"State":3,"Type":38,"Name":"Image/项目2.svg"},{"State":3,"Type":38,"Name":"Image/时间1.svg"},{"State":3,"Type":38,"Name":"Image/报告.svg"},{"State":3,"Type":1,"Name":"PCPage/项目负荷"},{"State":3,"Type":1,"Name":"PCPage/项目负荷子页面"}],"Version":"v1"}
This commit is contained in:
375
UserFile/CustomFormula.js
Normal file
375
UserFile/CustomFormula.js
Normal file
@@ -0,0 +1,375 @@
|
||||
//返回时间个性化文本
|
||||
function FRIENDLYTIMEFunction() {
|
||||
this.name = 'FRIENDLYTIME';
|
||||
this.maxArgs = 1;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
FRIENDLYTIMEFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
FRIENDLYTIMEFunction.prototype.evaluate = function () {
|
||||
var timeStr = arguments[0];
|
||||
// 将时间字符串转换为 Date 类型
|
||||
let dateTime;
|
||||
if (/^\d+$/.test(timeStr)) {
|
||||
// 如果是时间戳
|
||||
if (timeStr.length === 10) {
|
||||
dateTime = new Date(timeStr * 1000); // 10位时间戳
|
||||
} else if (timeStr.length === 13) {
|
||||
dateTime = new Date(timeStr); // 13位时间戳
|
||||
} else {
|
||||
return timeStr; // 时间戳格式错误
|
||||
}
|
||||
} else {
|
||||
dateTime = new Date(timeStr);
|
||||
}
|
||||
|
||||
if (!dateTime || isNaN(dateTime.getTime())) {
|
||||
return timeStr; // 如果时间字符串无效,则直接返回
|
||||
}
|
||||
|
||||
// 计算当前时间与入参时间的时间差
|
||||
const now = new Date();
|
||||
const diff = now.getTime() - dateTime.getTime();
|
||||
|
||||
// 根据时间差计算出更友好的显示文本
|
||||
let result;
|
||||
if (diff < 0) {
|
||||
// 未来时间
|
||||
result = "未来时间";
|
||||
} else if (diff < 60 * 5000) {
|
||||
// 一分钟内
|
||||
result = "刚刚";
|
||||
} else if (diff < 60 * 60 * 1000) {
|
||||
// 一小时内
|
||||
const minutes = Math.floor(diff / (60 * 1000));
|
||||
result = `${minutes}分钟前`;
|
||||
} else if (diff < 24 * 60 * 60 * 1000) {
|
||||
// 一天内
|
||||
const hours = Math.floor(diff / (60 * 60 * 1000));
|
||||
result = `${hours}小时前`;
|
||||
} else if (diff < 7 * 24 * 60 * 60 * 1000) {
|
||||
// 一周内
|
||||
const day = dateTime.getDay();
|
||||
const weekDays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
|
||||
result = `${weekDays[day]} ${dateTime.toLocaleTimeString()}`;
|
||||
} else {
|
||||
// 一周之前
|
||||
result = dateTime.toLocaleString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("FRIENDLYTIME", new FRIENDLYTIMEFunction());
|
||||
|
||||
|
||||
//提取模板字符串
|
||||
function GETTEMPLATEFunction() {
|
||||
this.name = 'GETTEMPLATE';
|
||||
this.maxArgs = 99;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
GETTEMPLATEFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
GETTEMPLATEFunction.prototype.evaluate = function () {
|
||||
const regex = /{{(.*?)}}/g;
|
||||
const tempResults = [];
|
||||
for (let leng = 0; leng < arguments.length; leng++) {
|
||||
const str = arguments[leng];
|
||||
while ((match = regex.exec(str)) !== null) {
|
||||
tempResults.push(match[1]);
|
||||
}
|
||||
}
|
||||
return tempResults.join(",");
|
||||
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("GETTEMPLATE", new GETTEMPLATEFunction());
|
||||
|
||||
|
||||
|
||||
//转换数值到中文大写金额
|
||||
function ToChineseCurrencyFunction() {
|
||||
this.name = 'ToChineseCurrency';
|
||||
this.maxArgs = 1;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
ToChineseCurrencyFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
ToChineseCurrencyFunction.prototype.evaluate = function () {
|
||||
var num = parseFloat(arguments[0]);
|
||||
const fraction = ['角', '分'];
|
||||
const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
|
||||
const unit = [['元', '万', '亿'], ['', '拾', '佰', '仟']];
|
||||
let head = num < 0 ? '欠' : '';
|
||||
num = Math.abs(num).toFixed(2);
|
||||
let s = '';
|
||||
for (let i = 0; i < fraction.length; i++) {
|
||||
s += (digit[Math.floor(num * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
|
||||
}
|
||||
|
||||
if (s === '') {
|
||||
s = '整';
|
||||
}
|
||||
num = Math.floor(num);
|
||||
for (let i = 0; i < unit[0].length && num > 0; i++) {
|
||||
let p = '';
|
||||
for (let j = 0; j < unit[1].length && num > 0; j++) {
|
||||
p = digit[num % 10] + unit[1][j] + p;
|
||||
num = Math.floor(num / 10);
|
||||
}
|
||||
s = p + unit[0][i] + s;
|
||||
}
|
||||
return head + s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整');
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("ToChineseCurrency", new ToChineseCurrencyFunction());
|
||||
|
||||
|
||||
|
||||
//获取JSON属性值
|
||||
function GetJsonValueFunction() {
|
||||
this.name = 'GetJsonValue';
|
||||
this.maxArgs = 2;
|
||||
this.minArgs = 2;
|
||||
}
|
||||
GetJsonValueFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
GetJsonValueFunction.prototype.evaluate = function () {
|
||||
var jsonstr = arguments[0];
|
||||
var keyname = arguments[1];
|
||||
var json = {};
|
||||
// 如果参数是字符串,则将其转换为JSON对象
|
||||
if (typeof jsonstr === 'string') {
|
||||
json = JSON.parse(json);
|
||||
}
|
||||
|
||||
// 访问指定属性值
|
||||
return json[keyname];
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("GetJsonValue", new GetJsonValueFunction());
|
||||
|
||||
|
||||
//计算税额
|
||||
function CalculateFunction() {
|
||||
this.name = 'Calculate';
|
||||
this.minArgs = 2;
|
||||
this.maxArgs = 4;
|
||||
}
|
||||
CalculateFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
CalculateFunction.prototype.evaluate = function () {
|
||||
var Amount = arguments[0];//开票金额
|
||||
var TaxRate = arguments[1];//税率
|
||||
var DiscountAmount = arguments[2] || 0;//折扣金额
|
||||
var IsTaxIncluded = Boolean(arguments[3]);//是否含税
|
||||
|
||||
var totalTaxAmount; //税额
|
||||
var noTaxAmount; //未税金额
|
||||
var totalAmount; //价税合计
|
||||
|
||||
function run(amount, taxrate, istaxincluded) {
|
||||
var totalTaxAmount; //税额
|
||||
var noTaxAmount; //未税金额
|
||||
var totalAmount; //价税合计
|
||||
|
||||
if (istaxincluded) {
|
||||
noTaxAmount = amount / (1 + taxrate);
|
||||
totalTaxAmount = amount - noTaxAmount;
|
||||
totalAmount = amount;
|
||||
} else {
|
||||
noTaxAmount = amount;
|
||||
totalTaxAmount = amount * taxrate;
|
||||
totalAmount = amount + totalTaxAmount;
|
||||
}
|
||||
|
||||
return [noTaxAmount.toFixed(2), totalTaxAmount.toFixed(2), totalAmount.toFixed(2)]
|
||||
}
|
||||
|
||||
var result_A = run(Amount, TaxRate, IsTaxIncluded);
|
||||
var result_B = run(DiscountAmount, TaxRate, IsTaxIncluded);
|
||||
|
||||
var result = {
|
||||
"未税金额": result_A[0] - result_B[0],
|
||||
"税额": result_A[1] - result_B[1],
|
||||
"价税合计": result_A[2] - result_B[2],
|
||||
};
|
||||
console.log(result);
|
||||
return result;
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("Calculate", new CalculateFunction());
|
||||
|
||||
|
||||
|
||||
//获取页面所有有效单元格的值,并组成JSON
|
||||
function CELLSVALUEFunction() {
|
||||
//参数一:是否返回文本,参数二:指定表名,参数三:是否返回数组
|
||||
this.name = 'CELLSVALUE';
|
||||
this.maxArgs = 3;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
CELLSVALUEFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
CELLSVALUEFunction.prototype.evaluate = function () {
|
||||
|
||||
try {
|
||||
//var page = Forguncy.Page._elements._cells[0];
|
||||
var subPageInfos = Forguncy.Page._elements._cells[0]._cellType.subPageInfos;
|
||||
if (!subPageInfos) return null
|
||||
var obj = {};
|
||||
subPageInfos.forEach(el => {
|
||||
el.childrens.forEach(child => {
|
||||
if (child.bindingInfo) {
|
||||
if (arguments.length == 1 || arguments[1] == "" || child.bindingInfo.TableName == arguments[1]) {
|
||||
obj[child.bindingInfo.ColumnName] = child._value;
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
if (arguments[2]) {
|
||||
return [obj];
|
||||
} else {
|
||||
return arguments[0] ? JSON.stringify(obj) : obj;
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("CELLSVALUE", new CELLSVALUEFunction());
|
||||
|
||||
|
||||
|
||||
//检测字符串是否在对象里面,参数说明:数据,字段名,查找值
|
||||
function TEXTINOBJFunction() {
|
||||
this.name = 'TEXTINOBJ';
|
||||
this.maxArgs = 3;
|
||||
this.minArgs = 3;
|
||||
}
|
||||
TEXTINOBJFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
TEXTINOBJFunction.prototype.evaluate = function () {
|
||||
return JSON.parse(arguments[0]).filter((item) => { return item[arguments[1]] == arguments[2] }).length;
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("TEXTINOBJ", new TEXTINOBJFunction());
|
||||
|
||||
|
||||
//检测字符串是否在里面,逗号分割文本,查找值
|
||||
function INARRAYFunction() {
|
||||
this.name = 'INARRAY';
|
||||
this.maxArgs = 2;
|
||||
this.minArgs = 2;
|
||||
}
|
||||
INARRAYFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
INARRAYFunction.prototype.evaluate = function () {
|
||||
return arguments[0].split(',').indexOf(arguments[1]) != -1 ? 1 : 0;
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("INARRAY", new INARRAYFunction());
|
||||
|
||||
|
||||
// 获取当前页面网址
|
||||
function GETBASEURLFunction() {
|
||||
this.name = 'GETBASEURL';
|
||||
this.maxArgs = 1;
|
||||
this.minArgs = 0;
|
||||
}
|
||||
GETBASEURLFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
GETBASEURLFunction.prototype.evaluate = function () {
|
||||
if (arguments[0]) {
|
||||
return location[arguments[0]]
|
||||
} else {
|
||||
return location.href
|
||||
}
|
||||
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("GETBASEURL", new GETBASEURLFunction());
|
||||
|
||||
|
||||
//合并数组
|
||||
function MERGEARRAYFunction() {
|
||||
this.name = 'MERGEARRAY';
|
||||
this.maxArgs = 99;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
MERGEARRAYFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
MERGEARRAYFunction.prototype.evaluate = function () {
|
||||
function merge(total, item) {
|
||||
return item != null ? total.concat(item) : total
|
||||
}
|
||||
return Array.from(new Set(new Array(...arguments).reduce(merge, [])))
|
||||
}
|
||||
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("MERGEARRAY", new MERGEARRAYFunction());
|
||||
|
||||
// 分拆文本为数组
|
||||
function SPLITTOARRAYFunction() {
|
||||
this.name = 'SPLITTOARRAY';
|
||||
this.maxArgs = 2;
|
||||
this.minArgs = 2;
|
||||
}
|
||||
SPLITTOARRAYFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
SPLITTOARRAYFunction.prototype.evaluate = function () {
|
||||
var str = arguments[0]
|
||||
var q = arguments[1]
|
||||
return str.split(q)
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("SPLITTOARRAY", new SPLITTOARRAYFunction());
|
||||
|
||||
|
||||
//合并分割文本并去重
|
||||
function unique(arr) {
|
||||
return Array.from(new Set(arr))
|
||||
}
|
||||
function ARRYJOINFunction() {
|
||||
this.name = 'ARRYJOIN';
|
||||
this.maxArgs = 99;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
ARRYJOINFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
ARRYJOINFunction.prototype.evaluate = function (args) {
|
||||
var newArray = [];
|
||||
for (let index = 0; index < arguments.length; index++) {
|
||||
newArray.push(arguments[index])
|
||||
}
|
||||
|
||||
var text = unique(newArray.join().split(",")).join()
|
||||
return text
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("ARRYJOIN", new ARRYJOINFunction());
|
||||
|
||||
//获取分割后字符串数量
|
||||
function SPLITCONTAFunction() {
|
||||
this.name = 'SPLITCONTA';
|
||||
this.maxArgs = 99;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
SPLITCONTAFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
SPLITCONTAFunction.prototype.evaluate = function () {
|
||||
var length_element = 0
|
||||
for (let leng = 0; leng < arguments.length; leng++) {
|
||||
const element = arguments[leng];
|
||||
if (element != null) {
|
||||
length_element += element.split(",").length;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return length_element;
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("SPLITCONTA", new SPLITCONTAFunction());
|
||||
|
||||
//生成二维码图片
|
||||
function QRFunction() {
|
||||
this.name = 'QR';
|
||||
this.maxArgs = 3;
|
||||
this.minArgs = 1;
|
||||
}
|
||||
QRFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
|
||||
QRFunction.prototype.evaluate = function () {
|
||||
if (arguments[0]) {
|
||||
var qr = new QRious();
|
||||
qr.background = 'white';
|
||||
qr.backgroundAlpha = 1.0;
|
||||
qr.foreground = 'black';
|
||||
qr.foregroundAlpha = 1;
|
||||
qr.level = 'L';
|
||||
qr.padding = arguments[2] ?? null;
|
||||
qr.size = arguments[1] ?? 200;
|
||||
qr.value = arguments[0];
|
||||
qr.mime = "image/png";
|
||||
return qr.toDataURL();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("QR", new QRFunction());
|
||||
Reference in New Issue
Block a user