diff --git a/src/api/supermarketerp/types/inventoryInOutReport.ts b/src/api/supermarketerp/types/inventoryInOutReport.ts new file mode 100644 index 0000000..cb5554e --- /dev/null +++ b/src/api/supermarketerp/types/inventoryInOutReport.ts @@ -0,0 +1,73 @@ +// 进销存报表相关类型定义 + +// 查询参数接口 +export interface InventoryInOutQueryParams { + current?: number // 当前页码 + size?: number // 每页记录数 + startDate?: string // 开始日期 (yyyy-MM-dd) + endDate?: string // 结束日期 (yyyy-MM-dd) + startTime?: string // 开始时间 (yyyy-MM-dd HH:mm:ss) + endTime?: string // 结束时间 (yyyy-MM-dd HH:mm:ss) + productName?: string // 商品名称 + productCode?: string // 商品编码 + categoryId?: number // 分类ID + warehouseId?: string // 仓库ID + onlyChanged?: boolean // 是否仅显示有发生额的商品 + topLimit?: number // 限制返回记录数 +} + +// 进销存报表数据项接口 +export interface InventoryInOutItem { + productId: number // 商品ID + productCode: string // 商品编码 + productName: string // 商品名称 + categoryId: number // 分类ID + categoryName: string // 分类名称 + unit: string // 基础单位 + openingQty: number // 期初库存数量 + inQty: number // 入库数量 + outQty: number // 出库数量 + closingQty: number // 期末库存数量 + inAmount: number // 入库金额 + outAmount: number // 出库金额 +} + +// 分页响应接口 +export interface InventoryInOutPageResponse { + records: InventoryInOutItem[] // 数据列表 + total: number // 总记录数 + size: number // 每页记录数 + current: number // 当前页码 + pages: number // 总页数 +} + +// 汇总统计接口 +export interface InventoryInOutSummary { + totalProducts: number // 统计商品总数 + changedProducts: number // 有发生额的商品数量 + totalOpeningQty: number // 总期初库存数量 + totalInQty: number // 总入库数量 + totalOutQty: number // 总出库数量 + totalClosingQty: number // 总期末库存数量 + totalInAmount: number // 总入库金额 + totalOutAmount: number // 总出库金额 + turnoverRate: number // 库存周转率 + avgPrice: number // 平均单价 +} + +// API响应接口 +export interface ApiResponse { + code: number // 状态码 + msg: string // 消息描述 + data: T // 具体数据 +} + +// 分页查询响应 +export type InventoryInOutPageApiResponse = ApiResponse + +// 列表查询响应 +export type InventoryInOutListApiResponse = ApiResponse + +// 汇总统计响应 +export type InventoryInOutSummaryApiResponse = ApiResponse + diff --git a/src/components/DictSelect/index.vue b/src/components/DictSelect/index.vue index 6433532..9711e8a 100644 --- a/src/components/DictSelect/index.vue +++ b/src/components/DictSelect/index.vue @@ -1,6 +1,6 @@ @@ -16,9 +16,11 @@ export type Props = { dictCode: string placeholder?: string hideIds?: string | Array + multiple?: boolean } const props = withDefaults(defineProps(), { placeholder: "请选择", + multiple: false, }) const state = reactive({ diff --git a/src/utils/jsonp.ts b/src/utils/jsonp.ts index bcd3676..d1b6420 100644 --- a/src/utils/jsonp.ts +++ b/src/utils/jsonp.ts @@ -7,7 +7,6 @@ interface JsonpOptions { timeout?: number callbackName?: string callbackParam?: string - debug?: boolean } /** @@ -18,17 +17,11 @@ interface JsonpOptions { */ export function jsonp(url: string, options: JsonpOptions = {}): Promise { const { - timeout = 15000, + timeout = 10000, callbackName = `jsonp_callback_${Date.now()}_${Math.random().toString(36).substr(2)}`, callbackParam = "callback", - debug = false } = options - if (debug) { - console.log('[JSONP] 发起请求:', url) - console.log('[JSONP] 回调函数名:', callbackName) - } - return new Promise((resolve, reject) => { // 创建 script 标签 const script = document.createElement("script") @@ -36,11 +29,7 @@ export function jsonp(url: string, options: JsonpOptions = {}): Promise { // 设置超时 const timer = setTimeout(() => { cleanup() - const error = new Error(`JSONP request timeout after ${timeout}ms`) - if (debug) { - console.error('[JSONP] 请求超时:', error) - } - reject(error) + reject(new Error("JSONP request timeout")) }, timeout) // 清理函数 @@ -56,34 +45,22 @@ export function jsonp(url: string, options: JsonpOptions = {}): Promise { // 设置全局回调函数 ;(window as any)[callbackName] = (data: any) => { - if (debug) { - console.log('[JSONP] 收到响应:', data) - } cleanup() resolve(data) } // 处理错误 - script.onerror = (event) => { + script.onerror = () => { cleanup() - const error = new Error("JSONP request failed to load script") - if (debug) { - console.error('[JSONP] 脚本加载失败:', event) - } - reject(error) + reject(new Error("JSONP request failed")) } // 构建请求 URL const separator = url.includes("?") ? "&" : "?" const requestUrl = `${url}${separator}${callbackParam}=${callbackName}` - if (debug) { - console.log('[JSONP] 完整请求URL:', requestUrl) - } - // 发起请求 script.src = requestUrl - script.async = true document.head.appendChild(script) }) } @@ -93,11 +70,9 @@ export function jsonp(url: string, options: JsonpOptions = {}): Promise { */ export class TencentMapAPI { private apiKey: string - private debug: boolean - constructor(apiKey: string, debug: boolean = false) { + constructor(apiKey: string) { this.apiKey = apiKey - this.debug = debug } /** @@ -109,17 +84,8 @@ export class TencentMapAPI { async reverseGeocode(lat: number, lng: number): Promise { const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${this.apiKey}&get_poi=1&output=jsonp` - if (this.debug) { - console.log('[TencentMapAPI] 逆地址解析请求:', { lat, lng }) - } - try { - const data = await jsonp(url, { debug: this.debug }) - - if (this.debug) { - console.log('[TencentMapAPI] 逆地址解析响应:', data) - } - + const data = await jsonp(url) return data } catch (error) { console.error("逆地址解析失败:", error) @@ -138,17 +104,8 @@ export class TencentMapAPI { keyword, )}&page_size=10&page_index=1&key=${this.apiKey}&output=jsonp` - if (this.debug) { - console.log('[TencentMapAPI] 地址搜索请求:', { keyword, boundary }) - } - try { - const data = await jsonp(url, { debug: this.debug }) - - if (this.debug) { - console.log('[TencentMapAPI] 地址搜索响应:', data) - } - + const data = await jsonp(url) return data } catch (error) { console.error("地址搜索失败:", error) diff --git a/src/utils/other.ts b/src/utils/other.ts index 251f19b..2b9b1f9 100644 --- a/src/utils/other.ts +++ b/src/utils/other.ts @@ -261,9 +261,13 @@ export function downBlobFile(url: any, query: any, fileName: string) { method: "get", responseType: "blob", params: query, - }).then((response) => { - handleBlobFile(response, fileName) }) + .then((response) => { + handleBlobFile(response, fileName) + }) + .catch((error) => { + useMessage().error(error.msg || "下载失败") + }) } export function postDownBlobFile(url: any, data: any, fileName: string) { @@ -278,9 +282,13 @@ export function postDownBlobFile(url: any, data: any, fileName: string) { descs: data?.descs ?? [], }, data, - }).then((response) => { - handleBlobFile(response, fileName) }) + .then((response) => { + handleBlobFile(response, fileName) + }) + .catch((error) => { + useMessage().error(error.msg || "下载失败") + }) } /** diff --git a/src/views/hard/hard-order/index.vue b/src/views/hard/hard-order/index.vue index 930c02f..832bf8d 100644 --- a/src/views/hard/hard-order/index.vue +++ b/src/views/hard/hard-order/index.vue @@ -30,6 +30,10 @@ + + + diff --git a/src/views/hard/hard-sh/index.vue b/src/views/hard/hard-sh/index.vue index 7bfb113..1f78747 100644 --- a/src/views/hard/hard-sh/index.vue +++ b/src/views/hard/hard-sh/index.vue @@ -87,7 +87,7 @@ - + @@ -138,6 +141,10 @@ const doCheckout = (row: any) => { push({ path: "/mch/mch-checkout/index", query: { mchId: row.merchantId } }) } +const exportMchExcel = (row: any) => { + postDownBlobFile("/hard/hard-total/export-mch-cs", { ...state.queryForm, merchantId: row.merchantId }, "商户流水.xlsx") +} + const getSummaries = (param: any) => { const { columns, data } = param const totalColumns = ["totalPayPrice", "totalPayCount", "totalRefundPrice", "totalRefundCount", "totalProfitPrice", "totalProfitCount"] diff --git a/src/views/mch/mch-checkout/index.vue b/src/views/mch/mch-checkout/index.vue index 7742059..6f0723b 100644 --- a/src/views/mch/mch-checkout/index.vue +++ b/src/views/mch/mch-checkout/index.vue @@ -1,16 +1,19 @@