20260808172946

This commit is contained in:
oneao committed 2026-08-08 17:29:51 +08:00
1 parent 4fbfea82f2
commit d72ca4193d
293 files changed
+37523 -73467

No files matched your search

+12 -4
View File
@@ -1,11 +1,13 @@
// src/utils/axios.js
import axios from "axios";
import { useUserStore } from "@/store";
import { ElMessage } from "element-plus";
import router from "@/router";
const instance = axios.create({
//baseURL: "http://localhost:8089/api", // 后端接口地址
baseURL: 'http://192.168.1.177:8089/api', // 后端接口地址
// baseURL: "http://192.168.1.137:8089/api",
baseURL: "http://localhost:8089/api", // 后端接口地址
// baseURL: "http://192.168.1.137:8089/api", // 后端接口地址
// baseURL: "http://192.168.1.177:8089/api",
// baseURL: '/api', // 后端接口地址
timeout: 30000,
});
@@ -15,7 +17,7 @@ instance.interceptors.request.use(
(config) => {
const userStore = useUserStore();
if (userStore.isLogined()) {
config.headers.Authorization = `Bearer ${userStore.userInfo.token}`;
config.headers.Authorization = `Bearer ${userStore.getToken()}`;
}
return config;
},
@@ -26,6 +28,12 @@ instance.interceptors.request.use(
instance.interceptors.response.use(
(response) => response,
(error) => {
if (error.response && error.response.status === 401) {
const userStore = useUserStore();
userStore.reset();
ElMessage.warning("登录过期,请重新登录");
router.push("/login");
}
return Promise.reject(error);
},
);
+7 -3
View File
@@ -1,5 +1,5 @@
import Big from "big.js";
import { formatToDate } from "./time";
import { formatToDate, formatToDateTime } from "./time";
/**
* 根据 format 判断列对齐方式
@@ -45,8 +45,10 @@ export function formatValueByFormat(value, format) {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
}).format(num);
} else if (fmt.startsWith("date")) {
} else if (fmt === "date") {
return formatToDate(value);
} else if (fmt === "datetime") {
return formatToDateTime(value);
} else if (fmt.startsWith("number")) {
return Number(value) || 0;
}
@@ -75,8 +77,10 @@ export function formatValueByFullFormat(value, format) {
if (Number.isNaN(num)) return value;
return num.toFixed(decimals);
} else if (fmt.startsWith("date")) {
} else if (fmt === "date") {
return formatToDate(value);
} else if (fmt === "datetime") {
return formatToDateTime(value);
} else if (fmt.startsWith("number")) {
return Number(value) || 0;
}
+214 -21
View File
@@ -378,6 +378,66 @@ export function diffData(
) {
const ignoreSet = new Set(ignoreFields);
const versionFields = new Set(["b_version", "mx_version"]);
/**
* 判断是否为数字类型
*
* 支持:
* 40
* "40"
* "40.00"
*/
const isNumberValue = (value) => {
if (typeof value === "number") {
return !Number.isNaN(value);
}
if (typeof value === "string") {
if (value.trim() === "") {
return false;
}
return !Number.isNaN(Number(value));
}
return false;
};
/**
* 数据值比较
*
* 数字:
* 40 === "40.00"
*
* 非数字:
* 保持原 JSON 比较逻辑
*/
const isEqualValue = (a, b) => {
// null undefined 空字符串统一
if (a == null || a === "") {
a = "";
}
if (b == null || b === "") {
b = "";
}
// 两边都是数字,按数值比较
if (isNumberValue(a) && isNumberValue(b)) {
return Math.abs(Number(a) - Number(b)) < 0.000001;
}
// 其他类型保持原来的比较方式
return JSON.stringify(a) === JSON.stringify(b);
};
const result = {
hasChanges: false,
insertdata: [],
@@ -385,106 +445,239 @@ export function diffData(
deletedata: [],
};
// 过滤字段
const filterFields = (row) => {
return Object.fromEntries(
Object.entries(row).filter(([key]) => {
return !key.startsWith("_") && !key.startsWith("v_") && !ignoreSet.has(key);
return (
!key.startsWith("_") &&
!key.startsWith("v_") &&
!ignoreSet.has(key)
);
}),
);
};
// 获取版本字段
const getVersionData = (row) => {
const data = {};
Object.keys(row).forEach((key) => {
if (versionFields.has(key)) {
data[key] = row[key];
}
});
return data;
};
// ===========================
// 单表处理
// 单表
// ===========================
if (isSingle) {
const isNewRecord = !original || Object.keys(original).length === 0 || !original[primaryKey];
// 新增
const isNewRecord =
!original ||
Object.keys(original).length === 0 ||
!original[primaryKey];
if (isNewRecord) {
result.hasChanges = true;
result.insertdata.push(filterFields(current));
return result;
}
// 修改
const changes = {};
Object.keys(current).forEach((key) => {
if (key.startsWith("_") || key.startsWith("v_") || ignoreSet.has(key)) return;
// 版本字段不参与比较
if (versionFields.has(key)) {
return;
}
if (
key.startsWith("_") ||
key.startsWith("v_") ||
ignoreSet.has(key)
) {
return;
}
const cur = current[key] ?? "";
const org = original[key] ?? "";
if (JSON.stringify(cur) !== JSON.stringify(org)) {
if (!isEqualValue(cur, org)) {
changes[key] = cur;
}
});
if (Object.keys(changes).length > 0) {
result.hasChanges = true;
result.updatedata.push({
[primaryKey]: current[primaryKey],
// 修改字段
...changes,
// 版本
...getVersionData(current),
});
}
return result;
}
// ===========================
// 子表处理
// ===========================
const pk = Array.isArray(primaryKey) ? primaryKey[0] : primaryKey;
const originalMap = new Map(original.map((item) => [item[pk], item]));
// ===========================
// 子表
// ===========================
const pk = Array.isArray(primaryKey)
? primaryKey[0]
: primaryKey;
const originalMap = new Map(
original.map((item) => [item[pk], item]),
);
// 新增
result.insertdata = current
.filter((row) => !row[pk] || !originalMap.has(row[pk]))
.filter(
(row) =>
!row[pk] ||
!originalMap.has(row[pk]),
)
.map(filterFields);
// 修改
current.forEach((row) => {
const id = row[pk];
if (!id) return;
if (!id) {
return;
}
const oldRow = originalMap.get(id);
if (!oldRow) return;
if (!oldRow) {
return;
}
const changes = {};
Object.keys(row).forEach((key) => {
if (key === pk || key.startsWith("_") || key.startsWith("v_") || ignoreSet.has(key)) {
// 版本字段不比较
if (versionFields.has(key)) {
return;
}
if (
key === pk ||
key.startsWith("_") ||
key.startsWith("v_") ||
ignoreSet.has(key)
) {
return;
}
const cur = row[key] ?? "";
const org = oldRow[key] ?? "";
if (JSON.stringify(cur) !== JSON.stringify(org)) {
if (!isEqualValue(cur, org)) {
changes[key] = cur;
}
});
if (Object.keys(changes).length > 0) {
result.updatedata.push({
[pk]: id,
...changes,
// 版本
...getVersionData(row),
});
}
});
// 删除
result.deletedata = original
.filter((o) => !current.some((c) => c[pk] === o[pk]))
.filter(
(o) =>
!current.some(
(c) => c[pk] === o[pk],
),
)
.map((o) => ({
[pk]: o[pk],
// 删除带版本
...getVersionData(o),
}));
result.hasChanges =
result.insertdata.length > 0 || result.updatedata.length > 0 || result.deletedata.length > 0;
result.insertdata.length > 0 ||
result.updatedata.length > 0 ||
result.deletedata.length > 0;
return result;
}
@@ -497,4 +690,4 @@ export default {
fillDefaultArray,
diffData,
fillSerialNoAndDefaults,
};
};
+16 -8
View File
@@ -7,6 +7,10 @@ const error = ref(null);
export async function delBefore(moduleId, id) {
try {
if (!id) {
return { success: true, message: "" };
}
saving.value = true;
error.value = "";
@@ -27,21 +31,25 @@ export async function delBefore(moduleId, id) {
saving.value = false;
}
}
export async function confirmDelete(rows) {
export async function confirmDelete(rows, title = "移除") {
const count = rows.length;
let msg = "确定要删除吗?";
let msg = "确定要" + title + "吗?";
if (count == 1) {
let id = rows[0].b_id || rows[0].subid || "";
msg = "确定要删除 " + id + " 吗?";
msg = "确定要" + title + id + " 吗?";
}
try {
await ElMessageBox.confirm(count > 1 ? `确定要删除选中的 ${count} 条数据吗?` : msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
});
await ElMessageBox.confirm(
count > 1 ? `确定要${title}选中的 ${count} 条数据吗?` : msg,
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
},
);
return true;
} catch (e) {
if (e === "cancel" || e === "close") {
+40 -16
View File
@@ -1,20 +1,20 @@
import axios from "@/utils/axios";
export async function getDataBySql(sql) {
try {
const response = await axios.get("/selectlistbysql", {
params: { sql }, // GET 请求参数
});
if (response.data?.success) {
return response.data.data;
} else {
console.error("查询失败:", response.data?.message);
return [];
}
} catch (err) {
console.error("接口异常:", err);
if (!sql || !sql.trim()) {
console.warn("SQL不能为空");
return [];
}
const { data } = await axios.post("/selectlistbysql", {
sql: sql.trim(),
});
if (!data?.success) {
throw new Error(data?.message || "查询失败");
}
return data.data || [];
}
export async function getDataBySqlPage(sql, pkColumn, page, size) {
@@ -95,10 +95,8 @@ export async function loaddataApi(viewname, searchcondition) {
}
export async function loaddatabysqlApi(sql) {
const { data } = await axios.get("/selectlistbysql", {
params: {
sql,
},
const { data } = await axios.post("/selectlistbysql", {
sql: sql.trim(),
});
if (!data?.success) {
@@ -120,6 +118,32 @@ export async function saveobjtApi(rows) {
return;
}
export async function saveobjtV5Api(rows) {
const { data } = await axios.post("/saveobjectV5", rows, {
headers: { "Content-Type": "application/json" },
});
if (!data?.success) {
throw new Error(data?.message || "保存失败");
}
return;
}
export async function saveobjtlockApi(rows) {
const { data } = await axios.post("/saveobject_Lock", rows, {
headers: { "Content-Type": "application/json" },
});
if (!data?.success) {
throw new Error(data?.message || "保存失败");
}
return;
}
export async function getobjectApi(tablename, pkcolumn, pkvalue) {
const params = {
tableName: tablename,
+40 -15
View File
@@ -637,21 +637,48 @@ export async function handleMappingConfig(selectId, subidliststr, targetRef) {
}
}
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
export async function handleMappingConfigObj(selectId, subidliststr, targetRef) {
let selectSql = "";
export const editableStates = ["草拟", "审核驳回", "送审"];
// 是否可编辑
export function isEditableState(state) {
return editableStates.includes(state || "");
}
const data_selectsql = await getDataBySql(
`select * from s_selectsql where selectid='${selectId}'`,
);
// 审核通过状态
export const approvedStates = ["审核通过"];
// 是否审核通过
export function isApprovedState(state) {
return !approvedStates.includes(state || "");
if (data_selectsql.records.length > 0) {
selectSql = data_selectsql.records[0].selectsql;
}
const sql = `${selectSql} ${subidliststr}`;
console.log("sql=----------");
console.log(sql);
const data = await getDataBySql(sql);
if (!data.records.length) {
return;
}
const data_selectdatamap = await getDataBySql(
`select * from s_selectdatamap where selectid='${selectId}'`,
);
if (data_selectdatamap.records.length > 0) {
const maps = data_selectdatamap.records;
const row = data.records[0];
const resultObj = {};
maps.forEach((item) => {
resultObj[item.des_field] = row[item.source_field];
});
targetRef.value = {
...targetRef.value,
...JSON.parse(JSON.stringify(resultObj)),
};
}
}
export default {
@@ -670,8 +697,6 @@ export default {
handleSaveColumnEdit,
getTableLabelEdit,
handleMappingConfig,
isEditableState,
isApprovedState,
};
// 导出单例
@@ -0,0 +1,146 @@
// src/formula/DependencyGraph.js
import extractVariables from "./VariableExtractor"
export default class DependencyGraph {
constructor(configs = []) {
/**
* qty
* ↓
* amount
* ↓
* tax
*/
this.graph = new Map()
/**
* amount
* ↓
* [qty,price]
*/
this.reverseGraph = new Map()
this.build(configs)
}
//---------------------------------------------
// 建立依赖图
//---------------------------------------------
build(configs) {
configs.forEach(item => {
if (!item.formula)
return
const vars = extractVariables(item.formula)
//-----------------------------------------
// 保存反向依赖
//-----------------------------------------
this.reverseGraph.set(
item.field,
vars
)
//-----------------------------------------
// 正向依赖
//-----------------------------------------
vars.forEach(v => {
if (!this.graph.has(v))
this.graph.set(v, [])
this.graph.get(v).push(
item.field
)
})
})
}
//---------------------------------------------
// 获取直接依赖
//---------------------------------------------
getNext(field) {
return this.graph.get(field) || []
}
//---------------------------------------------
// 获取公式依赖字段
//---------------------------------------------
getVariables(field) {
return this.reverseGraph.get(field) || []
}
hasCycle() {
const visited = new Set()
const stack = new Set()
const dfs = (node) => {
if (stack.has(node))
return true
if (visited.has(node))
return false
visited.add(node)
stack.add(node)
const next =
this.getNext(node)
for (const n of next) {
if (dfs(n))
return true
}
stack.delete(node)
return false
}
for (const key of this.graph.keys()) {
if (dfs(key))
return true
}
return false
}
}
@@ -0,0 +1,41 @@
// src/formula/FormulaCache.js
/**
* 编译缓存
*/
class FormulaCache {
constructor() {
this.cache = new Map()
}
has(key) {
return this.cache.has(key)
}
get(key) {
return this.cache.get(key)
}
set(key, value) {
this.cache.set(key, value)
}
clear() {
this.cache.clear()
}
}
export default new FormulaCache()
@@ -0,0 +1,84 @@
// src/formula/FormulaCompiler.js
import FormulaFunctions from "./FormulaFunctions"
import FormulaCache from "./FormulaCache"
/**
* 编译公式
*
* qty*price
*
* =>
*
* function(scope){}
*/
export default class FormulaCompiler {
/**
* 编译
*/
static compile(formula) {
if (!formula)
return () => null
//---------------------------------
// 已编译
//---------------------------------
if (FormulaCache.has(formula)) {
return FormulaCache.get(formula)
}
//---------------------------------
// 编译
//---------------------------------
const fn = new Function(
"scope",
"func",
`
with(func){
with(scope){
return ${formula}
}
}
`
)
//---------------------------------
// 包装
//---------------------------------
const execute = (scope) => {
try {
return fn(scope, FormulaFunctions)
}
catch (e) {
console.error("公式执行失败:", formula)
console.error(e)
return null
}
}
FormulaCache.set(formula, execute)
return execute
}
}
@@ -0,0 +1,231 @@
// src/formula/FormulaEngine.js
import FormulaCompiler from "./FormulaCompiler";
import DependencyGraph from "./DependencyGraph";
import TableCalculator from "./TableCalculator";
export default class FormulaEngine {
constructor(configs = []) {
this.configs = configs;
// 行公式
this.rowConfigs = [];
// 汇总公式
this.tableConfigs = [];
// field -> config
this.rowMap = new Map();
// DependencyGraph
this.graph = null;
this.init();
}
/**
* 初始化
*/
init() {
//-----------------------------
// Row Formula
//-----------------------------
this.rowConfigs = this.configs.filter(
x => x.type === "row"
);
//-----------------------------
// Table Formula
//-----------------------------
this.tableConfigs = this.configs.filter(
x => x.type === "table"
);
//-----------------------------
// 编译
//-----------------------------
this.rowConfigs.forEach(item => {
item.execute = FormulaCompiler.compile(
item.formula
);
this.rowMap.set(
item.field,
item
);
});
//-----------------------------
// 建立依赖图
//-----------------------------
this.graph = new DependencyGraph(
this.rowConfigs
);
}
/**
* 初始化计算整行
*/
calcAll(row) {
this.rowConfigs.forEach(item => {
row[item.field] = item.execute(row);
});
return row;
}
/**
* 更新一个字段
*
* field 发生变化
*/
update(row, field) {
const queue = [field];
const visited = new Set();
while (queue.length > 0) {
const current = queue.shift();
const nextFields = this.graph.getNext(current);
nextFields.forEach(nextField => {
if (visited.has(nextField))
return;
visited.add(nextField);
const config = this.rowMap.get(nextField);
if (!config)
return;
//-----------------------------------
// 重新计算
//-----------------------------------
row[nextField] = config.execute(row);
//-----------------------------------
// 继续传播
//-----------------------------------
queue.push(nextField);
});
}
return row;
}
/**
* 更新多个字段
*/
batchUpdate(row, fields = []) {
const queue = [...fields];
const visited = new Set();
while (queue.length > 0) {
const current = queue.shift();
const nextFields = this.graph.getNext(current);
nextFields.forEach(nextField => {
if (visited.has(nextField))
return;
visited.add(nextField);
const config = this.rowMap.get(nextField);
if (!config)
return;
row[nextField] = config.execute(row);
queue.push(nextField);
});
}
return row;
}
/**
* 更新Footer
*/
updateTable(rows) {
const footer = {};
this.tableConfigs.forEach(item => {
const formula = item.formula;
const match = formula.match(
/(sum|avg|max|min|count)\((.*?)\)/
);
if (!match)
return;
const func = match[1];
const field = match[2];
if (typeof TableCalculator[func] !== "function")
return;
footer[item.field] = TableCalculator[func](
rows,
field
);
});
return footer;
}
/**
* 全部重新计算
*/
updateAll(rows) {
rows.forEach(row => {
this.calcAll(row);
});
return this.updateTable(rows);
}
}
@@ -0,0 +1,75 @@
// src/formula/FormulaFunctions.js
/**
* 内置函数
*/
const FormulaFunctions = {
// ------------------------
// 数学
// ------------------------
round(value, precision = 2) {
value = Number(value || 0)
return Number(value.toFixed(precision))
},
abs(value) {
return Math.abs(Number(value || 0))
},
ceil(value) {
return Math.ceil(Number(value || 0))
},
floor(value) {
return Math.floor(Number(value || 0))
},
max(...args) {
return Math.max(...args.map(v => Number(v || 0)))
},
min(...args) {
return Math.min(...args.map(v => Number(v || 0)))
},
//----------------------------------
// 判断
//----------------------------------
if(condition, trueValue, falseValue) {
return condition ? trueValue : falseValue
},
//----------------------------------
// 空值
//----------------------------------
nvl(value, defaultValue = 0) {
return value == null ? defaultValue : value
},
//----------------------------------
// 字符串
//----------------------------------
len(str) {
return (str || "").length
},
upper(str) {
return (str || "").toUpperCase()
},
lower(str) {
return (str || "").toLowerCase()
},
concat(...args) {
return args.join("")
}
}
export default FormulaFunctions
@@ -0,0 +1,54 @@
// src/formula/FormulaValidator.js
import extractVariables from "./VariableExtractor"
/**
* 检查公式是否合法
*/
export default class FormulaValidator {
/**
* 校验
*/
static validate(configs) {
const errors = []
configs.forEach(item => {
if (!item.formula)
return
try {
// 提取变量
extractVariables(item.formula)
}
catch (e) {
errors.push({
field: item.field,
formula: item.formula,
message: e.message
})
}
})
return {
success: errors.length == 0,
errors
}
}
}
@@ -0,0 +1,76 @@
// src/formula/TableCalculator.js
export default class TableCalculator {
//-------------------------
// 求和
//-------------------------
static sum(rows, field) {
return rows.reduce((total, row) => {
return total + Number(row[field] || 0)
}, 0)
}
//-------------------------
// 平均
//-------------------------
static avg(rows, field) {
if (!rows.length)
return 0
return this.sum(rows, field) / rows.length
}
//-------------------------
// 最大
//-------------------------
static max(rows, field) {
if (!rows.length)
return 0
return Math.max(
...rows.map(r => Number(r[field] || 0))
)
}
//-------------------------
// 最小
//-------------------------
static min(rows, field) {
if (!rows.length)
return 0
return Math.min(
...rows.map(r => Number(r[field] || 0))
)
}
//-------------------------
// 数量
//-------------------------
static count(rows) {
return rows.length
}
}
@@ -0,0 +1,45 @@
// src/formula/VariableExtractor.js
/**
* 提取变量
*
* qty*price
*
* =>
*
* ["qty","price"]
*/
const keywords = [
"sum",
"avg",
"max",
"min",
"round",
"abs",
"ceil",
"floor",
"if",
"nvl",
"true",
"false"
]
export default function extractVariables(formula) {
if (!formula)
return []
const result = formula.match(/[a-zA-Z_][a-zA-Z0-9_]*/g) || []
return [...new Set(
result.filter(item => !keywords.includes(item))
)]
}
window.extractVariables = extractVariables
@@ -0,0 +1,3 @@
import FormulaEngine from "./FormulaEngine"
export default FormulaEngine
+327 -44
View File
@@ -1,8 +1,9 @@
import { ElMessage, ElMessageBox } from "element-plus";
import { ref, unref } from "vue";
import { ref, unref, computed } from "vue";
import axios from "@/utils/axios";
import { useUserStore } from "@/store/user";
import { getDate, getDateTime } from "@/utils/time";
import { getDataBySql } from "@/utils/doSql";
const userStore = useUserStore();
@@ -10,6 +11,19 @@ const loading = ref(false);
const saving = ref(false);
const error = ref(null);
export async function getfieldvaluebyid(tablename,returnfield,keyfield,keyvalue) {
const sql = `SELECT ${returnfield} FROM ${tablename} WHERE ${keyfield} = '${keyvalue}'`;
// console.log(sql);
const result = await getDataBySql(sql);
if (!result?.records?.length) {
return "";
}
return Object.values(result.records[0])[0] ?? "";
}
export async function getDefaultValue(targetRef, tablename) {
try {
loading.value = true;
@@ -51,6 +65,7 @@ export async function getDefaultValue(targetRef, tablename) {
export async function checkMustField(targetObj, tablename) {
const targetdata = unref(targetObj);
console.log(targetObj);
const params = {
tableName: tablename || "v_bs_business",
};
@@ -77,6 +92,76 @@ export async function checkMustField(targetObj, tablename) {
return true;
}
export async function checkAllowRepeat(maintable, tableName) {
// 获取不可重复字段
const columnSql = `
select col_FieldName,col_TableName,col_Caption
from s_columnLib
where col_AllowRepeat <> '1'
and col_TableName='${tableName}'
`;
const result = await getDataBySql(columnSql);
const columns = result.records || [];
for (const column of columns) {
const fieldName = column.col_FieldName;
if (fieldName === "b_id") {
continue;
}
// 当前表单值
const value = maintable[fieldName];
// 空值跳过
if (value === null || value === undefined || value === "") {
continue;
}
// 查询数据库是否存在
const checkSql = `
select count(1) as num
from ${tableName}
where ${fieldName}='${value}' and b_id <> '${maintable.b_id}'
`;
const result = await getDataBySql(checkSql);
const records = result?.records || [];
if (records.length > 0 && Number(records[0].num) > 0) {
ElMessage.warning(`${column.col_Caption || fieldName} 已存在,不能重复`);
return false;
}
}
return true;
}
export async function initReserveData(maintable, tableName) {
const columnSql = `
select col_FieldName,col_TableName,col_Caption
from s_columnLib
where col_NeedReserve = '1'
and col_TableName='${tableName}'
`;
const result = await getDataBySql(columnSql);
const columns = result.records || [];
const reserveData = {};
columns.forEach((item) => {
const fieldName = item.col_FieldName;
const value = maintable[fieldName];
if (value !== null && value !== undefined && value !== "") {
reserveData[fieldName] = value;
}
});
return reserveData;
}
export async function getMoneyExRate({
rows = [],
@@ -125,11 +210,6 @@ export function toMoney(val, scale = 3) {
return Number(num.toFixed(scale));
}
export const editableStates = ["草拟", "审核驳回", "送审"];
export function isEditableStateAndQR(state, cwqr) {
return editableStates.includes(state || "") && String(cwqr) !== "1";
}
export function isNotEmpty(val) {
return val !== null && val !== undefined && String(val).trim() !== "";
}
@@ -138,25 +218,13 @@ export function getFieldString(arr, field, limit = 100) {
return [...new Set(arr.map((item) => item[field]).filter(Boolean))].slice(0, limit).join(",");
}
export function morePermission(permissionId) {
const userStore = useUserStore();
return !userStore.hasActionPermission(permissionId);
}
export function handleBankInvChange(val, maintable, field) {
if (field == "v_dw_name") {
maintable.b_dw_bankacount = val?.b_bankacount || "";
maintable.b_dw_invaccount = val?.b_invaccount || "";
}
if (field == "v_mycompanyname") {
maintable.b_my_bankacount = val?.b_bankacount || "";
maintable.b_my_invaccount = val?.b_invaccount || "";
}
}
/**
* 验证集装箱号
* ISO 6346 标准
*
* 格式:
* 4位字母 + 7位数字
*
* @param {string} containerNo 集装箱号
* @returns {boolean}
*/
@@ -170,55 +238,270 @@ export function checkContainerNo(containerNo) {
return false;
}
const chars = value.substring(0, 10);
// ISO 6346 字母对应值
const letterMap = {
A: 10,
B: 12,
C: 13,
D: 14,
E: 15,
F: 16,
G: 17,
H: 18,
I: 19,
J: 20,
K: 21,
L: 23,
M: 24,
N: 25,
O: 26,
P: 27,
Q: 28,
R: 29,
S: 30,
T: 31,
U: 32,
V: 34,
W: 35,
X: 36,
Y: 37,
Z: 38,
};
let sum = 0;
for (let i = 0; i < chars.length; i++) {
// 前10位参与计算
for (let i = 0; i < 10; i++) {
const char = value[i];
let num;
if (/[A-Z]/.test(chars[i])) {
num = chars[i].charCodeAt(0) - 55;
// ISO6346 字母映射跳过 11、22、33
if (num >= 11) num--;
if (num >= 22) num--;
if (num >= 33) num--;
if (letterMap[char]) {
num = letterMap[char];
} else {
num = Number(chars[i]);
num = Number(char);
}
// 权重 2^位置
sum += num * Math.pow(2, i);
}
// ISO 6346:
// 校验码 = (总和 % 11) % 10
const checkCode = (sum % 11) % 10;
return checkCode === Number(value[10]);
}
// export function confirmSave(message = "数据已修改,是否保存?") {
// return ElMessageBox.confirm(message, "提示", {
// confirmButtonText: "保存",
// cancelButtonText: "不保存",
// type: "warning",
// })
// .then(() => {
// return true; // 点击保存
// })
// .catch(() => {
// return false; // 点击不保存或关闭
// });
// }
export function confirmSave(message = "数据已修改,是否保存?") {
return ElMessageBox.confirm(message, "提示", {
confirmButtonText: "保存",
cancelButtonText: "不保存",
type: "warning",
})
.then(() => {
return true; // 点击保存
return new Promise((resolve) => {
ElMessageBox({
title: "提示",
message,
showCancelButton: true,
showClose: true,
confirmButtonText: "保存",
cancelButtonText: "不保存",
distinguishCancelAndClose: true,
type: "warning",
})
.catch(() => {
return false; // 点击不保存或关闭
});
.then(() => {
// 保存
resolve("save");
})
.catch((action) => {
if (action === "cancel") {
// 不保存
resolve("noSave");
} else if (action === "close") {
// 点击右上角关闭
resolve("cancel");
}
});
});
}
// ---------------应收、应付、利润汇总
export function handleFeeSummary(receiveRef, payRef, fields = {}) {
return computed(() => {
const data = calcFeeSummary(receiveRef.value, payRef.value, fields);
return {
allHtml:
formatCurrencyHtml(data.receive, data.receiveRmb, "应收") +
formatCurrencyHtml(data.pay, data.payRmb, "应付") +
formatCurrencyHtml(data.profit, data.profitRmb, "利润"),
};
});
}
// 币种金额HTML
function formatCurrencyHtml(summary = {}, rmb, title = "") {
let html = `<div class="g3currencytotal"><div>${title}合计:</div>`;
html += Object.entries(summary)
.map(([currency, amount]) => {
return `
<div>${currency}:</div>
<div>${Number(amount || 0).toFixed(2)}</div>
<div class="g3currencytotalsx"></div>
`;
})
.join("");
html += `
<div>${title}折本币:</div>
<div>${Number(rmb || 0).toFixed(2)}</div>
</div>`;
return html;
}
export function handleYsYfSummary(receiveRef, payRef, fields = {}) {
return computed(() => {
const data = calcFeeSummary(receiveRef.value, payRef.value, fields);
return {
allHtml: formatYsYfHtml(data.receive, "应收") + formatYsYfHtml(data.pay, "应付"),
};
});
}
// 币种金额HTML
function formatYsYfHtml(summary = {}, title = "") {
let html = `<div class="g3currencytotal"><div>${title}合计:</div>`;
html += Object.entries(summary)
.map(([currency, amount], index, arr) => {
return `
<div>${currency}:</div>
<div>${Number(amount || 0).toFixed(2)}</div>
${index !== arr.length - 1 ? '<div class="g3currencytotalsx"></div>' : ""}
`;
})
.join("");
html += `</div>`;
return html;
}
// 应收、应付、利润汇总
export function calcFeeSummary(receive = [], pay = [], fields = {}) {
const {
currencyField = "mx_moneytype_id",
amountField = "mx_amount",
rmbField = "mx_amount_rmb",
typeField = "mx_type_id",
} = fields;
const result = {
receive: {},
pay: {},
profit: {},
receiveRmb: 0,
payRmb: 0,
profitRmb: 0,
};
const rows = [...(receive || []), ...(pay || [])];
rows.forEach((row) => {
const currency = row[currencyField] || "未知币种";
const amount = toMoney(row[amountField]);
const rmb = toMoney(row[rmbField]);
const type = row[typeField];
if (type === "应收") {
result.receive[currency] = toMoney((result.receive[currency] || 0) + amount);
result.receiveRmb = toMoney(result.receiveRmb + rmb);
}
if (type === "应付") {
result.pay[currency] = toMoney((result.pay[currency] || 0) + amount);
result.payRmb = toMoney(result.payRmb + rmb);
}
});
// 利润 = 应收 - 应付
const currencies = new Set([...Object.keys(result.receive), ...Object.keys(result.pay)]);
currencies.forEach((currency) => {
result.profit[currency] = toMoney(
(result.receive[currency] || 0) - (result.pay[currency] || 0),
);
});
result.profitRmb = toMoney(result.receiveRmb - result.payRmb);
return result;
}
export function handleDisabledState(stateGetter) {
const editable = computed(() => ["草拟", "审核驳回"].includes(stateGetter()));
const approved = computed(() => stateGetter() === "审核通过");
return {
editable,
approved,
};
}
export function generateUuid() {
if (window.crypto && crypto.getRandomValues) {
const buf = new Uint8Array(16);
crypto.getRandomValues(buf);
// 设置 UUID v4 标识位
buf[6] = (buf[6] & 0x0f) | 0x40;
buf[8] = (buf[8] & 0x3f) | 0x80;
const hex = Array.from(buf).map((b) => b.toString(16).padStart(2, "0"));
return [
hex.slice(0, 4).join(""),
hex.slice(4, 6).join(""),
hex.slice(6, 8).join(""),
hex.slice(8, 10).join(""),
hex.slice(10, 16).join(""),
].join("-");
}
// 兼容老浏览器(360兼容模式等)
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
// ------------------
// 默认导出所有方法
export default {
getDefaultValue,
checkMustField,
checkAllowRepeat,
initReserveData,
getMoneyExRate,
toMoney,
isEditableStateAndQR,
isNotEmpty,
getFieldString,
handleBankInvChange,
confirmSave,
handleFeeSummary,
handleYsYfSummary,
handleDisabledState,
};
@@ -40,3 +40,25 @@ export function processGridKeydown(event, $table) {
$table.setCurrentColumn(columns[toIndex]);
}
}
export function processRowDrag(list, event, sortField = "mx_xh") {
const { oldRow, newRow } = event;
console.log("1111111111");
const oldIndex = list.indexOf(oldRow);
const newIndex = list.indexOf(newRow);
console.log(oldIndex);
console.log(newIndex);
if (oldIndex < 0 || newIndex < 0 || oldIndex === newIndex) {
return;
}
const [row] = list.splice(oldIndex, 1);
list.splice(newIndex, 0, row);
list.forEach((item, index) => {
item[sortField] = index + 1;
});
}
-980
View File
@@ -1,980 +0,0 @@
// import ssDialog from '@/components/ssDialog.vue'
// import shDialog from '@/components/shDialog.vue'
// import bhDialog from '@/components/bhDialog.vue'
import toshDialog from "@/components/sendsh/toshDialog.vue";
import { createVNode, render, h } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import axios from "@/utils/axios";
import { getDataBySql } from "@/utils/doSql";
import dayjs from "dayjs";
import { useUserStore } from "@/store/user";
/**
* 审核中心 - Vue3版本
* @param {String} ywid - 业务ID
* @param {String} savetable - 主表表名
* @param {String} ModuleID - 模块ID
* @param {String} state - 审核状态(如 审核通过、驳回)
* @param {Array} shsetdatas - 审核流程设定
* @param {Function} func - 回调函数
*/
export async function mod_shcenter_sh(ywid, savetable, ModuleID, state, shsetdatas, Fuserid, func) {
try {
// === 1. 读取业务主表数据 ===
const mainSql = `select * from ${savetable} where b_id='${ywid}' order by b_id`;
const mainRes = await axios.get("/selectlistbysql", { params: { sql: mainSql } });
const ywdatas = mainRes.data?.data?.records || [];
if (ywdatas.length === 0) {
ElMessage.warning("当前业务单不存在");
return;
}
const rowdata = ywdatas[0];
const ywownerid = rowdata.b_owner_id;
// === 2. 查询待审记录 ===
const shSql = `select * from sh_record where b_dj_id='${ywid}' and b_module_id='${ModuleID}' order by b_id desc`;
const shRes = await axios.get("/selectlistbysql", { params: { sql: shSql } });
const shrecords = shRes.data?.data?.records || [];
if (shrecords.length === 0) {
ElMessage.warning("没有待审记录");
return;
}
const now_level = Number(shrecords[0].b_level);
const shlevel = now_level + 1;
const dsh_useid = shrecords[0].b_tosh_useid;
const userid = Fuserid; // 当前登录用户ID(请根据实际修改)
if (String(dsh_useid).trim() !== String(userid).trim()) {
ElMessage.error("你没有该票业务的审批权限");
return;
}
// === 3. 判断审批权限、是否有下一步 ===
let can_sh = false;
let can_nextsh = false;
let level_userid = [];
for (const shset of shsetdatas) {
if (Number(shset.b_level) === Number(shlevel)) {
if (shset.b_user_id === dsh_useid) {
can_sh = true;
}
}
if (Number(shset.b_level) === Number(shlevel + 1)) {
can_nextsh = true;
level_userid.push(shset.b_user_id);
}
}
if (!can_sh) {
ElMessage.error("你没有该票业务的审批权限");
return;
}
// === 4. 设置当前状态 ===
const xxx = ["一", "二", "三", "四", "五", "六", "七", "八"];
let sh_state = can_nextsh ? `${xxx[now_level]}审通过` : "审核通过";
const str_leveluserid = level_userid.map((item) => `'${item}'`).join(",");
const searchcondition = `b_id in (${str_leveluserid})`;
const shSql1 = `select * from b_user where ${searchcondition}`;
const shRes1 = await axios.get("/selectlistbysql", { params: { sql: shSql1 } });
const shrecords_id = shRes1.data?.data?.records || [];
const level_userid_upadte = shrecords_id.map((item) => ({
b_id: item.b_id,
b_name: item.b_name,
}));
// === 5. 弹出选择审批人弹窗 ===
const data = await openShDialog(level_userid_upadte, ywownerid);
if (!data) {
ElMessage.info("已取消转送");
return;
}
// === 7. 调用保存函数 ===
await save_sh_data(
ModuleID,
userid,
savetable,
rowdata,
sh_state,
shlevel,
data.user,
data.memo,
func,
);
} catch (err) {
console.error(err);
ElMessage.error("审批失败");
}
}
// export function openShDialog(levelUserIds, ywownerid) {
// return new Promise(resolve => {
// const container = document.createElement('div')
// document.body.appendChild(container)
// const closeDialog = () => {
// render(null, container)
// document.body.removeChild(container)
// }
// const vnode = createVNode(shDialog, {
// modelValue: true,
// levelUserIds,
// ywownerid,
// onConfirm: data => {
// closeDialog()
// resolve(data)
// },
// onCancel: () => {
// closeDialog()
// resolve(null)
// }
// })
// render(vnode, container)
// })
// }
/**
* 模拟保存审批数据
*/
async function save_sh_data(
ModuleID,
userid,
savetable,
rowdata,
state,
shlevel,
tosh_useid,
sh_memo,
func,
) {
if (rowdata == undefined) return;
const updateRows = [];
const insert_sh_records = [];
var oldstate = rowdata.b_state;
const inputdatetime = dayjs().format("YYYY-MM-DD HH:mm:ss");
const obj = { b_id: rowdata.b_id, b_state: state };
updateRows.push(obj);
insert_sh_records.push({
b_module_id: ModuleID,
b_user_id: userid,
b_level: shlevel,
b_name: state,
b_dj_id: rowdata.b_id,
b_sh: "1",
b_sh_date: inputdatetime,
b_sh_memo: sh_memo,
b_tosh_useid: tosh_useid,
});
const requestData = [];
if (updateRows.length > 0) {
requestData.push({
tableName: savetable,
keyField: "b_id",
inserts: [],
updates: updateRows,
deletes: [],
});
requestData.push({
tableName: "sh_record",
keyField: "b_id",
inserts: insert_sh_records,
updates: [],
deletes: [],
});
if (savetable === "cw_zdorder") {
const updateFeeData = [];
const zdidarr = updateRows.map((row) => `'${row.b_id}'`);
// 获取账单状态
const getBStateById = (id) => {
const row = updateRows.find((r) => r.b_id === id);
return row ? row.b_state : "";
};
// 这里替代 loaddatas()
const searchsql = `isnull(mx_zdorderid, '') in (${zdidarr.join(",")})`;
const cwres = await axios.get("/selectlistbysql", {
params: {
sql: `select * from bs_business_cw where ${searchsql} order by subid`,
},
});
const cwrows = cwres.data?.data?.records || [];
for (const cw of cwrows) {
const zdstate = getBStateById(cw.mx_zdorderid) || state;
updateFeeData.push({
subid: cw.subid,
father: cw.father,
mx_zdorder_state: zdstate,
});
}
if (updateFeeData.length > 0) {
requestData.push({
tableName: "bs_business_cw",
keyField: "subid",
inserts: [],
updates: updateFeeData,
deletes: [],
});
}
}
}
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success(state + "成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
}
export const main_shcenter_ss = async (ywid, savetable, ModuleID, state, userid, func) => {
// 1️⃣ 校验业务单是否存在
let searchsql = `select * from ${savetable} where b_id='${ywid}' order by b_id`;
const ywdatasRes = await axios.get("/selectlistbysql", { params: { sql: searchsql } });
const ywdatas = ywdatasRes.data?.data?.records || [];
if (!ywdatas.length) {
ElMessage.error("当前业务单号不存在");
return false;
}
const newstate = ywdatas[0].b_state;
const canuse_state = ["草拟", "审核驳回", ""];
if (!canuse_state.includes(newstate)) {
ElMessage.warning(`只有 ${canuse_state.join(",")} 的记录才能 ${state}!`);
return false;
}
// 2️⃣ 获取审批配置
let sql = `select * from sh_b_set where b_module_id='${ModuleID}' order by b_level`;
const shsetRes = await axios.get("/selectlistbysql", { params: { sql } });
const shsetdatas = shsetRes.data?.data?.records || [];
const level_userid = shsetdatas.filter((i) => i.b_level === "1").map((i) => i.b_user_id);
if (!level_userid.length) {
ElMessage.error("当前模块未配置一级审批人");
return false;
}
const str_leveluserid = level_userid.map((item) => `'${item}'`).join(",");
const searchcondition = `b_id in (${str_leveluserid})`;
const shSql1 = `select * from b_user where ${searchcondition}`;
const shRes1 = await axios.get("/selectlistbysql", { params: { sql: shSql1 } });
const shrecords_id = shRes1.data?.data?.records || [];
const level_userid_upadte = shrecords_id.map((item) => ({
b_id: item.b_id,
b_name: item.b_name,
}));
// 3️⃣ 打开弹窗
const selected = await openSelectApproverDialog(level_userid_upadte);
if (!selected) {
ElMessage.info("已取消送审");
return;
}
// 4️⃣ 保存送审逻辑
await save_ss_data(
ModuleID,
userid,
savetable,
ywid,
newstate,
state,
selected.user,
selected.memo,
func,
);
};
/**
* 动态创建审批人选择弹窗
*/
// function openSelectApproverDialog(levelUserIds) {
// return new Promise(resolve => {
// const container = document.createElement('div')
// document.body.appendChild(container)
// const closeDialog = () => {
// render(null, container)
// document.body.removeChild(container)
// }
// // 创建虚拟节点
// const vnode = createVNode(ssDialog, {
// levelUserIds,
// modelValue: true, // 确保初始显示
// 'onUpdate:visible': val => {
// if (!val) closeDialog()
// },
// onConfirm: data => {
// closeDialog()
// resolve(data)
// },
// onCancel: () => {
// closeDialog()
// resolve(null)
// },
// })
// // 渲染到 DOM
// render(vnode, container)
// })
// }
/**
* 保存送审数据(示例,可与你的后端对应)
*/
async function save_ss_data(
ModuleID,
userid,
savetable,
ywid,
oldstate,
state,
tosh_useid,
sh_memo,
func,
) {
const updateRows = [];
const insert_sh_records = [];
const obj = { b_id: ywid, b_state: state };
updateRows.push(obj);
const inputdatetime = dayjs().format("YYYY-MM-DD HH:mm:ss");
insert_sh_records.push({
b_module_id: ModuleID,
b_user_id: userid,
b_level: "0",
b_name: state,
b_dj_id: ywid,
b_sh: "1",
b_sh_date: inputdatetime,
b_sh_memo: sh_memo,
b_tosh_useid: tosh_useid,
});
const requestData = [];
if (updateRows.length > 0) {
requestData.push({
tableName: savetable,
keyField: "b_id",
inserts: [],
updates: updateRows,
deletes: [],
});
requestData.push({
tableName: "sh_record",
keyField: "b_id",
inserts: insert_sh_records,
updates: [],
deletes: [],
});
if (savetable === "cw_zdorder") {
const updateFeeData = [];
const zdidarr = updateRows.map((row) => `'${row.b_id}'`);
// 获取账单状态
const getBStateById = (id) => {
const row = updateRows.find((r) => r.b_id === id);
return row ? row.b_state : "";
};
// 这里替代 loaddatas()
const searchsql = `isnull(mx_zdorderid, '') in (${zdidarr.join(",")})`;
const cwres = await axios.get("/selectlistbysql", {
params: {
sql: `select * from bs_business_cw where ${searchsql} order by subid`,
},
});
const cwrows = cwres.data?.data?.records || [];
for (const cw of cwrows) {
const zdstate = getBStateById(cw.mx_zdorderid) || state;
updateFeeData.push({
subid: cw.subid,
father: cw.father,
mx_zdorder_state: zdstate,
});
}
if (updateFeeData.length > 0) {
requestData.push({
tableName: "bs_business_cw",
keyField: "subid",
inserts: [],
updates: updateFeeData,
deletes: [],
});
}
}
}
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success(state + "成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
}
export const mod_shcenter_bh = async (ywid, savetable, ModuleID, state, userid, func) => {
// 加载业务数据
let searchsql = `select * from ${savetable} where b_id='${ywid}' order by b_id`;
const ywdatasRes = await axios.get("/selectlistbysql", { params: { sql: searchsql } });
const ywdatas = ywdatasRes.data?.data?.records || [];
if (!ywdatas.length) {
ElMessage.error("当前业务单号不存在");
return false;
}
const rowdata = ywdatas[0];
const ywownerid = rowdata.b_owner_id;
const nowstate = rowdata.b_state;
if (nowstate === "审核驳回") {
ElMessage.warning("已驳回!请检查!");
return false;
}
// 查询审核记录
const shSql = `select * from sh_record where b_dj_id='${ywid}' and b_module_id='${ModuleID}' order by b_id desc`;
const shRes = await axios.get("/selectlistbysql", { params: { sql: shSql } });
const shrecords = shRes.data?.data?.records || [];
let now_level = 0;
if (!shrecords || shrecords.length === 0) {
// 没有记录时判断权限
const shSql1 = `select * from sh_b_set where b_module_id='${ModuleID}' and b_user_id='${userid}' order by b_level`;
const shRes1 = await axios.get("/selectlistbysql", { params: { sql: shSql1 } });
const shsetdatas = shRes1.data?.data?.records || [];
if (!shsetdatas || shsetdatas.length === 0) {
ElMessage.warning("你没有该票业务的驳回权限");
return false;
}
} else {
now_level = shrecords[0].b_level;
const dsh_useid = shrecords[0].b_tosh_useid;
const sh_userid = shrecords[0].b_user_id;
if (dsh_useid !== userid && sh_userid !== userid && now_level > 0) {
ElMessage.warning("你没有该票业务的驳回权限");
return false;
}
if (nowstate === "送审" && dsh_useid !== userid) {
ElMessage.warning("你没有该票业务的驳回权限");
return false;
}
}
// === 5. 弹出驳回弹窗 ===
const data = await openBHDialog("", ywownerid);
if (!data) {
ElMessage.info("已取消驳回");
return;
}
await save_bh_data(
ModuleID,
userid,
savetable,
ywid,
state,
now_level,
data.user,
data.memo,
func,
);
};
// export function openBHDialog(levelUserIds, ywownerid) {
// return new Promise(resolve => {
// const container = document.createElement('div')
// document.body.appendChild(container)
// const closeDialog = () => {
// render(null, container)
// document.body.removeChild(container)
// }
// const vnode = createVNode(bhDialog, {
// modelValue: true,
// levelUserIds,
// ywownerid,
// onConfirm: data => {
// closeDialog()
// resolve(data)
// },
// onCancel: () => {
// closeDialog()
// resolve(null)
// }
// })
// render(vnode, container)
// })
// }
async function save_bh_data(
ModuleID,
userid,
savetable,
ywid,
state,
now_level,
tosh_useid,
sh_memo,
func,
) {
const updateRows = [];
const insert_sh_records = [];
const inputdatetime = dayjs().format("YYYY-MM-DD HH:mm:ss");
const obj = { b_id: ywid, b_state: state };
updateRows.push(obj);
insert_sh_records.push({
b_module_id: ModuleID,
b_user_id: userid,
b_level: now_level,
b_name: state,
b_dj_id: ywid,
b_sh: "0",
b_sh_date: inputdatetime,
b_sh_memo: sh_memo,
b_tosh_useid: tosh_useid,
});
const requestData = [];
if (updateRows.length > 0) {
requestData.push({
tableName: savetable,
keyField: "b_id",
inserts: [],
updates: updateRows,
deletes: [],
});
requestData.push({
tableName: "sh_record",
keyField: "b_id",
inserts: insert_sh_records,
updates: [],
deletes: [],
});
if (savetable === "cw_zdorder") {
const updateFeeData = [];
const zdidarr = updateRows.map((row) => `'${row.b_id}'`);
// 获取账单状态
const getBStateById = (id) => {
const row = updateRows.find((r) => r.b_id === id);
return row ? row.b_state : "";
};
// 这里替代 loaddatas()
const searchsql = `isnull(mx_zdorderid, '') in (${zdidarr.join(",")})`;
const cwres = await axios.get("/selectlistbysql", {
params: {
sql: `select * from bs_business_cw where ${searchsql} order by subid`,
},
});
const cwrows = cwres.data?.data?.records || [];
for (const cw of cwrows) {
const zdstate = getBStateById(cw.mx_zdorderid) || state;
updateFeeData.push({
subid: cw.subid,
father: cw.father,
mx_zdorder_state: zdstate,
});
}
if (updateFeeData.length > 0) {
requestData.push({
tableName: "bs_business_cw",
keyField: "subid",
inserts: [],
updates: updateFeeData,
deletes: [],
});
}
}
}
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success(state + "成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
}
export const modgrididstate = async (rows, savetable, ModuleID, state, func) => {
if (!rows || rows.length === 0) {
ElMessage.warning("请勾选要送审的记录!");
return;
}
// 状态可变范围
let canuse_state = [];
if (state === "送审") canuse_state = ["草拟", "审核驳回", ""];
if (state === "归档") canuse_state = ["审核通过", "完成"];
// 时间辅助
const inputdatetime = ["cw_zdorder", "cw_zdorder_f"].includes(ModuleID)
? dayjs().format("YYYY-MM-DD HH:mm:ss")
: "";
const updateFeeData = [];
const updateRows = [];
// 遍历勾选行
for (const row of rows) {
if (!row) return;
const oldstate = row.b_state || row.b_State;
const allowUpdate = canuse_state.length === 0 || canuse_state.includes(oldstate);
if (!allowUpdate) {
ElMessage.warning(`只有 [${canuse_state.join(",")}] 的记录才能 ${state}!`);
return;
}
// 针对 cw_zdorder 模块的附表更新逻辑
if (["cw_zdorder", "cw_zdorder_f"].includes(ModuleID)) {
let searchsql = `select * from bs_business_cw where isnull(mx_zdorderid,'')='${row.b_id}' order by subid`;
const response = await axios.get("/selectlistbysql", { params: { sql: searchsql } });
if (response.data?.success) {
const records = response.data.data.records || [];
if (records.length > 0) {
for (const cw of records) {
updateFeeData.push({
subid: cw.subid,
father: cw.father,
mx_zdorder_state: state,
});
}
}
}
// 审核驳回时校验费用
if (state === "审核驳回") {
const sql = `select count(*) as cnt,sum(case when isnull(mx_invoiceid,'')<>'' or isnull(mx_sumamount,0)<>0 then 1 else 0 end) as un_cnt from bs_business_cw where mx_zdorderid='${row.b_id}'`;
const response = await axios.get("/selectlistbysql", { params: { sql } });
if (response.data?.success) {
const records = response.data.data.records || [];
if (records.length > 0) {
if (records[0].cnt > 0 && records[0].cnt === records[0].un_cnt) {
ElMessage.error("驳回失败!费用项已销账或开票!");
return;
}
}
}
}
}
// 针对仓库模块的校验
if (["ck_in", "ck_out"].includes(ModuleID)) {
if (state === "审核驳回" && row.b_depotconfirm === "1") {
ElMessage.error("驳回失败!仓库确认数据不能驳回!");
return;
}
}
const obj = { b_id: row.b_id, b_state: state };
updateRows.push(obj);
}
const requestData = [];
if (updateRows.length > 0) {
requestData.push({
tableName: savetable,
keyField: "b_id",
inserts: [],
updates: updateRows,
deletes: [],
});
if (updateFeeData.length > 0) {
requestData.push({
tableName: "bs_business_cw",
keyField: "subid",
inserts: [],
updates: updateFeeData,
deletes: [],
});
}
}
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success(state + "成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
};
// ---------------------------
export async function tosh(row, moduleid, tablename, func) {
try {
if (row.b_state !== "草拟" && !row.b_state.includes("驳回")) {
ElMessage.warning("只有状态为草拟或驳回的数据才能进行送审");
return;
}
let strid = row.b_id;
// === 5. 弹出选择审批人弹窗 ===
const data = await opentoshDialog();
if (!data) {
ElMessage.info("已取消送审");
return;
}
// === 7. 调用保存函数 ===
await save_tosh_data(moduleid, tablename, strid, data.memo, func);
} catch (err) {
console.error(err);
ElMessage.error("送审失败");
}
}
export function opentoshDialog(levelUserIds, ywownerid) {
return new Promise((resolve) => {
const container = document.createElement("div");
document.body.appendChild(container);
const closeDialog = () => {
render(null, container);
document.body.removeChild(container);
};
const vnode = createVNode(toshDialog, {
modelValue: true,
onConfirm: (data) => {
closeDialog();
resolve(data);
},
onCancel: () => {
closeDialog();
resolve(null);
},
});
render(vnode, container);
});
}
async function save_tosh_data(ModuleID, tablename, strid, sh_memo, func) {
const userStore = useUserStore();
let sstate = "";
let jobj = [];
let recordrows = [];
let wxsenddatas = [];
let thistime = dayjs().format("YYYY-MM-DD HH:mm:ss");
const res = await getDataBySql(`select * from ${tablename} where b_id='${strid}' order by b_id`);
if (res.records.length > 0) {
for (let item of res.records) {
const res1 = await getDataBySql(`select b_state from ${tablename} where b_id='${item.b_id}'`);
if (res1.records.length > 0) {
sstate = res1.records[0].b_state;
}
if (sstate != "草拟" && sstate.indexOf("驳回") <= -1) {
ElMessage.warning("只有状态为草拟或驳回的数据才能进行送审");
return;
}
let jtmp = {};
jtmp.b_id = item.b_id;
jtmp.b_state = "送审";
jobj.push(jtmp);
var recrow = {};
recrow["b_module_id"] = ModuleID;
recrow["b_user_id"] = userStore.userInfo.userid;
recrow["b_dj_id"] = item.b_id;
recrow["b_level"] = "0";
recrow["b_sh"] = "1";
recrow["b_name"] = "送审";
recrow["b_sh_date"] = thistime;
recrow["b_sh_memo"] = sh_memo;
recordrows.push(recrow);
let modname = "";
const res = await getDataBySql(`select b_ChineseName from s_module where b_id='${ModuleID}'`);
if (res.records.length > 0) {
modname = res.records[0].b_ChineseName;
}
const ds_datas = await getDataBySql(
`select sh_b_set.b_condition,b_user_id,b_user.b_phone,sh_b_set.b_level,b_user.b_password from sh_b_set left join b_user on sh_b_set.b_user_id = b_user.b_id where b_module_id='${ModuleID}' and b_level='1'`,
);
if (ds_datas.records.length > 0) {
for (const k of ds_datas.records) {
if (k.b_phone != "") {
let canuse = true;
let condition = k.b_condition;
let mobileids = k.b_phone;
if (condition) {
const res1 = await getDataBySql(
`select * from ${tablename} where b_id='${item.b_id}' and ${condition}`,
);
if (res1.records.length == 0) {
canuse = false;
}
if (canuse) {
var obj = {};
obj["mobileids"] = mobileids;
obj["b_id"] = item.b_id;
obj["modid"] = modname;
obj["b_owner_id"] = userStore.userInfo.userid;
obj["orgid"] = userStore.userInfo.orgid;
obj["userid"] = k.b_user_id;
obj["password"] = k.b_password;
wxsenddatas.push(obj);
}
}
}
}
}
}
}
const requestData = [
{
tableName: "sh_record",
keyField: "b_id",
inserts: recordrows,
updates: [],
deletes: [],
},
{
tableName: tablename,
keyField: "b_id",
inserts: [],
updates: jobj,
deletes: [],
},
];
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success("送审成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
}
export async function shcenter_cs(rows, ModuleID, tablename, func) {
const userStore = useUserStore();
let sstate = "";
let jobj = [];
let recordrows = [];
let thistime = dayjs().format("YYYY-MM-DD HH:mm:ss");
const res1 = await getDataBySql(`select b_state from ${tablename} where b_id='${rows.b_id}'`);
if (res1.records.length > 0) {
sstate = res1.records[0].b_state;
}
if (sstate != "送审") {
ElMessage.warning("只有状态为送审的数据才能进行撤审!");
return;
}
let jtmp = {};
jtmp.b_id = rows.b_id;
jtmp.b_state = "草拟";
jobj.push(jtmp);
var recrow = {};
recrow["b_module_id"] = ModuleID;
recrow["b_user_id"] = userStore.userInfo.userid;
recrow["b_dj_id"] = rows.b_id;
recrow["b_level"] = "0";
recrow["b_sh"] = "0";
recrow["b_name"] = "撤销送审";
recrow["b_sh_date"] = thistime;
recrow["b_sh_memo"] = "";
recordrows.push(recrow);
const requestData = [
{
tableName: "sh_record",
keyField: "b_id",
inserts: recordrows,
updates: [],
deletes: [],
},
{
tableName: tablename,
keyField: "b_id",
inserts: [],
updates: jobj,
deletes: [],
},
];
const response = await axios.post("/saveobjectV2", requestData, {
headers: { "Content-Type": "application/json" },
});
if (response.data?.success) {
ElMessage.success("撤审成功!");
if (typeof func === "function") {
await func();
}
} else {
throw new Error(response.data?.message || "保存失败");
}
}
+12 -2
View File
@@ -55,7 +55,17 @@ export function getcheckdjid(strvalid = "") {
}
export function getDateAfter(date, after = 0) {
return dayjs(date).add(Number(after), "day").format("YYYY-MM-DD");
if (!date) {
return "";
}
const d = dayjs(date);
if (!d.isValid()) {
return "";
}
return d.add(Number(after), "day").format("YYYY-MM-DD");
}
// 默认导出所有方法
@@ -66,4 +76,4 @@ export default {
formatToDate,
formatToDateTime,
getcheckdjid,
};
};