diff --git a/src/App.vue b/src/App.vue index 57a2f04..bf5fd34 100644 --- a/src/App.vue +++ b/src/App.vue @@ -8,6 +8,7 @@ import { useSettingsStore } from '@/store/modules/settings'; import { handleThemeStyle } from '@/utils/theme'; import { useAppStore } from '@/store/modules/app'; +import { useDictStore } from './store/modules/dict'; const appStore = useAppStore(); onMounted(() => { diff --git a/src/api/system/SdbChargeItem/index.ts b/src/api/system/SdbChargeItem/index.ts new file mode 100644 index 0000000..7526c84 --- /dev/null +++ b/src/api/system/SdbChargeItem/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ChargeItemVO, ChargeItemForm, ChargeItemQuery } from './type'; + +/** + * 查询收费项目管理列表 + * @param query + * @returns {*} + */ + +export const listChargeItem = (query?: ChargeItemQuery): AxiosPromise => { + return request({ + url: '/chargeItem/list', + method: 'get', + params: query + }); +}; + +/** + * 查询收费项目管理详细 + * @param id + */ +export const getChargeItem = (id: string | number): AxiosPromise => { + return request({ + url: '/chargeItem/' + id, + method: 'get' + }); +}; + +/** + * 新增收费项目管理 + * @param data + */ +export const addChargeItem = (data: ChargeItemForm) => { + return request({ + url: '/chargeItem', + method: 'post', + data: data + }); +}; + +/** + * 修改收费项目管理 + * @param data + */ +export const updateChargeItem = (data: ChargeItemForm) => { + return request({ + url: '/chargeItem', + method: 'put', + data: data + }); +}; + +/** + * 删除收费项目管理 + * @param id + */ +export const delChargeItem = (id: string | number | Array) => { + return request({ + url: '/chargeItem/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/SdbChargeItem/type.ts b/src/api/system/SdbChargeItem/type.ts new file mode 100644 index 0000000..6fee7d4 --- /dev/null +++ b/src/api/system/SdbChargeItem/type.ts @@ -0,0 +1,150 @@ +export interface ChargeItemVO { + /** + * 收费项目管理表id + */ + id: string | number; + + /** + * 项目名称 + */ + name: string; + + /** + * 计费方式 0单次收费 1周期收费 2仪表收费 + */ + billingMethod: string; + + /** + * 单价 + */ + price: number; + + /** + * 单位 0㎡ 1度 3m³ 4升 + */ + unit: string; + + /** + * 精度 0保留两位小数 1保留一位小数 2保留整数 + */ + precision: string; + + /** + * 进位方式 0四舍五入 1向上进位 2向下进位 + */ + carryMethod: string; + + /** + * 滞纳金比例 % + */ + lateFee: number; + + /** + * 备注 + */ + remark: string; + + /** + * 小区id + */ + villageId: string | number; +} + +export interface ChargeItemForm extends BaseEntity { + /** + * 收费项目管理表id + */ + id?: string | number; + + /** + * 项目名称 + */ + name?: string; + + /** + * 计费方式 0单次收费 1周期收费 2仪表收费 + */ + billingMethod?: string; + + /** + * 单价 + */ + price?: number; + + /** + * 单位 0㎡ 1度 3m³ 4升 + */ + unit?: string; + + /** + * 精度 0保留两位小数 1保留一位小数 2保留整数 + */ + precision?: string; + + /** + * 进位方式 0四舍五入 1向上进位 2向下进位 + */ + carryMethod?: string; + + /** + * 滞纳金比例 % + */ + lateFee?: number; + + /** + * 备注 + */ + remark?: string; + + /** + * 小区id + */ + villageId?: string | number; +} + +export interface ChargeItemQuery extends PageQuery { + /** + * 项目名称 + */ + name?: string; + + /** + * 计费方式 0单次收费 1周期收费 2仪表收费 + */ + billingMethod?: string; + + /** + * 单价 + */ + price?: number; + + /** + * 单位 0㎡ 1度 3m³ 4升 + */ + unit?: string; + + /** + * 精度 0保留两位小数 1保留一位小数 2保留整数 + */ + precision?: string; + + /** + * 进位方式 0四舍五入 1向上进位 2向下进位 + */ + carryMethod?: string; + + /** + * 滞纳金比例 % + */ + lateFee?: number; + + /** + * 小区id + */ + villageId?: string | number; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/TPurchaseIn/index.ts b/src/api/system/TPurchaseIn/index.ts new file mode 100644 index 0000000..c5fcac7 --- /dev/null +++ b/src/api/system/TPurchaseIn/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { StockInVO, StockInForm, StockInQuery } from './type'; + +/** + * 查询入库主列表 + * @param query + * @returns {*} + */ + +export const listStockIn = (query?: StockInQuery): AxiosPromise => { + return request({ + url: '/stockIn/list', + method: 'get', + params: query + }); +}; + +/** + * 查询入库主详细 + * @param id + */ +export const getStockIn = (id: string | number): AxiosPromise => { + return request({ + url: '/stockIn/' + id, + method: 'get' + }); +}; + +/** + * 新增入库主 + * @param data + */ +export const addStockIn = (data: StockInForm) => { + return request({ + url: '/stockIn', + method: 'post', + data: data + }); +}; + +/** + * 修改入库主 + * @param data + */ +export const updateStockIn = (data: StockInForm) => { + return request({ + url: '/stockIn', + method: 'put', + data: data + }); +}; + +/** + * 删除入库主 + * @param id + */ +export const delStockIn = (id: string | number | Array) => { + return request({ + url: '/stockIn/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/TPurchaseIn/type.ts b/src/api/system/TPurchaseIn/type.ts new file mode 100644 index 0000000..f6a06f2 --- /dev/null +++ b/src/api/system/TPurchaseIn/type.ts @@ -0,0 +1,128 @@ +import { MaterialVO } from '../Tmaterial/type'; + +export interface StockInVO { + /** + * 主键 + */ + id: string | number; + + /** + * 入库单号* + */ + inNo: string; + + /** + * 入库日期* + */ + inDate: string; + totalAmount: string; + /** + * 供应商id* + */ + supplierId: string; + + /** + * 入库仓库id* + */ + warehouseId: string; + + /** + * 操作状态 入库/未入库 + */ + operateStatus: string; + + /** + * 负责人 + */ + leader: string; + + /** + * 备注 + */ + remark: string; + + items: MaterialVO[]; + + warehouseName: string; + supplierName: string; + createTime: string; +} + +export interface StockInForm extends BaseEntity { + /** + * 主键 + */ + id?: string | number; + + /** + * 入库单号* + */ + inNo?: string; + + /** + * 入库日期* + */ + inDate?: string; + + /** + * 供应商id* + */ + supplierId?: string; + + /** + * 入库仓库id* + */ + warehouseId?: string; + + /** + * 操作状态 入库/未入库 + */ + operateStatus?: string; + + /** + * 负责人 + */ + leader?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface StockInQuery extends PageQuery { + /** + * 入库单号* + */ + inNo?: string; + + /** + * 入库日期* + */ + inDate?: string; + + /** + * 供应商id* + */ + supplierId?: string; + + /** + * 入库仓库id* + */ + warehouseId?: string; + + /** + * 操作状态 入库/未入库 + */ + operateStatus?: string; + + /** + * 负责人 + */ + leader?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/TissueOut/index.ts b/src/api/system/TissueOut/index.ts new file mode 100644 index 0000000..2ccfeec --- /dev/null +++ b/src/api/system/TissueOut/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { StockOutVO, StockOutForm, StockOutQuery } from './type'; + +/** + * 查询出库主列表 + * @param query + * @returns {*} + */ + +export const listStockOut = (query?: StockOutQuery): AxiosPromise => { + return request({ + url: '/stockOut/list', + method: 'get', + params: query + }); +}; + +/** + * 查询出库主详细 + * @param id + */ +export const getStockOut = (id: string | number): AxiosPromise => { + return request({ + url: '/stockOut/' + id, + method: 'get' + }); +}; + +/** + * 新增出库主 + * @param data + */ +export const addStockOut = (data: StockOutForm) => { + return request({ + url: '/stockOut', + method: 'post', + data: data + }); +}; + +/** + * 修改出库主 + * @param data + */ +export const updateStockOut = (data: StockOutForm) => { + return request({ + url: '/stockOut', + method: 'put', + data: data + }); +}; + +/** + * 删除出库主 + * @param id + */ +export const delStockOut = (id: string | number | Array) => { + return request({ + url: '/stockOut/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/TissueOut/type.ts b/src/api/system/TissueOut/type.ts new file mode 100644 index 0000000..657f70f --- /dev/null +++ b/src/api/system/TissueOut/type.ts @@ -0,0 +1,127 @@ +import { MaterialVO } from '../Tmaterial/type'; + +export interface StockOutVO { + /** + * 主键 + */ + id: string; + + /** + * 出库单号* + */ + outNo: string; + + /** + * 出库日期* + */ + outDate: string; + totalAmount: string; + /** + * 领用人(供应商id)* + */ + supplierId: string; + + /** + * 出库仓库id* + */ + warehouseId: string; + + /** + * 操作状态 未出库/出库 + */ + operateStatus: string; + + /** + * 负责人 + */ + leader: string; + + /** + * 备注 + */ + remark: string; + items: MaterialVO[]; + + warehouseName: string; + supplierName: string; + createTime: string; +} + +export interface StockOutForm extends BaseEntity { + /** + * 主键 + */ + id?: string; + + /** + * 出库单号* + */ + outNo?: string; + + /** + * 出库日期* + */ + outDate?: string; + + /** + * 领用人(供应商id)* + */ + supplierId?: string; + + /** + * 出库仓库id* + */ + warehouseId?: string; + + /** + * 操作状态 未出库/出库 + */ + operateStatus?: string; + + /** + * 负责人 + */ + leader?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface StockOutQuery extends PageQuery { + /** + * 出库单号* + */ + outNo?: string; + + /** + * 出库日期* + */ + outDate?: string; + + /** + * 领用人(供应商id)* + */ + supplierId?: string; + + /** + * 出库仓库id* + */ + warehouseId?: string; + + /** + * 操作状态 未出库/出库 + */ + operateStatus?: string; + + /** + * 负责人 + */ + leader?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/Tmaterial/index.ts b/src/api/system/Tmaterial/index.ts new file mode 100644 index 0000000..53e5f68 --- /dev/null +++ b/src/api/system/Tmaterial/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { MaterialVO, MaterialForm, MaterialQuery } from './type'; + +/** + * 查询物料列表 + * @param query + * @returns {*} + */ + +export const listMaterial = (query?: MaterialQuery): AxiosPromise => { + return request({ + url: '/warehouse/material/list', + method: 'get', + params: query + }); +}; + +/** + * 查询物料详细 + * @param id + */ +export const getMaterial = (id: string | number): AxiosPromise => { + return request({ + url: '/warehouse/material/' + id, + method: 'get' + }); +}; + +/** + * 新增物料 + * @param data + */ +export const addMaterial = (data: MaterialForm) => { + return request({ + url: '/warehouse/material', + method: 'post', + data: data + }); +}; + +/** + * 修改物料 + * @param data + */ +export const updateMaterial = (data: MaterialForm) => { + return request({ + url: '/warehouse/material', + method: 'put', + data: data + }); +}; + +/** + * 删除物料 + * @param id + */ +export const delMaterial = (id: string | number | Array) => { + return request({ + url: '/warehouse/material/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/Tmaterial/type.ts b/src/api/system/Tmaterial/type.ts new file mode 100644 index 0000000..41d168c --- /dev/null +++ b/src/api/system/Tmaterial/type.ts @@ -0,0 +1,90 @@ +export interface MaterialVO { + /** + * 物料ID + */ + id: string; + + /** + * 物料名称* + */ + materialName: string; + + /** + * 品牌* + */ + brand: string; + + /** + * 规格型号* + */ + model: string; + + /** + * 计量单位 + */ + unit: string; + + /** + * 备注 + */ + remark: string; +} + +export interface MaterialForm extends BaseEntity { + /** + * 物料ID + */ + id?: string; + + /** + * 物料名称* + */ + materialName?: string; + + /** + * 品牌* + */ + brand?: string; + + /** + * 规格型号* + */ + model?: string; + + /** + * 计量单位 + */ + unit?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface MaterialQuery extends PageQuery { + /** + * 物料名称* + */ + materialName?: string; + + /** + * 品牌* + */ + brand?: string; + + /** + * 规格型号* + */ + model?: string; + + /** + * 计量单位 + */ + unit?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/Tstock/index.ts b/src/api/system/Tstock/index.ts new file mode 100644 index 0000000..eeddd1b --- /dev/null +++ b/src/api/system/Tstock/index.ts @@ -0,0 +1,16 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; + +/** + * 查询 库存查询列表 + * @param query + * @returns {*} + */ + +export const listStock = (query?: any): AxiosPromise => { + return request({ + url: '/stock/list', + method: 'get', + params: query + }); +}; diff --git a/src/api/system/Tsupplier/index.ts b/src/api/system/Tsupplier/index.ts new file mode 100644 index 0000000..27c5a3e --- /dev/null +++ b/src/api/system/Tsupplier/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { SupplierVO, SupplierForm, SupplierQuery } from './type'; + +/** + * 查询供应商列表 + * @param query + * @returns {*} + */ + +export const listSupplier = (query?: SupplierQuery): AxiosPromise => { + return request({ + url: '/warehouse/supplier/list', + method: 'get', + params: query + }); +}; + +/** + * 查询供应商详细 + * @param id + */ +export const getSupplier = (id: string | number): AxiosPromise => { + return request({ + url: '/warehouse/supplier/' + id, + method: 'get' + }); +}; + +/** + * 新增供应商 + * @param data + */ +export const addSupplier = (data: SupplierForm) => { + return request({ + url: '/warehouse/supplier', + method: 'post', + data: data + }); +}; + +/** + * 修改供应商 + * @param data + */ +export const updateSupplier = (data: SupplierForm) => { + return request({ + url: '/warehouse/supplier', + method: 'put', + data: data + }); +}; + +/** + * 删除供应商 + * @param id + */ +export const delSupplier = (id: string | number | Array) => { + return request({ + url: '/warehouse/supplier/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/Tsupplier/type.ts b/src/api/system/Tsupplier/type.ts new file mode 100644 index 0000000..1aa4666 --- /dev/null +++ b/src/api/system/Tsupplier/type.ts @@ -0,0 +1,105 @@ +export interface SupplierVO { + /** + * 主键ID + */ + id: string | number; + + /** + * 供应商名称* + */ + supplierName: string; + + /** + * 联系人* + */ + contactPerson: string; + + /** + * 联系电话* + */ + contactPhone: string; + + /** + * 邮箱 + */ + email: string; + + /** + * 地址 + */ + address: string; + + /** + * 备注 + */ + remark: string; +} + +export interface SupplierForm extends BaseEntity { + /** + * 主键ID + */ + id?: string | number; + + /** + * 供应商名称* + */ + supplierName?: string; + + /** + * 联系人* + */ + contactPerson?: string; + + /** + * 联系电话* + */ + contactPhone?: string; + + /** + * 邮箱 + */ + email?: string; + + /** + * 地址 + */ + address?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface SupplierQuery extends PageQuery { + /** + * 供应商名称* + */ + supplierName?: string; + + /** + * 联系人* + */ + contactPerson?: string; + + /** + * 联系电话* + */ + contactPhone?: string; + + /** + * 邮箱 + */ + email?: string; + + /** + * 地址 + */ + address?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/system/Twarehouse/index.ts b/src/api/system/Twarehouse/index.ts new file mode 100644 index 0000000..3e8179f --- /dev/null +++ b/src/api/system/Twarehouse/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { WarehouseVO, WarehouseForm, WarehouseQuery } from './type'; + +/** + * 查询仓库列表 + * @param query + * @returns {*} + */ + +export const listWarehouse = (query?: WarehouseQuery): AxiosPromise => { + return request({ + url: '/warehouse/list', + method: 'get', + params: query + }); +}; + +/** + * 查询仓库详细 + * @param id + */ +export const getWarehouse = (id: string | number): AxiosPromise => { + return request({ + url: '/warehouse/' + id, + method: 'get' + }); +}; + +/** + * 新增仓库 + * @param data + */ +export const addWarehouse = (data: WarehouseForm) => { + return request({ + url: '/warehouse', + method: 'post', + data: data + }); +}; + +/** + * 修改仓库 + * @param data + */ +export const updateWarehouse = (data: WarehouseForm) => { + return request({ + url: '/warehouse', + method: 'put', + data: data + }); +}; + +/** + * 删除仓库 + * @param id + */ +export const delWarehouse = (id: string | number | Array) => { + return request({ + url: '/warehouse/' + id, + method: 'delete' + }); +}; diff --git a/src/api/system/Twarehouse/type.ts b/src/api/system/Twarehouse/type.ts new file mode 100644 index 0000000..299599c --- /dev/null +++ b/src/api/system/Twarehouse/type.ts @@ -0,0 +1,120 @@ +export interface WarehouseVO { + /** + * 仓库ID + */ + id: string | number; + + /** + * 仓库名称* + */ + warehouseName: string; + + /** + * 仓库归属id*(关联com_village) + */ + villageId: number; + + /** + * 联系人* + */ + contactPerson: string; + + /** + * 联系电话* + */ + contactPhone: string; + + /** + * 地址 + */ + address: string; + + /** + * 状态 0-启用 1-禁用 + */ + status: string; + + /** + * 备注 + */ + remark: string; +} + +export interface WarehouseForm extends BaseEntity { + /** + * 仓库ID + */ + id?: string | number; + + /** + * 仓库名称* + */ + warehouseName?: string; + + /** + * 仓库归属id*(关联com_village) + */ + villageId?: number; + + /** + * 联系人* + */ + contactPerson?: string; + + /** + * 联系电话* + */ + contactPhone?: string; + + /** + * 地址 + */ + address?: string; + + /** + * 状态 0-启用 1-禁用 + */ + status?: string; + + /** + * 备注 + */ + remark?: string; +} + +export interface WarehouseQuery extends PageQuery { + /** + * 仓库名称* + */ + warehouseName?: string; + + /** + * 仓库归属id*(关联com_village) + */ + villageId?: number; + + /** + * 联系人* + */ + contactPerson?: string; + + /** + * 联系电话* + */ + contactPhone?: string; + + /** + * 地址 + */ + address?: string; + + /** + * 状态 0-启用 1-禁用 + */ + status?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/components/Holder/material.vue b/src/components/Holder/material.vue new file mode 100644 index 0000000..520412d --- /dev/null +++ b/src/components/Holder/material.vue @@ -0,0 +1,272 @@ + + + + + diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index c53fd3d..425f528 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -7,6 +7,7 @@ import { defineStore } from 'pinia'; import { ref } from 'vue'; import { useHouseStore } from './house'; import { UserInfo } from '@/api/system/user/types'; +import { useDictStore } from './dict'; export const useUserStore = defineStore('user', () => { const token = ref(getToken()); @@ -63,6 +64,7 @@ export const useUserStore = defineStore('user', () => { // 注销 const logout = async (): Promise => { + useDictStore().cleanDict(); await logoutApi(); token.value = ''; roles.value = []; diff --git a/src/utils/map.ts b/src/utils/map.ts new file mode 100644 index 0000000..3f2954a --- /dev/null +++ b/src/utils/map.ts @@ -0,0 +1,10 @@ +/** + * 合并两个对象数组并去重(基于 id,后面的覆盖前面的) + */ +export function mergeObjectsAndDedupe(arr1: T[], arr2: T[]): T[] { + const map = new Map(arr1.map((item) => [item.id, item])); + arr2.forEach((item) => { + if (item.id) map.set(item.id, item); + }); + return [...map.values()]; +} diff --git a/src/utils/money.ts b/src/utils/money.ts new file mode 100644 index 0000000..2f868ba --- /dev/null +++ b/src/utils/money.ts @@ -0,0 +1,82 @@ +/** + * 数字金额转中文大写(支持整数、小数) + * @param num - 待转换的金额(支持数字或字符串格式) + * @returns 中文大写金额字符串 + */ +export function convertToChineseCapital(num: number | string): string { + // 中文数字映射 + const digits: readonly string[] = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; + // 基本单位(个、拾、佰、仟) + const units: readonly string[] = ['', '拾', '佰', '仟']; + // 大单位(万、亿、万亿) + const bigUnits: readonly string[] = ['', '万', '亿', '万亿']; + + // 1. 标准化输入:保留4位小数,分割整数与小数部分 + const [intPartRaw, decPartRaw] = Number(num).toFixed(4).split('.'); + // 去除整数前导零,若全零则保留一个 '0' + const intPart: string = intPartRaw.replace(/^0+/, '') || '0'; + + let result: string = ''; + + // 2. 处理整数部分 + if (intPart === '0') { + result = '零元'; + } else { + // 从右向左,每4位分为一组(处理万、亿等大单位) + const groups: string[] = []; + let tempInt: string = intPart; + while (tempInt.length > 0) { + groups.unshift(tempInt.slice(-4)); + tempInt = tempInt.slice(0, -4); + } + + // 遍历每一组进行转换 + groups.forEach((group: string, gIndex: number) => { + let groupStr: string = ''; + let needZero: boolean = false; // 标记是否需要补零 + + for (let i = 0; i < group.length; i++) { + const digit: number = parseInt(group[i], 10); + const unitPos: number = group.length - 1 - i; // 当前数字对应的单位位置 + + if (digit === 0) { + needZero = true; + } else { + // 补零(如果前面有0) + if (needZero) { + groupStr += '零'; + needZero = false; + } + groupStr += digits[digit] + units[unitPos]; + } + } + + // 拼接大单位(万、亿) + if (groupStr) { + result += groupStr + bigUnits[groups.length - 1 - gIndex]; + } + }); + result += '元'; + } + + // 3. 处理小数部分(仅保留角、分,忽略毫、厘) + const jiao: number = parseInt(decPartRaw[0], 10); // 角(第1位小数) + const fen: number = parseInt(decPartRaw[1], 10); // 分(第2位小数) + + if (jiao === 0 && fen === 0) { + result += '整'; + } else { + // 处理“角” + if (jiao > 0) { + result += digits[jiao] + '角'; + } else if (jiao === 0 && fen > 0) { + result += '零'; + } + // 处理“分” + if (fen > 0) { + result += digits[fen] + '分'; + } + } + + return result; +} diff --git a/src/utils/print.ts b/src/utils/print.ts new file mode 100644 index 0000000..35cf6f9 --- /dev/null +++ b/src/utils/print.ts @@ -0,0 +1,264 @@ +/** + * 🔥 Vue后台专用 - 打印指定DIV(样式完全还原 + 无侧边栏/导航) + * 适配 Element Plus / scoped样式 / 后台管理系统 + */ +export function printVueDiv(elementId: string, title: string = '打印') { + const el = document.getElementById(elementId); + if (!el) { + console.error('未找到打印元素'); + return; + } + + const win = window.open('', '_blank', 'width=1000,height=800'); + if (!win) return; + + // ============================================== + // 【核心1】复制 全局样式 + Element Plus 样式 + // ============================================== + const styles = Array.from(document.querySelectorAll('link[rel="stylesheet"], style:not([scoped])')) + .map((item) => item.outerHTML) + .join(''); + + // ============================================== + // 【核心2】手动注入打印区域的 scoped 样式(关键!) + // ============================================== + const printScopeStyle = ` + +`; + + // ============================================== + // 【核心3】写入新窗口 + // ============================================== + win.document.write(` + + + + ${title} + + ${styles} + ${printScopeStyle} + + + ${el.outerHTML} + + + `); + + win.document.close(); + win.onload = () => { + setTimeout(() => { + win.print(); + win.close(); + }, 300); + }; +} +/** + * 打印指定 DOM 元素(绝对不会打印其他内容) + * @param elementId 目标 div 的 id + * @param title 打印标题(可选) + */ +export function printDivPure(elementId: string, title: string = '打印') { + // 1. 获取目标元素 + const targetElement = document.getElementById(elementId); + if (!targetElement) { + console.error(`未找到 id 为 "${elementId}" 的元素`); + return; + } + + // 2. 保存原页面的所有内容 + const originalBodyContent = document.body.innerHTML; + + // 3. 克隆目标元素 + const cloneElement = targetElement.cloneNode(true) as HTMLElement; + + // 4. 【核心】把 body 替换成只有目标元素的内容 + document.body.innerHTML = ''; + + // 添加打印专用样式 + const printStyle = document.createElement('style'); + printStyle.innerHTML = ` + @page { + size: A4; + margin: 10mm; + } + body { + margin: 0; + padding: 20px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + } + `; + document.head.appendChild(printStyle); + + // 插入目标元素 + document.body.appendChild(cloneElement); + + // 5. 打印 + window.print(); + + // 6. 【核心】打印完恢复原页面内容 + setTimeout(() => { + document.body.innerHTML = originalBodyContent; + document.head.removeChild(printStyle); + // 强制刷新一下 Vue 组件(避免恢复后事件丢失) + window.location.reload(); + }, 100); +} + +/** + * 打印指定 DOM 元素(新窗口法加强版,不刷新页面) + * @param elementId 目标 div 的 id + * @param title 打印标题(可选) + */ +export function printDivNewWindow(elementId: string, title: string = '打印') { + const targetElement = document.getElementById(elementId); + if (!targetElement) { + console.error(`未找到 id 为 "${elementId}" 的元素`); + return; + } + + const printWindow = window.open('', '_blank', 'width=800,height=1000'); + if (!printWindow) { + console.error('无法打开新窗口,请检查浏览器弹窗拦截设置'); + return; + } + + // 【关键】深度克隆目标元素,包括所有子节点 + const clone = targetElement.cloneNode(true) as HTMLElement; + + printWindow.document.write(` + + + + ${title} + + + ${Array.from(document.querySelectorAll('link[rel="stylesheet"]')) + .map((l) => l.outerHTML) + .join('')} + + ${Array.from(document.querySelectorAll('style')) + .map((s) => s.outerHTML) + .join('')} + + + + + `); + + // 把克隆的元素插入到新窗口 + printWindow.document.body.appendChild(clone); + printWindow.document.close(); + + // 等待加载完成后打印 + printWindow.onload = () => { + printWindow.focus(); + setTimeout(() => { + printWindow.print(); + printWindow.close(); + }, 300); + }; +} diff --git a/src/utils/request.ts b/src/utils/request.ts index a00f560..454f7e9 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -51,13 +51,20 @@ export function needVillageId(url: string): boolean { // 去掉 ? 后面的参数 const path = url.split('?')[0]; - // 遍历白名单,正则匹配 - return !whiteVillageId.some((pattern) => { - // 把 * 转成正则的 .* 通配 - const regPattern = pattern.replace(/\*/g, '[^\\/]*'); - const regex = new RegExp(`^${regPattern}$`); - return regex.test(path); + // 遍历白名单匹配 + const isWhite = whiteVillageId.some((pattern) => { + // 处理 /* 结尾的通配(匹配该路径及其所有子路径) + if (pattern.endsWith('/*')) { + const basePath = pattern.slice(0, -2); // 比如 /warehouse/* → /warehouse + // 只要 path 是 /warehouse 或 /warehouse/ 或 /warehouse/xxx 就匹配 + return path === basePath || path.startsWith(basePath + '/'); + } else { + // 精确匹配 + return path === pattern; + } }); + + return !isWhite; } // 请求拦截器 service.interceptors.request.use( @@ -105,6 +112,7 @@ service.interceptors.request.use( } else { obj = config.data; } + if (!config.data) config.data = {}; Object.assign(config.data, obj); diff --git a/src/views/system/Sdb/ChargeItem/add.vue b/src/views/system/Sdb/ChargeItem/add.vue new file mode 100644 index 0000000..43f60f8 --- /dev/null +++ b/src/views/system/Sdb/ChargeItem/add.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/src/views/system/Sdb/ChargeItem/index.vue b/src/views/system/Sdb/ChargeItem/index.vue new file mode 100644 index 0000000..fa9a012 --- /dev/null +++ b/src/views/system/Sdb/ChargeItem/index.vue @@ -0,0 +1,249 @@ + + + + + diff --git a/src/views/system/inspection/Record/index.vue b/src/views/system/inspection/Record/index.vue index 15abc42..edc325b 100644 --- a/src/views/system/inspection/Record/index.vue +++ b/src/views/system/inspection/Record/index.vue @@ -6,7 +6,7 @@ - + @@ -74,6 +74,7 @@ + + diff --git a/src/views/system/warehouse/Inventory/index.vue b/src/views/system/warehouse/Inventory/index.vue index ae6056c..81fe09d 100644 --- a/src/views/system/warehouse/Inventory/index.vue +++ b/src/views/system/warehouse/Inventory/index.vue @@ -1,12 +1,154 @@ - - + diff --git a/src/views/system/warehouse/IssueOut/Main.vue b/src/views/system/warehouse/IssueOut/Main.vue new file mode 100644 index 0000000..e8911f5 --- /dev/null +++ b/src/views/system/warehouse/IssueOut/Main.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/views/system/warehouse/IssueOut/add.vue b/src/views/system/warehouse/IssueOut/add.vue new file mode 100644 index 0000000..e10e055 --- /dev/null +++ b/src/views/system/warehouse/IssueOut/add.vue @@ -0,0 +1,267 @@ + + + + + diff --git a/src/views/system/warehouse/IssueOut/index.vue b/src/views/system/warehouse/IssueOut/index.vue index b9405b3..16abbaa 100644 --- a/src/views/system/warehouse/IssueOut/index.vue +++ b/src/views/system/warehouse/IssueOut/index.vue @@ -1,12 +1,237 @@ - - + diff --git a/src/views/system/warehouse/Material/addMaterial.vue b/src/views/system/warehouse/Material/addMaterial.vue new file mode 100644 index 0000000..8dfd1b8 --- /dev/null +++ b/src/views/system/warehouse/Material/addMaterial.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/views/system/warehouse/Material/index.vue b/src/views/system/warehouse/Material/index.vue index f2ce355..cf53eb6 100644 --- a/src/views/system/warehouse/Material/index.vue +++ b/src/views/system/warehouse/Material/index.vue @@ -1,12 +1,239 @@ - - + diff --git a/src/views/system/warehouse/PurchaseIn/Main.vue b/src/views/system/warehouse/PurchaseIn/Main.vue new file mode 100644 index 0000000..043aad4 --- /dev/null +++ b/src/views/system/warehouse/PurchaseIn/Main.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/views/system/warehouse/PurchaseIn/add.vue b/src/views/system/warehouse/PurchaseIn/add.vue new file mode 100644 index 0000000..de5f49b --- /dev/null +++ b/src/views/system/warehouse/PurchaseIn/add.vue @@ -0,0 +1,275 @@ + + + + + diff --git a/src/views/system/warehouse/PurchaseIn/index.vue b/src/views/system/warehouse/PurchaseIn/index.vue index 7c28c8d..c87fcae 100644 --- a/src/views/system/warehouse/PurchaseIn/index.vue +++ b/src/views/system/warehouse/PurchaseIn/index.vue @@ -1,12 +1,228 @@ - - + diff --git a/src/views/system/warehouse/Supplier/addSupplier.vue b/src/views/system/warehouse/Supplier/addSupplier.vue new file mode 100644 index 0000000..8eab7dd --- /dev/null +++ b/src/views/system/warehouse/Supplier/addSupplier.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/src/views/system/warehouse/Supplier/index.vue b/src/views/system/warehouse/Supplier/index.vue index 0115d05..705eece 100644 --- a/src/views/system/warehouse/Supplier/index.vue +++ b/src/views/system/warehouse/Supplier/index.vue @@ -1,12 +1,247 @@ - - + diff --git a/src/views/system/warehouse/Warehouse/addWarehouse.vue b/src/views/system/warehouse/Warehouse/addWarehouse.vue new file mode 100644 index 0000000..d15f73d --- /dev/null +++ b/src/views/system/warehouse/Warehouse/addWarehouse.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/src/views/system/warehouse/Warehouse/index.vue b/src/views/system/warehouse/Warehouse/index.vue index 6ddd426..7a3f77b 100644 --- a/src/views/system/warehouse/Warehouse/index.vue +++ b/src/views/system/warehouse/Warehouse/index.vue @@ -1,12 +1,262 @@ - - +