纸板小程序:订单/送货单:列表与详情功能
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
// utils/app.ts
|
||||
import { IAppOption } from '../app'; // 引入你定义的IAppOption接口
|
||||
|
||||
/**
|
||||
* 获取带TS类型的App实例(全局复用)
|
||||
*/
|
||||
export const getAppInstance = (): IAppOption => {
|
||||
const appInstance = getApp<IAppOption>(); // 核心:TS类型断言
|
||||
if (!appInstance) {
|
||||
throw new Error('App实例未初始化');
|
||||
}
|
||||
return appInstance;
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
import { getCustomerList, getSupplierList } from '../api/index'
|
||||
import { getAppInstance } from './app';
|
||||
|
||||
// 获取客户数据
|
||||
export async function getCustomerData() {
|
||||
const app = getAppInstance();
|
||||
const res = await getCustomerList({ isGetAll: true, orderBy: 'sortnum asc' }).catch(() => {});
|
||||
if (res && res.data.list) {
|
||||
app.globalData.customerList = res.data.list.map(item => {
|
||||
item.label = item.name;
|
||||
item.value = item.id;
|
||||
return item;
|
||||
});
|
||||
app.globalData.customerList.unshift({label: '全部',value: 0})
|
||||
}else {
|
||||
app.globalData.customerList = [];
|
||||
}
|
||||
}
|
||||
// 获取供应商数据
|
||||
export async function getSupplierData() {
|
||||
const app = getAppInstance();
|
||||
const res = await getSupplierList({ isGetAll: true, orderBy: 'sortnum asc' }).catch(() => {});
|
||||
if (res && res.data.list) {
|
||||
app.globalData.supplierList = res.data.list.map(item => {
|
||||
item.label = item.name;
|
||||
item.value = item.id;
|
||||
return item;
|
||||
});
|
||||
app.globalData.supplierList.unshift({label: '全部',value: 0})
|
||||
}else {
|
||||
app.globalData.supplierList = [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// utils/request.ts
|
||||
import { RequestOptions, ApiResponse, RequestPromise } from '../types/request';
|
||||
|
||||
// 基础域名(区分开发/生产环境,建议通过环境变量配置)
|
||||
|
||||
const BASE_URL = 'https://yueyingkeji.twaycloud.com/api' // 生产环境‘
|
||||
|
||||
/**
|
||||
* 通用请求函数(Promise 风格)
|
||||
* @param options 请求配置
|
||||
* @returns Promise<ApiResponse<T>>
|
||||
*/
|
||||
export const request = <T = any>(options: RequestOptions): RequestPromise<T> => {
|
||||
// 解构配置,设置默认值
|
||||
const {
|
||||
url,
|
||||
method = 'GET',
|
||||
data = {},
|
||||
header = {},
|
||||
timeout = 10000
|
||||
} = options;
|
||||
let { showLoading, ...realData } = data;
|
||||
|
||||
// 2. 真正要传给接口的数据(已经剔除了 showLoading)
|
||||
const requestData = realData;
|
||||
showLoading = options.data?options.data.showLoading:true;
|
||||
// 显示加载中弹窗
|
||||
if (showLoading) {
|
||||
wx.showLoading({ title: options.method == 'POST'?'提交中...':'加载中...', mask: true });
|
||||
}
|
||||
|
||||
// 拼接完整URL(相对路径补全域名,完整URL直接使用)
|
||||
const fullUrl = url.startsWith('http') ? url : `${BASE_URL}${url}`;
|
||||
const userInfo = wx.getStorageSync('userInfo');
|
||||
const token = `${userInfo.id},${userInfo.accesstoken}`;
|
||||
const devicecode = wx.getStorageSync('deviceCode');
|
||||
// 构建请求头(默认JSON格式,自动携带登录Token)
|
||||
const defaultHeader = {
|
||||
'Content-Type': 'application/json',
|
||||
// 从本地缓存获取Token(结合之前的登录逻辑)
|
||||
'Authorization': token,
|
||||
'devicecode': devicecode
|
||||
};
|
||||
const finalHeader = { ...defaultHeader, ...header };
|
||||
|
||||
// 返回Promise,封装wx.request
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url: fullUrl,
|
||||
method,
|
||||
data: requestData,
|
||||
header: finalHeader,
|
||||
timeout,
|
||||
// 成功回调(后端返回响应,无论code是否为200)
|
||||
success: (res) => {
|
||||
// 类型断言:将res.data转为ApiResponse类型
|
||||
// const response = res.data;
|
||||
// 业务错误(如code≠200):reject出去,外层catch处理
|
||||
if (res.statusCode == 401) {
|
||||
const userInfo = wx.getStorageSync('userInfo');
|
||||
if (userInfo) {
|
||||
wx.showToast({ title: '登录已过期,请重新登录', icon: 'none',duration: 1500 });
|
||||
wx.removeStorageSync('userInfo');
|
||||
setTimeout(() => {
|
||||
wx.reLaunch({ url: '/pages/login/login' });
|
||||
}, 1300);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((!res.statusCode || res.statusCode != 200) || res.data.success == false) {
|
||||
wx.showToast({ title: res.data.message || '请求失败', icon: 'none',duration: 1500 });
|
||||
reject({
|
||||
type: 'business', // 业务错误类型
|
||||
...res
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 业务成功:resolve返回响应数据
|
||||
resolve(res);
|
||||
},
|
||||
// 失败回调(网络错误、超时等)
|
||||
fail: (err) => {
|
||||
const errMsg = err.errMsg || '网络异常,请稍后重试';
|
||||
wx.showToast({ title: errMsg, icon: 'none',duration: 1500 });
|
||||
reject({
|
||||
type: 'network', // 网络错误类型
|
||||
code: -1,
|
||||
msg: errMsg,
|
||||
data: null
|
||||
});
|
||||
},
|
||||
// 完成回调(无论成功/失败,关闭加载弹窗)
|
||||
complete: () => {
|
||||
if (showLoading) {
|
||||
setTimeout(() => {
|
||||
wx.hideLoading();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 封装常用请求方法(简化调用)
|
||||
export const get = <T = any>(
|
||||
url: string,
|
||||
data?: Record<string, any>,
|
||||
options?: Omit<RequestOptions, 'url' | 'method'>
|
||||
): RequestPromise<T> => {
|
||||
return request<T>({ url, method: 'GET', ...data, ...options });
|
||||
};
|
||||
|
||||
export const post = <T = any>(
|
||||
url: string,
|
||||
data?: Record<string, any>,
|
||||
options?: Omit<RequestOptions, 'url' | 'method'>
|
||||
): RequestPromise<T> => {
|
||||
return request<T>({ url, method: 'POST', data, ...options });
|
||||
};
|
||||
|
||||
export const put = <T = any>(
|
||||
url: string,
|
||||
data?: Record<string, any>,
|
||||
options?: Omit<RequestOptions, 'url' | 'method'>
|
||||
): RequestPromise<T> => {
|
||||
return request<T>({ url, method: 'PUT', data, ...options });
|
||||
};
|
||||
|
||||
export const del = <T = any>(
|
||||
url: string,
|
||||
data?: Record<string, any>,
|
||||
options?: Omit<RequestOptions, 'url' | 'method'>
|
||||
): RequestPromise<T> => {
|
||||
return request<T>({ url, method: 'DELETE', data, ...options });
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
export const formatTime = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return (
|
||||
[year, month, day].map(formatNumber).join('/') +
|
||||
' ' +
|
||||
[hour, minute, second].map(formatNumber).join(':')
|
||||
)
|
||||
}
|
||||
|
||||
const formatNumber = (n: number) => {
|
||||
const s = n.toString()
|
||||
return s[1] ? s : '0' + s
|
||||
}
|
||||
|
||||
export const getMonthDay = () => {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth(); // 0~11,0代表1月
|
||||
|
||||
// 当月第一天
|
||||
const firstDay = new Date(year, month, 1);
|
||||
// 当月最后一天:下个月的第0天
|
||||
const lastDay = new Date(year, month + 1, 0);
|
||||
|
||||
// 格式化日期为 YYYY-MM-DD
|
||||
const format = (date) => {
|
||||
const y = date.getFullYear();
|
||||
const m = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const d = date.getDate().toString().padStart(2, '0');
|
||||
return `${y}-${m}-${d}`;
|
||||
};
|
||||
|
||||
const firstStr = format(firstDay); // 例如 2026-06-01
|
||||
const lastStr = format(lastDay); // 例如 2026-06-30
|
||||
return [firstStr,lastStr]
|
||||
}
|
||||
Reference in New Issue
Block a user