移除前端静态HTML页面,迁移至现代化前端框架

This commit is contained in:
2025-09-18 12:43:41 +08:00
parent 19ca52d06c
commit 737d936bb3
125 changed files with 1507 additions and 12394 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

View File

@@ -960,9 +960,8 @@
},
"node_modules/@dcloudio/uni-ui": {
"version": "1.5.11",
"resolved": "https://registry.npmmirror.com/@dcloudio/uni-ui/-/uni-ui-1.5.11.tgz",
"integrity": "sha512-DBtk046ofmeFd82zRI7d89SoEwrAxYzUN3WVPm1DIBkpLPG5F5QDNkHMnZGu2wNrMEmGBjBpUh3vqEY1L3jaMw==",
"license": "Apache-2.0"
"resolved": "https://registry.npmjs.org/@dcloudio/uni-ui/-/uni-ui-1.5.11.tgz",
"integrity": "sha512-DBtk046ofmeFd82zRI7d89SoEwrAxYzUN3WVPm1DIBkpLPG5F5QDNkHMnZGu2wNrMEmGBjBpUh3vqEY1L3jaMw=="
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.20.2",

View File

@@ -1,5 +1,6 @@
import { request } from '@/utils/request';
import type { IAcceptance, IAcceptanceDetail } from '@/types/acceptance';
import type { IAcceptance, IAcceptanceDetail, IAcceptanceUpdateData } from '@/types/acceptance';
import type { ResponseData } from '@/types/request';
// 获取验收列表
export const fetchAcceptanceList = async (): Promise<IAcceptance[]> => {
@@ -7,7 +8,7 @@ export const fetchAcceptanceList = async (): Promise<IAcceptance[]> => {
const res = await request({
url: '/acceptance/list',
method: 'GET'
});
}) as ResponseData<IAcceptance[]>;
return res.data;
} catch (error) {
console.error('获取验收列表失败:', error);
@@ -21,7 +22,7 @@ export const fetchAcceptanceDetail = async (acceptanceId: string): Promise<IAcce
const res = await request({
url: `/acceptance/${acceptanceId}/detail`,
method: 'GET'
});
}) as ResponseData<IAcceptanceDetail>;
return res.data;
} catch (error) {
console.error('获取验收详情失败:', error);
@@ -41,10 +42,52 @@ export const submitAcceptance = async (data: {
url: '/acceptance/submit',
method: 'POST',
data
});
}) as ResponseData<IAcceptanceDetail>;
return res.data;
} catch (error) {
console.error('提交验收结果失败:', error);
throw error;
}
};
// 更新验收结果
export const updateAcceptance = async (
acceptanceId: string,
data: IAcceptanceUpdateData
): Promise<IAcceptanceDetail> => {
try {
const res = await request({
url: `/acceptance/${acceptanceId}/update`,
method: 'PUT',
data
}) as ResponseData<IAcceptanceDetail>;
return res.data;
} catch (error) {
console.error('更新验收结果失败:', error);
throw error;
}
};
// 获取验收统计数据
export const fetchAcceptanceStats = async (): Promise<{
total: number;
passed: number;
failed: number;
pending: number;
}> => {
try {
const res = await request({
url: '/acceptance/stats',
method: 'GET'
}) as ResponseData<{
total: number;
passed: number;
failed: number;
pending: number;
}>;
return res.data;
} catch (error) {
console.error('获取验收统计数据失败:', error);
throw error;
}
};

View File

@@ -1,84 +1,81 @@
{
"name": "活牛采购-客户端",
"appid": "",
"description": "活牛采购智能数字化系统客户端小程序",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
},
"modules": {},
"distribute": {
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>"
]
},
"ios": {
"dSYMs": false,
"privacyDescription": {
"NSLocationWhenInUseUsageDescription": "此应用需要访问您的位置信息,以便提供运输跟踪服务",
"NSCameraUsageDescription": "此应用需要访问您的相机,以便上传照片和视频",
"NSPhotoLibraryUsageDescription": "此应用需要访问您的相册,以便选择照片和视频",
"NSMicrophoneUsageDescription": "此应用需要访问您的麦克风,以便录制视频"
"name" : "活牛采购-客户端",
"appid" : "__UNI__D79EE30",
"description" : "活牛采购智能数字化系统客户端小程序",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>"
]
},
"ios" : {
"dSYMs" : false,
"privacyDescription" : {
"NSLocationWhenInUseUsageDescription" : "此应用需要访问您的位置信息,以便提供运输跟踪服务",
"NSCameraUsageDescription" : "此应用需要访问您的相机,以便上传照片和视频",
"NSPhotoLibraryUsageDescription" : "此应用需要访问您的相册,以便选择照片和视频",
"NSMicrophoneUsageDescription" : "此应用需要访问您的麦克风,以便录制视频"
}
}
}
},
"mp-weixin" : {
"appid" : "wx0123456789abcdef",
"setting" : {
"urlCheck" : false,
"es6" : true,
"postcss" : true,
"minified" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "您的位置信息将用于运输跟踪服务"
}
},
"requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
},
"mp-alipay" : {
"usingComponents" : true,
"appid" : "2021000000000000"
},
"vueVersion" : "3",
"h5" : {
"router" : {
"mode" : "hash",
"base" : "/"
},
"title" : "活牛采购-客户端",
"optimization" : {
"treeShaking" : {
"enable" : true
}
}
}
}
},
"mp-weixin": {
"appid": "wx0123456789abcdef",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"permission": {
"scope.userLocation": {
"desc": "您的位置信息将用于运输跟踪服务"
}
},
"requiredPrivateInfos": [
"getLocation",
"chooseLocation"
]
},
"mp-alipay": {
"usingComponents": true,
"appid": "2021000000000000"
},
"vueVersion": "3",
"h5": {
"router": {
"mode": "hash",
"base": "/"
},
"title": "活牛采购-客户端",
"optimization": {
"treeShaking": {
"enable": true
}
}
}
}
}

View File

@@ -1,18 +1,90 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { useOrderStore } from '@/stores/order';
import { fetchAcceptanceDetail } from '@/api/acceptance';
import { fetchAcceptanceDetail, updateAcceptance } from '@/api/acceptance';
import uniIcons from '@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue';
const UniIcons = uniIcons;
const orderStore = useOrderStore();
const acceptanceDetail = ref<any>(null);
const loading = ref(false);
const submitting = ref(false);
const error = ref('');
const showImagePreview = ref(false);
const currentImageIndex = ref(0);
const acceptanceId = ref('');
// 验收表单
const acceptanceForm = ref({
result: '',
notes: '',
weight: 0,
healthStatus: 'healthy',
images: [] as string[]
});
// 健康状态选项
const healthOptions = [
{ value: 'healthy', label: '健康' },
{ value: 'minor_issues', label: '轻微问题' },
{ value: 'major_issues', label: '严重问题' }
];
// 计算属性:状态文本
const statusText = computed(() => {
if (!acceptanceDetail.value) return '';
switch (acceptanceDetail.value.status) {
case 'passed':
return '验收通过';
case 'failed':
return '验收未通过';
default:
return '待验收';
}
});
// 计算属性:状态类名
const statusClass = computed(() => {
if (!acceptanceDetail.value) return '';
switch (acceptanceDetail.value.status) {
case 'passed':
return 'status-passed';
case 'failed':
return 'status-failed';
default:
return 'status-pending';
}
});
// 获取验收详情
const getAcceptanceDetail = async (acceptanceId: string) => {
const getAcceptanceDetail = async () => {
try {
loading.value = true;
acceptanceDetail.value = await fetchAcceptanceDetail(acceptanceId);
// 从路由参数获取验收ID
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const query = currentPage.$page?.options || {};
acceptanceId.value = query.id || '';
if (!acceptanceId.value) {
error.value = '缺少验收ID';
return;
}
acceptanceDetail.value = await fetchAcceptanceDetail(acceptanceId.value);
// 如果已有验收结果,填充表单
if (acceptanceDetail.value && acceptanceDetail.value.status !== 'pending') {
acceptanceForm.value = {
result: acceptanceDetail.value.result || '',
notes: acceptanceDetail.value.notes || '',
weight: acceptanceDetail.value.weight || 0,
healthStatus: acceptanceDetail.value.healthStatus || 'healthy',
images: acceptanceDetail.value.images || []
};
}
} catch (err) {
error.value = '获取验收详情失败';
console.error('获取验收详情失败:', err);
@@ -21,60 +93,489 @@ const getAcceptanceDetail = async (acceptanceId: string) => {
}
};
onMounted(() => {
const acceptanceId = ''; // 从路由参数获取
if (acceptanceId) {
getAcceptanceDetail(acceptanceId);
// 选择图片
const chooseImage = () => {
uni.chooseImage({
count: 9,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
// 上传图片到服务器(这里模拟上传成功)
const tempFilePaths = res.tempFilePaths;
acceptanceForm.value.images = [...acceptanceForm.value.images, ...tempFilePaths];
}
});
};
// 预览图片
const previewImage = (index: number) => {
currentImageIndex.value = index;
showImagePreview.value = true;
};
// 删除图片
const deleteImage = (index: number) => {
acceptanceForm.value.images.splice(index, 1);
};
// 提交验收结果
const submitAcceptance = async (status: 'passed' | 'failed') => {
if (!acceptanceDetail.value || !acceptanceId.value) return;
try {
submitting.value = true;
// 验证表单
if (!acceptanceForm.value.result) {
uni.showToast({
title: '请填写验收结果',
icon: 'none'
});
return;
}
// 提交验收结果
await updateAcceptance(acceptanceId.value, {
...acceptanceForm.value,
status,
acceptanceTime: new Date().toISOString()
});
uni.showToast({
title: status === 'passed' ? '验收通过' : '验收未通过',
icon: 'success'
});
// 刷新数据
setTimeout(() => {
getAcceptanceDetail();
}, 1500);
} catch (err) {
uni.showToast({
title: '提交验收结果失败',
icon: 'none'
});
console.error('提交验收结果失败:', err);
} finally {
submitting.value = false;
}
};
onMounted(() => {
getAcceptanceDetail();
});
</script>
<template>
<view class="container">
<!-- 验收详情 -->
<view v-if="acceptanceDetail" class="card">
<view class="flex-between">
<text class="text-bold">订单号: {{ acceptanceDetail.orderId }}</text>
<text :class="acceptanceDetail.status === 'passed' ? 'text-primary' : 'text-danger'">
{{ acceptanceDetail.status === 'passed' ? '验收通过' : '验收未通过' }}
</text>
</view>
<view class="divider"></view>
<text>验收时间: {{ acceptanceDetail.acceptanceTime }}</text>
<view class="margin-top-sm">
<text>验收人: {{ acceptanceDetail.acceptor }}</text>
</view>
<view class="margin-top-sm">
<text>验收结果: {{ acceptanceDetail.result }}</text>
</view>
<view class="margin-top-sm" v-if="acceptanceDetail.images">
<text>验收照片:</text>
<!-- 图片展示 -->
</view>
</view>
<!-- 加载状态 -->
<view class="flex-center" v-if="loading">
<view class="loading-state" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误信息 -->
<view class="flex-center" v-if="error">
<view class="error-state" v-if="error">
<text class="text-danger">{{ error }}</text>
<button type="default" size="mini" @tap="getAcceptanceDetail">重试</button>
</view>
<!-- 验收详情 -->
<block v-if="acceptanceDetail && !loading">
<!-- 订单信息 -->
<view class="section card">
<view class="section-header">
<text class="section-title">订单信息</text>
<text :class="statusClass">{{ statusText }}</text>
</view>
<view class="info-row">
<text class="info-label">订单号</text>
<text class="info-value">{{ acceptanceDetail.orderId }}</text>
</view>
<view class="info-row">
<text class="info-label">供应商</text>
<text class="info-value">{{ acceptanceDetail.supplierName || '未知' }}</text>
</view>
<view class="info-row">
<text class="info-label">牛只品种</text>
<text class="info-value">{{ acceptanceDetail.cattleBreed || '未知' }}</text>
</view>
<view class="info-row">
<text class="info-label">数量</text>
<text class="info-value">{{ acceptanceDetail.quantity || 0 }} </text>
</view>
</view>
<!-- 验收结果 -->
<view class="section card" v-if="acceptanceDetail.status !== 'pending'">
<view class="section-header">
<text class="section-title">验收结果</text>
</view>
<view class="info-row">
<text class="info-label">验收时间</text>
<text class="info-value">{{ acceptanceDetail.acceptanceTime || '未知' }}</text>
</view>
<view class="info-row">
<text class="info-label">验收人</text>
<text class="info-value">{{ acceptanceDetail.acceptor || '未知' }}</text>
</view>
<view class="info-row" v-if="acceptanceDetail.weight">
<text class="info-label">实际重量</text>
<text class="info-value">{{ acceptanceDetail.weight }} kg</text>
</view>
<view class="info-row" v-if="acceptanceDetail.healthStatus">
<text class="info-label">健康状况</text>
<text class="info-value">{{
acceptanceDetail.healthStatus === 'healthy' ? '健康' :
acceptanceDetail.healthStatus === 'minor_issues' ? '轻微问题' : '严重问题'
}}</text>
</view>
<view class="info-row">
<text class="info-label">验收结果</text>
<text class="info-value">{{ acceptanceDetail.result || '未知' }}</text>
</view>
<view class="info-row" v-if="acceptanceDetail.notes">
<text class="info-label">备注</text>
<text class="info-value">{{ acceptanceDetail.notes }}</text>
</view>
<!-- 验收图片 -->
<view class="image-section" v-if="acceptanceDetail.images && acceptanceDetail.images.length > 0">
<text class="image-title">验收图片</text>
<view class="image-grid">
<view
v-for="(image, index) in acceptanceDetail.images"
:key="index"
class="image-item"
@tap="previewImage(index)"
>
<image :src="image" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<!-- 验收表单 -->
<view class="section card" v-if="acceptanceDetail.status === 'pending'">
<view class="section-header">
<text class="section-title">验收表单</text>
</view>
<view class="form-item">
<text class="form-label">实际重量 (kg)</text>
<input
type="digit"
v-model="acceptanceForm.weight"
placeholder="请输入实际重量"
class="form-input"
/>
</view>
<view class="form-item">
<text class="form-label">健康状况</text>
<picker
mode="selector"
:range="healthOptions"
range-key="label"
@change="(e) => acceptanceForm.healthStatus = healthOptions[e.detail.value].value"
>
<view class="picker-view">
<text>{{
healthOptions.find(opt => opt.value === acceptanceForm.healthStatus)?.label
}}</text>
<UniIcons type="arrowdown" size="16" color="#666"></UniIcons>
</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">验收结果</text>
<textarea
v-model="acceptanceForm.result"
placeholder="请输入验收结果"
class="form-textarea"
></textarea>
</view>
<view class="form-item">
<text class="form-label">备注</text>
<textarea
v-model="acceptanceForm.notes"
placeholder="请输入备注信息(选填)"
class="form-textarea"
></textarea>
</view>
<!-- 上传图片 -->
<view class="form-item">
<text class="form-label">上传图片</text>
<view class="image-grid">
<view
v-for="(image, index) in acceptanceForm.images"
:key="index"
class="image-item"
>
<image :src="image" mode="aspectFill" @tap="previewImage(index)"></image>
<view class="delete-icon" @tap.stop="deleteImage(index)">
<UniIcons type="close" size="20" color="#fff"></UniIcons>
</view>
</view>
<view class="image-upload" @tap="chooseImage" v-if="acceptanceForm.images.length < 9">
<UniIcons type="camera" size="30" color="#999"></UniIcons>
</view>
</view>
</view>
<!-- 提交按钮 -->
<view class="form-buttons">
<button
type="warn"
:disabled="submitting"
@tap="submitAcceptance('failed')"
>验收不通过</button>
<button
type="primary"
:disabled="submitting"
@tap="submitAcceptance('passed')"
>验收通过</button>
</view>
</view>
</block>
<!-- 图片预览 -->
<uni-popup ref="imagePreview" type="center" :show="showImagePreview" @change="(e) => showImagePreview = e.show">
<view class="image-preview">
<image
:src="acceptanceForm.images[currentImageIndex] || ''"
mode="widthFix"
class="preview-image"
></image>
<view class="close-preview" @tap="showImagePreview = false">
<UniIcons type="close" size="24" color="#fff"></UniIcons>
</view>
</view>
</uni-popup>
</view>
</template>
<style lang="scss">
.container {
padding: 20rpx;
min-height: 100vh;
box-sizing: border-box;
background-color: #f5f5f5;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}
.section {
margin-bottom: 30rpx;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.status-passed {
color: #3cc51f;
font-weight: bold;
}
.status-failed {
color: #ff3b30;
font-weight: bold;
}
.status-pending {
color: #ff9500;
font-weight: bold;
}
}
}
.info-row {
display: flex;
margin-bottom: 20rpx;
.info-label {
width: 160rpx;
color: #666;
font-size: 28rpx;
}
.info-value {
flex: 1;
color: #333;
font-size: 28rpx;
}
}
.form-item {
margin-bottom: 30rpx;
.form-label {
display: block;
margin-bottom: 16rpx;
font-size: 28rpx;
color: #333;
}
.form-input {
width: 100%;
height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
box-sizing: border-box;
font-size: 28rpx;
}
.form-textarea {
width: 100%;
height: 200rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 20rpx;
box-sizing: border-box;
font-size: 28rpx;
}
.picker-view {
display: flex;
justify-content: space-between;
align-items: center;
height: 80rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
box-sizing: border-box;
}
}
.image-section {
margin-top: 30rpx;
.image-title {
display: block;
margin-bottom: 20rpx;
font-size: 28rpx;
color: #333;
}
}
.image-grid {
display: flex;
flex-wrap: wrap;
.image-item {
width: 200rpx;
height: 200rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
position: relative;
image {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.delete-icon {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
.image-upload {
width: 200rpx;
height: 200rpx;
border: 1rpx dashed #ddd;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.form-buttons {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
button {
width: 48%;
}
}
.loading-state, .error-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
text {
margin-bottom: 20rpx;
}
}
.image-preview {
width: 600rpx;
height: 600rpx;
background-color: #000;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.preview-image {
max-width: 100%;
max-height: 100%;
}
.close-preview {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 60rpx;
height: 60rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

View File

@@ -1,23 +1,83 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { useOrderStore } from '@/stores/order';
import { fetchAcceptanceList } from '@/api/acceptance';
import uniIcons from '@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue';
import type { IAcceptance, AcceptanceStatus } from '@/types/acceptance';
const UniIcons = uniIcons;
const orderStore = useOrderStore();
const acceptanceList = ref<any[]>([]);
const acceptanceList = ref<IAcceptance[]>([]);
const loading = ref(false);
const refreshing = ref(false);
const error = ref('');
const statusFilter = ref<AcceptanceStatus | 'all'>('all');
// 状态选项
const statusOptions = [
{ value: 'all', label: '全部' },
{ value: 'pending', label: '待验收' },
{ value: 'passed', label: '已通过' },
{ value: 'failed', label: '未通过' }
];
// 获取验收列表
const getAcceptanceList = async () => {
try {
loading.value = true;
acceptanceList.value = await fetchAcceptanceList();
const result = await fetchAcceptanceList();
acceptanceList.value = result;
} catch (err) {
error.value = '获取验收列表失败';
console.error('获取验收列表失败:', err);
} finally {
loading.value = false;
refreshing.value = false;
}
};
// 过滤后的验收列表
const filteredAcceptanceList = computed(() => {
if (statusFilter.value === 'all') {
return acceptanceList.value;
}
return acceptanceList.value.filter(item => item.status === statusFilter.value);
});
// 下拉刷新
const onRefresh = () => {
refreshing.value = true;
getAcceptanceList();
};
// 跳转到验收详情
const navigateToDetail = (id: string) => {
uni.navigateTo({
url: `/pages/acceptance/acceptance-detail?id=${id}`
});
};
// 获取状态标签样式
const getStatusClass = (status: AcceptanceStatus): string => {
switch (status) {
case 'passed':
return 'status-passed';
case 'failed':
return 'status-failed';
default:
return 'status-pending';
}
};
// 获取状态文本
const getStatusText = (status: AcceptanceStatus): string => {
switch (status) {
case 'passed':
return '验收通过';
case 'failed':
return '验收未通过';
default:
return '待验收';
}
};
@@ -28,43 +88,216 @@ onMounted(() => {
<template>
<view class="container">
<!-- 验收列表 -->
<view v-for="item in acceptanceList" :key="item.id" class="card">
<view class="flex-between">
<text class="text-bold">订单号: {{ item.orderId }}</text>
<text :class="item.status === 'passed' ? 'text-primary' : 'text-danger'">
{{ item.status === 'passed' ? '验收通过' : '验收未通过' }}
</text>
</view>
<view class="divider"></view>
<text>验收时间: {{ item.acceptanceTime }}</text>
<view class="margin-top-sm">
<text>验收结果: {{ item.result }}</text>
</view>
<!-- 筛选栏 -->
<view class="filter-bar">
<picker
mode="selector"
:range="statusOptions"
range-key="label"
@change="(e) => statusFilter = statusOptions[e.detail.value].value"
>
<view class="filter-item">
<text>{{ statusOptions.find(opt => opt.value === statusFilter)?.label }}</text>
<UniIcons type="arrowdown" size="16" color="#666"></UniIcons>
</view>
</picker>
</view>
<!-- 加载状态 -->
<view class="flex-center" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误信息 -->
<view class="flex-center" v-if="error">
<text class="text-danger">{{ error }}</text>
</view>
<!-- 验收列表 -->
<scroll-view
scroll-y
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
class="acceptance-list"
>
<!-- 空状态 -->
<view v-if="!loading && filteredAcceptanceList.length === 0" class="empty-state">
<image src="/static/images/empty-acceptance.png" mode="aspectFit"></image>
<text>暂无验收记录</text>
</view>
<!-- 验收列表 -->
<view
v-for="item in filteredAcceptanceList"
:key="item.id"
class="acceptance-card"
@tap="navigateToDetail(item.id)"
>
<view class="acceptance-header">
<text class="order-no">订单号: {{ item.orderId }}</text>
<text :class="getStatusClass(item.status)">
{{ getStatusText(item.status) }}
</text>
</view>
<view class="acceptance-info">
<view class="info-row">
<UniIcons type="calendar" size="18" color="#666"></UniIcons>
<text class="info-label">验收时间:</text>
<text class="info-value">{{ item.acceptanceTime || '未验收' }}</text>
</view>
<view class="info-row" v-if="item.acceptor">
<UniIcons type="person" size="18" color="#666"></UniIcons>
<text class="info-label">验收人:</text>
<text class="info-value">{{ item.acceptor }}</text>
</view>
<view class="info-row">
<UniIcons type="info" size="18" color="#666"></UniIcons>
<text class="info-label">验收结果:</text>
<text class="info-value">{{ item.result || '暂无结果' }}</text>
</view>
</view>
<view class="acceptance-footer">
<view class="action-buttons" v-if="item.status === 'pending'">
<button type="primary" size="mini" class="action-button">
开始验收
</button>
</view>
<view class="action-buttons" v-else>
<button type="default" size="mini" class="action-button">
查看详情
</button>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="loading-state" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误信息 -->
<view class="error-state" v-if="error">
<text class="text-danger">{{ error }}</text>
</view>
</scroll-view>
</view>
</template>
<style lang="scss">
.container {
padding: 20rpx;
height: 100vh;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.card {
.filter-bar {
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.filter-item {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.acceptance-list {
flex: 1;
}
.acceptance-card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.acceptance-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
.order-no {
font-size: 28rpx;
font-weight: bold;
}
.status-passed {
color: #3cc51f;
}
.status-failed {
color: #ff3b30;
}
.status-pending {
color: #ff9500;
}
}
.acceptance-info {
padding: 20rpx 0;
.info-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.info-label {
margin: 0 10rpx;
color: #666;
width: 120rpx;
}
.info-value {
flex: 1;
color: #333;
}
}
}
.acceptance-footer {
padding-top: 20rpx;
border-top: 1rpx solid #eee;
.action-buttons {
display: flex;
justify-content: flex-end;
.action-button {
margin-left: 20rpx;
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
text {
color: #999;
}
}
.loading-state, .error-state {
display: flex;
justify-content: center;
padding: 20rpx;
text {
color: #999;
}
}
</style>

View File

@@ -3,6 +3,9 @@ import { ref, computed, onMounted } from 'vue';
import { useOrderStore } from '@/stores/order';
import { useSupplierStore } from '@/stores/supplier';
import type { IOrderCreateForm, ICattleBreed } from './types';
import uniIcons from '@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue';
const UniIcons = uniIcons;
const orderStore = useOrderStore();
const supplierStore = useSupplierStore();
@@ -98,7 +101,7 @@ onMounted(() => {
{{ supplierStore.suppliers.find(s => s.id === form.supplierId)?.name || '请选择供应商' }}
</text>
<text v-else class="placeholder">请选择供应商</text>
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
<UniIcons type="arrowright" size="16" color="#999"></UniIcons>
</view>
</picker>
</view>
@@ -120,7 +123,7 @@ onMounted(() => {
{{ form.cattleBreed }} (¥{{ form.price }}/kg)
</text>
<text v-else class="placeholder">请选择牛只品种</text>
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
<UniIcons type="arrowright" size="16" color="#999"></UniIcons>
</view>
</picker>
</view>

View File

@@ -1,22 +1,43 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, onUnmounted } from 'vue';
import { useOrderStore } from '@/stores/order';
import {
fetchTrackingDetail,
updateTrackingStatus,
subscribeTracking
subscribeTracking,
getTrackingHistory
} from '@/api/tracking';
const orderStore = useOrderStore();
const trackingDetail = ref<any>(null);
const trackingHistory = ref<any[]>([]);
const loading = ref(false);
const error = ref('');
const mapContext = ref<any>(null);
const markers = ref<any[]>([]);
const polyline = ref<any[]>([]);
const refreshInterval = ref<number | null>(null);
// 获取运输详情
const getTrackingDetail = async (trackingId: string) => {
try {
loading.value = true;
trackingDetail.value = await fetchTrackingDetail(trackingId);
const [detail, history] = await Promise.all([
fetchTrackingDetail(trackingId),
getTrackingHistory(trackingId)
]);
trackingDetail.value = detail;
trackingHistory.value = history;
// 设置地图标记点和路线
setupMapData();
// 订阅实时位置更新
subscribeTracking(trackingId);
// 设置定时刷新
setupRefreshInterval(trackingId);
} catch (err) {
error.value = '获取运输详情失败';
console.error('获取运输详情失败:', err);
@@ -25,12 +46,107 @@ const getTrackingDetail = async (trackingId: string) => {
}
};
// 设置地图数据
const setupMapData = () => {
if (!trackingDetail.value || !trackingHistory.value) return;
// 设置当前位置标记
markers.value = [{
id: 1,
latitude: trackingDetail.value.currentLatitude,
longitude: trackingDetail.value.currentLongitude,
title: '当前位置',
iconPath: '/static/images/truck.png',
width: 30,
height: 30
}, {
id: 2,
latitude: trackingDetail.value.destinationLatitude,
longitude: trackingDetail.value.destinationLongitude,
title: '目的地',
iconPath: '/static/images/destination.png',
width: 30,
height: 30
}];
// 设置路线
const points = trackingHistory.value.map(point => ({
latitude: point.latitude,
longitude: point.longitude
}));
polyline.value = [{
points,
color: '#1989FA',
width: 4,
arrowLine: true
}];
// 更新地图视野
updateMapView();
};
// 更新地图视野
const updateMapView = () => {
if (!mapContext.value) {
mapContext.value = uni.createMapContext('trackingMap');
}
// 确保地图包含所有标记点
mapContext.value.includePoints({
points: markers.value.map(marker => ({
latitude: marker.latitude,
longitude: marker.longitude
})),
padding: [50, 50, 50, 50]
});
};
// 设置定时刷新
const setupRefreshInterval = (trackingId: string) => {
// 每30秒刷新一次位置
refreshInterval.value = setInterval(() => {
getTrackingDetail(trackingId);
}, 30000) as unknown as number;
};
// 拨打司机电话
const callDriver = () => {
if (!trackingDetail.value?.driverPhone) return;
uni.makePhoneCall({
phoneNumber: trackingDetail.value.driverPhone,
fail: (err) => {
console.error('拨打电话失败:', err);
}
});
};
onMounted(() => {
const trackingId = ''; // 从路由参数获取
// 从路由参数获取跟踪ID
const eventChannel = getOpenerEventChannel();
eventChannel.on('trackingId', (data: { id: string }) => {
if (data.id) {
getTrackingDetail(data.id);
}
});
// 或者从URL参数获取
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const trackingId = currentPage.$page?.options?.id;
if (trackingId) {
getTrackingDetail(trackingId);
}
});
onUnmounted(() => {
// 清除定时器
if (refreshInterval.value) {
clearInterval(refreshInterval.value);
}
});
</script>
<template>
@@ -71,7 +187,48 @@ onMounted(() => {
<!-- 地图容器 -->
<view class="map-container margin-top">
<text>地图显示区域</text>
<map
id="trackingMap"
class="map"
:latitude="trackingDetail.currentLatitude"
:longitude="trackingDetail.currentLongitude"
:markers="markers"
:polyline="polyline"
show-location
enable-rotate
enable-traffic
></map>
</view>
<!-- 联系司机 -->
<view class="action-buttons margin-top">
<button
type="primary"
@tap="callDriver"
:disabled="!trackingDetail.driverPhone"
>
联系司机
</button>
</view>
<!-- 运输历史记录 -->
<view class="history-container margin-top">
<view class="section-title">运输记录</view>
<view class="timeline">
<view
v-for="(record, index) in trackingHistory"
:key="index"
class="timeline-item"
>
<view class="timeline-dot" :class="{ 'active': index === 0 }"></view>
<view class="timeline-content">
<view class="timeline-time">{{ record.timestamp }}</view>
<view class="timeline-title">{{ record.status }}</view>
<view class="timeline-desc">{{ record.location }}</view>
<view v-if="record.remark" class="timeline-remark">{{ record.remark }}</view>
</view>
</view>
</view>
</view>
</view>
@@ -100,12 +257,89 @@ onMounted(() => {
}
.map-container {
height: 300rpx;
background-color: #f5f5f5;
height: 500rpx;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
margin-top: 20rpx;
.map {
width: 100%;
height: 100%;
}
}
.action-buttons {
display: flex;
justify-content: space-around;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.timeline {
position: relative;
&::before {
content: '';
position: absolute;
left: 16rpx;
top: 0;
width: 2rpx;
height: 100%;
background-color: #eee;
}
.timeline-item {
position: relative;
padding-left: 60rpx;
margin-bottom: 30rpx;
.timeline-dot {
position: absolute;
left: 10rpx;
top: 10rpx;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background-color: #999;
&.active {
background-color: #3cc51f;
box-shadow: 0 0 0 4rpx rgba(60, 197, 31, 0.2);
}
}
.timeline-content {
padding: 20rpx;
background-color: #f8f8f8;
border-radius: 8rpx;
.timeline-time {
font-size: 24rpx;
color: #999;
}
.timeline-title {
font-size: 28rpx;
font-weight: bold;
margin: 10rpx 0;
}
.timeline-desc {
font-size: 26rpx;
color: #666;
}
.timeline-remark {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
font-style: italic;
}
}
}
}
</style>

View File

@@ -1,26 +1,92 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import { useOrderStore } from '@/stores/order';
import { fetchTrackingList } from '@/api/tracking';
import uniIcons from '@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue';
// 定义运输跟踪项的类型
interface TrackingItem {
id: string;
orderNo: string;
status: 'in_transit' | 'completed';
driverName: string;
driverPhone: string;
currentLocation: string;
estimatedArrival: string;
remainingDistance: number;
progressPercentage: number;
}
const UniIcons = uniIcons;
const orderStore = useOrderStore();
const trackingList = ref<any[]>([]);
const trackingList = ref<TrackingItem[]>([]);
const loading = ref(false);
const refreshing = ref(false);
const error = ref('');
const statusFilter = ref<string>('all');
// 状态选项
const statusOptions = [
{ value: 'all', label: '全部' },
{ value: 'in_transit', label: '运输中' },
{ value: 'completed', label: '已完成' }
];
// 获取运输跟踪列表
const getTrackingList = async () => {
try {
loading.value = true;
trackingList.value = await fetchTrackingList();
const params = statusFilter.value === 'all' ? {} : { status: statusFilter.value };
const result = await fetchTrackingList(params);
trackingList.value = result.data as TrackingItem[] || [];
} catch (err) {
error.value = '获取运输跟踪列表失败';
console.error('获取运输跟踪列表失败:', err);
} finally {
loading.value = false;
refreshing.value = false;
}
};
// 下拉刷新
const onRefresh = () => {
refreshing.value = true;
getTrackingList();
};
// 跳转到详情页
const navigateToDetail = (id: string) => {
uni.navigateTo({
url: `/pages/tracking/tracking-detail?id=${id}`,
success: (res) => {
// 传递参数
res.eventChannel.emit('trackingId', { id });
}
});
};
// 计算剩余时间
const calculateRemainingTime = (estimatedArrival: string) => {
const arrivalTime = new Date(estimatedArrival).getTime();
const now = Date.now();
const diff = arrivalTime - now;
if (diff <= 0) return '已到达';
const hours = Math.floor(diff / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
return `${hours}小时${minutes}分钟`;
};
// 格式化距离
const formatDistance = (distance: number) => {
if (distance >= 1000) {
return `${(distance / 1000).toFixed(1)}km`;
}
return `${distance}m`;
};
onMounted(() => {
getTrackingList();
});
@@ -28,46 +94,247 @@ onMounted(() => {
<template>
<view class="container">
<!-- 运输跟踪列表 -->
<view v-for="item in trackingList" :key="item.id" class="card">
<view class="flex-between">
<text class="text-bold">订单号: {{ item.orderId }}</text>
<text :class="item.status === 'completed' ? 'text-primary' : 'text-warning'">
{{ item.status === 'completed' ? '已完成' : '运输中' }}
</text>
</view>
<view class="divider"></view>
<text>司机: {{ item.driverName }}</text>
<view class="margin-top-sm">
<text>当前位置: {{ item.currentLocation }}</text>
</view>
<view class="margin-top-sm">
<text>预计到达: {{ item.estimatedArrival }}</text>
</view>
<!-- 筛选栏 -->
<view class="filter-bar">
<picker
mode="selector"
:range="statusOptions"
range-key="label"
@change="(e) => {
statusFilter = statusOptions[e.detail.value].value;
getTrackingList();
}"
>
<view class="filter-item">
<text>{{ statusOptions.find(opt => opt.value === statusFilter)?.label }}</text>
<UniIcons type="arrowdown" size="16" color="#666"></UniIcons>
</view>
</picker>
</view>
<!-- 加载状态 -->
<view class="flex-center" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误信息 -->
<view class="flex-center" v-if="error">
<text class="text-danger">{{ error }}</text>
</view>
<!-- 运输跟踪列表 -->
<scroll-view
scroll-y
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
class="tracking-list"
>
<!-- 空状态 -->
<view v-if="!loading && trackingList.length === 0" class="empty-state">
<image src="/static/images/empty-tracking.png" mode="aspectFit"></image>
<text>暂无运输记录</text>
</view>
<!-- 运输跟踪列表 -->
<view
v-for="item in trackingList"
:key="item.id"
class="tracking-card"
@tap="navigateToDetail(item.id)"
>
<view class="tracking-header">
<text class="order-no">订单号: {{ item.orderNo }}</text>
<text :class="item.status === 'completed' ? 'status-completed' : 'status-transit'">
{{ item.status === 'completed' ? '已完成' : '运输中' }}
</text>
</view>
<view class="tracking-info">
<view class="info-row">
<UniIcons type="car" size="18" color="#666"></UniIcons>
<text class="info-label">司机:</text>
<text class="info-value">{{ item.driverName }}</text>
</view>
<view class="info-row">
<UniIcons type="location" size="18" color="#666"></UniIcons>
<text class="info-label">当前位置:</text>
<text class="info-value">{{ item.currentLocation }}</text>
</view>
<view class="info-row">
<UniIcons type="clock" size="18" color="#666"></UniIcons>
<text class="info-label">预计到达:</text>
<text class="info-value">{{ item.estimatedArrival }}</text>
</view>
<view class="info-row" v-if="item.status !== 'completed'">
<UniIcons type="countdown" size="18" color="#666"></UniIcons>
<text class="info-label">剩余时间:</text>
<text class="info-value highlight">{{ calculateRemainingTime(item.estimatedArrival) }}</text>
</view>
<view class="info-row" v-if="item.status !== 'completed'">
<UniIcons type="forward" size="18" color="#666"></UniIcons>
<text class="info-label">剩余距离:</text>
<text class="info-value highlight">{{ formatDistance(item.remainingDistance) }}</text>
</view>
</view>
<view class="tracking-footer">
<view class="progress-container">
<view class="progress-bar">
<view
class="progress-fill"
:style="{ width: `${item.progressPercentage}%` }"
></view>
</view>
<text class="progress-text">{{ item.progressPercentage }}%</text>
</view>
</view>
</view>
<!-- 加载状态 -->
<view class="loading-state" v-if="loading">
<text>加载中...</text>
</view>
<!-- 错误信息 -->
<view class="error-state" v-if="error">
<text class="text-danger">{{ error }}</text>
</view>
</scroll-view>
</view>
</template>
<style lang="scss">
.container {
padding: 20rpx;
height: 100vh;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.card {
.filter-bar {
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.filter-item {
display: flex;
align-items: center;
justify-content: space-between;
}
}
.tracking-list {
flex: 1;
}
.tracking-card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
.tracking-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
.order-no {
font-size: 28rpx;
font-weight: bold;
}
.status-completed {
color: #3cc51f;
}
.status-transit {
color: #1989fa;
}
}
.tracking-info {
padding: 20rpx 0;
.info-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.info-label {
margin: 0 10rpx;
color: #666;
width: 120rpx;
}
.info-value {
flex: 1;
color: #333;
&.highlight {
color: #1989fa;
font-weight: bold;
}
}
}
}
.tracking-footer {
padding-top: 20rpx;
border-top: 1rpx solid #eee;
.progress-container {
display: flex;
align-items: center;
.progress-bar {
flex: 1;
height: 10rpx;
background-color: #eee;
border-radius: 10rpx;
overflow: hidden;
margin-right: 20rpx;
.progress-fill {
height: 100%;
background-color: #1989fa;
border-radius: 10rpx;
}
}
.progress-text {
font-size: 24rpx;
color: #666;
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
text {
color: #999;
}
}
.loading-state, .error-state {
display: flex;
justify-content: center;
padding: 20rpx;
text {
color: #999;
}
}
</style>

View File

@@ -14,14 +14,30 @@ export interface IAcceptance {
// 验收详情
export interface IAcceptanceDetail extends IAcceptance {
images: string[];
note?: string;
notes?: string;
cattleCount: number;
qualifiedCount: number;
unqualifiedReason?: string;
weightDifference?: number;
weight?: number;
healthStatus?: 'healthy' | 'minor_issues' | 'major_issues';
supplierName?: string;
cattleBreed?: string;
quantity?: number;
temperatureRecords?: {
cattleId: string;
temperature: number;
status: 'normal' | 'abnormal';
}[];
}
// 更新验收数据
export interface IAcceptanceUpdateData {
status: AcceptanceStatus;
result: string;
notes?: string;
weight?: number;
healthStatus?: 'healthy' | 'minor_issues' | 'major_issues';
images?: string[];
acceptanceTime?: string;
}

View File

@@ -1 +0,0 @@
{"version":3,"file":"acceptance.js","sources":["api/acceptance.ts"],"sourcesContent":["import { request } from '@/utils/request';\nimport type { IAcceptance, IAcceptanceDetail } from '@/types/acceptance';\n\n// 获取验收列表\nexport const fetchAcceptanceList = async (): Promise<IAcceptance[]> => {\n try {\n const res = await request({\n url: '/acceptance/list',\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取验收列表失败:', error);\n throw error;\n }\n};\n\n// 获取验收详情\nexport const fetchAcceptanceDetail = async (acceptanceId: string): Promise<IAcceptanceDetail> => {\n try {\n const res = await request({\n url: `/acceptance/${acceptanceId}/detail`,\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取验收详情失败:', error);\n throw error;\n }\n};\n\n// 提交验收结果\nexport const submitAcceptance = async (data: {\n orderId: string;\n result: 'passed' | 'failed';\n images: string[];\n note?: string;\n}): Promise<IAcceptanceDetail> => {\n try {\n const res = await request({\n url: '/acceptance/submit',\n method: 'POST',\n data\n });\n return res.data;\n } catch (error) {\n console.error('提交验收结果失败:', error);\n throw error;\n }\n};"],"names":["request","uni"],"mappings":";;;AAIO,MAAM,sBAAsB,YAAoC;AACjE,MAAA;AACI,UAAA,MAAM,MAAMA,sBAAQ;AAAA,MACxB,KAAK;AAAA,MACL,QAAQ;AAAA,IAAA,CACT;AACD,WAAO,IAAI;AAAA,WACJ,OAAO;AACdC,kBAAA,MAAA,MAAA,SAAA,2BAAc,aAAa,KAAK;AAC1B,UAAA;AAAA,EACR;AACF;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"auth.js","sources":["api/auth.ts"],"sourcesContent":["import { request } from '@/utils/request';\ninterface ILoginForm {\n username: string;\n password: string;\n}\n\ninterface IRegisterForm {\n username: string;\n password: string;\n phone: string;\n captcha: string;\n role: 'client' | 'supplier' | 'driver' | 'staff';\n}\n\n// 用户登录\nexport const login = async (data: ILoginForm) => {\n return request({\n url: '/auth/login',\n method: 'POST',\n data\n });\n};\n\n// 用户注册\nexport const register = async (data: IRegisterForm) => {\n return request({\n url: '/auth/register',\n method: 'POST',\n data\n });\n};\n\n// 获取验证码\nexport const getCaptcha = async (phone: string) => {\n return request({\n url: '/auth/captcha',\n method: 'GET',\n data: { phone }\n });\n};\n\n// 验证验证码\nexport const verifyCaptcha = async (phone: string, code: string) => {\n return request({\n url: '/auth/verify-captcha',\n method: 'POST',\n data: { phone, code }\n });\n};"],"names":["request"],"mappings":";;AAea,MAAA,QAAQ,OAAO,SAAqB;AAC/C,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AACH;AAGa,MAAA,WAAW,OAAO,SAAwB;AACrD,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AACH;AAGa,MAAA,aAAa,OAAO,UAAkB;AACjD,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM,EAAE,MAAM;AAAA,EAAA,CACf;AACH;;;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"payment.js","sources":["api/payment.ts"],"sourcesContent":["import { request } from '@/utils/request';\nimport type { IPayment, IPaymentDetail } from '@/types/payment';\n\n// 获取支付列表\nexport const fetchPaymentList = async (): Promise<IPayment[]> => {\n try {\n const res = await request({\n url: '/payment/list',\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取支付列表失败:', error);\n throw error;\n }\n};\n\n// 获取支付详情\nexport const fetchPaymentDetail = async (paymentId: string): Promise<IPaymentDetail> => {\n try {\n const res = await request({\n url: `/payment/${paymentId}/detail`,\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取支付详情失败:', error);\n throw error;\n }\n};\n\n// 发起支付\nexport const createPayment = async (orderId: string, amount: number, method: string): Promise<{\n paymentId: string;\n paymentParams: any;\n}> => {\n try {\n const res = await request({\n url: '/payment/create',\n method: 'POST',\n data: { orderId, amount, method }\n });\n return res.data;\n } catch (error) {\n console.error('创建支付失败:', error);\n throw error;\n }\n};\n\n// 查询支付状态\nexport const checkPaymentStatus = async (paymentId: string): Promise<{\n status: 'pending' | 'paid' | 'failed';\n paidTime?: string;\n}> => {\n try {\n const res = await request({\n url: `/payment/${paymentId}/status`,\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('查询支付状态失败:', error);\n throw error;\n }\n};"],"names":["request","uni"],"mappings":";;;AAIO,MAAM,mBAAmB,YAAiC;AAC3D,MAAA;AACI,UAAA,MAAM,MAAMA,sBAAQ;AAAA,MACxB,KAAK;AAAA,MACL,QAAQ;AAAA,IAAA,CACT;AACD,WAAO,IAAI;AAAA,WACJ,OAAO;AACdC,kBAAA,MAAA,MAAA,SAAA,wBAAc,aAAa,KAAK;AAC1B,UAAA;AAAA,EACR;AACF;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"statistics.js","sources":["api/statistics.ts"],"sourcesContent":["import { request } from '@/utils/request';\n\n// 获取采购统计数据\nexport const getPurchaseStats = async (params: { \n startDate?: string;\n endDate?: string;\n}) => {\n return request({\n url: '/stats/purchase',\n method: 'GET',\n data: params\n });\n};\n\n// 获取运输统计数据\nexport const getTransportStats = async () => {\n return request({\n url: '/stats/transport',\n method: 'GET'\n });\n};\n\n// 获取财务统计数据\nexport const getFinancialStats = async () => {\n return request({\n url: '/stats/financial',\n method: 'GET'\n });\n};"],"names":["request"],"mappings":";;AAGa,MAAA,mBAAmB,OAAO,WAGjC;AACJ,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,EAAA,CACP;AACH;AAGO,MAAM,oBAAoB,YAAY;AAC3C,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,EAAA,CACT;AACH;AAGO,MAAM,oBAAoB,YAAY;AAC3C,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,EAAA,CACT;AACH;;;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"tracking.js","sources":["api/tracking.ts"],"sourcesContent":["import { request } from '@/utils/request';\n\n// 获取运输跟踪列表\nexport const fetchTrackingList = (params?: {\n status?: string;\n page?: number;\n pageSize?: number;\n}) => {\n return request({\n url: '/api/tracking/list',\n method: 'GET',\n params\n });\n};\n\n// 获取运输跟踪详情\nexport const fetchTrackingDetail = (id: string) => {\n return request({\n url: `/api/tracking/${id}`,\n method: 'GET'\n });\n};\n\n// 更新运输状态\nexport const updateTrackingStatus = (data: {\n id: string;\n status: string;\n location?: string;\n remark?: string;\n}) => {\n return request({\n url: '/api/tracking/update',\n method: 'POST',\n data\n });\n};\n\n// 获取运输历史记录\nexport const getTrackingHistory = (id: string) => {\n return request({\n url: `/api/tracking/${id}/history`,\n method: 'GET'\n });\n};\n\n// 订阅实时位置更新\nexport const subscribeTracking = (id: string) => {\n return request({\n url: `/api/tracking/${id}/subscribe`,\n method: 'GET'\n });\n};"],"names":["request"],"mappings":";;AAGa,MAAA,oBAAoB,CAAC,WAI5B;AACJ,SAAOA,sBAAQ;AAAA,IACb,KAAK;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,EAAA,CACD;AACH;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"user.js","sources":["api/user.ts"],"sourcesContent":["import { request } from '@/utils/request';\nimport type { IUser, IUserSettings } from '@/types/user';\n\n// 更新用户设置\nexport const updateUserSettings = async (settings: Partial<IUserSettings>) => {\n try {\n const res = await request({\n url: '/user/settings',\n method: 'POST',\n data: settings\n });\n return res.data;\n } catch (error) {\n console.error('更新用户设置失败:', error);\n throw error;\n }\n};\n\n// 获取用户详细信息(包含个人资料)\nexport const fetchUserProfile = async (): Promise<IUser & { profile: any }> => {\n try {\n const res = await request({\n url: '/user/profile',\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取用户资料失败:', error);\n throw error;\n }\n};\n\n// 获取用户信息\nexport const fetchUserInfo = async (): Promise<IUser> => {\n try {\n const res = await request({\n url: '/user/info',\n method: 'GET'\n });\n return res.data;\n } catch (error) {\n console.error('获取用户信息失败:', error);\n throw error;\n }\n};"],"names":["request","uni"],"mappings":";;;AAIa,MAAA,qBAAqB,OAAO,aAAqC;AACxE,MAAA;AACI,UAAA,MAAM,MAAMA,sBAAQ;AAAA,MACxB,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,IAAA,CACP;AACD,WAAO,IAAI;AAAA,WACJ,OAAO;AACdC,kBAAA,MAAA,MAAA,SAAA,qBAAc,aAAa,KAAK;AAC1B,UAAA;AAAA,EACR;AACF;AAGO,MAAM,mBAAmB,YAA+C;AACzE,MAAA;AACI,UAAA,MAAM,MAAMD,sBAAQ;AAAA,MACxB,KAAK;AAAA,MACL,QAAQ;AAAA,IAAA,CACT;AACD,WAAO,IAAI;AAAA,WACJ,OAAO;AACdC,kBAAA,MAAA,MAAA,SAAA,qBAAc,aAAa,KAAK;AAC1B,UAAA;AAAA,EACR;AACF;;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.js","sources":["App.vue","main.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onLaunch, onShow, onHide } from '@dcloudio/uni-app';\nimport { useUserStore } from '@/stores/user';\n\nconst userStore = useUserStore();\n\nonLaunch(() => {\n uni.__f__('log','at App.vue:8','App Launch');\n // 初始化时检查登录状态\n userStore.checkLoginStatus();\n});\n\nonShow(() => {\n uni.__f__('log','at App.vue:14','App Show');\n});\n\nonHide(() => {\n uni.__f__('log','at App.vue:18','App Hide');\n});\n</script>\n\n<template>\n <view>\n <!-- 这里是所有页面的容器 -->\n <slot />\n </view>\n</template>\n\n<style>\n/* 全局样式 */\npage {\n font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica,\n Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n font-weight: 400;\n font-size: 14px;\n color: #333;\n background-color: #f8f8f8;\n}\n</style>","import { createSSRApp } from 'vue';\nimport App from './App.vue';\nimport { createPinia } from 'pinia';\nimport * as Pinia from 'pinia';\n\nexport function createApp() {\n const app = createSSRApp(App);\n const pinia = createPinia();\n \n // 配置Pinia\n pinia.use(({ store }) => {\n // 持久化存储\n const storageKey = `pinia_${store.$id}`;\n const savedState = uni.getStorageSync(storageKey);\n if (savedState) {\n store.$patch(JSON.parse(savedState));\n }\n \n store.$subscribe((mutation, state) => {\n uni.setStorageSync(storageKey, JSON.stringify(state));\n });\n });\n\n app.use(pinia);\n \n return {\n app,\n pinia\n };\n}"],"names":["useUserStore","onLaunch","uni","onShow","onHide","createSSRApp","App","createPinia"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAIA,UAAM,YAAYA,YAAAA;AAElBC,kBAAAA,SAAS,MAAM;AACTC,oBAAAA,MAAA,MAAM,OAAM,gBAAe,YAAY;AAE3C,gBAAU,iBAAiB;AAAA,IAAA,CAC5B;AAEDC,kBAAAA,OAAO,MAAM;AACPD,oBAAAA,MAAA,MAAM,OAAM,iBAAgB,UAAU;AAAA,IAAA,CAC3C;AAEDE,kBAAAA,OAAO,MAAM;AACPF,oBAAAA,MAAA,MAAM,OAAM,iBAAgB,UAAU;AAAA,IAAA,CAC3C;;;;;;ACbM,SAAS,YAAY;AACpB,QAAA,MAAMG,2BAAaC,SAAG;AAC5B,QAAM,QAAQC,cAAAA;AAGd,QAAM,IAAI,CAAC,EAAE,YAAY;AAEjB,UAAA,aAAa,SAAS,MAAM,GAAG;AAC/B,UAAA,aAAaL,cAAAA,MAAI,eAAe,UAAU;AAChD,QAAI,YAAY;AACd,YAAM,OAAO,KAAK,MAAM,UAAU,CAAC;AAAA,IACrC;AAEM,UAAA,WAAW,CAAC,UAAU,UAAU;AACpCA,oBAAA,MAAI,eAAe,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,IAAA,CACrD;AAAA,EAAA,CACF;AAED,MAAI,IAAI,KAAK;AAEN,SAAA;AAAA,IACL;AAAA,IACA;AAAA,EAAA;AAEJ;AACA,YAAY,IAAI,MAAM,MAAM;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"assets.js","sources":["../../../../../../../../static/images/empty-order.png"],"sourcesContent":["export default \"/static/images/empty-order.png\""],"names":[],"mappings":";AAAA,MAAe,aAAA;;"}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"uni-icons.js","sources":["node_modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue","/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/node_modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue?type=component"],"sourcesContent":["<template>\r\n\t<!-- #ifdef APP-NVUE -->\r\n\t<text :style=\"styleObj\" class=\"uni-icons\" @click=\"_onClick\">{{unicode}}</text>\r\n\t<!-- #endif -->\r\n\t<!-- #ifndef APP-NVUE -->\r\n\t<text :style=\"styleObj\" class=\"uni-icons\" :class=\"['uniui-'+type,customPrefix,customPrefix?type:'']\" @click=\"_onClick\">\r\n\t\t<slot></slot>\r\n\t</text>\r\n\t<!-- #endif -->\r\n</template>\r\n\r\n<script>\r\n\timport { fontData } from './uniicons_file_vue.js';\r\n\r\n\tconst getVal = (val) => {\r\n\t\tconst reg = /^[0-9]*$/g\r\n\t\treturn (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;\r\n\t}\r\n\r\n\t// #ifdef APP-NVUE\r\n\tvar domModule = weex.requireModule('dom');\r\n\timport iconUrl from './uniicons.ttf'\r\n\tdomModule.addRule('fontFace', {\r\n\t\t'fontFamily': \"uniicons\",\r\n\t\t'src': \"url('\" + iconUrl + \"')\"\r\n\t});\r\n\t// #endif\r\n\r\n\t/**\r\n\t * Icons 图标\r\n\t * @description 用于展示 icons 图标\r\n\t * @tutorial https://ext.dcloud.net.cn/plugin?id=28\r\n\t * @property {Number} size 图标大小\r\n\t * @property {String} type 图标图案,参考示例\r\n\t * @property {String} color 图标颜色\r\n\t * @property {String} customPrefix 自定义图标\r\n\t * @event {Function} click 点击 Icon 触发事件\r\n\t */\r\n\texport default {\r\n\t\tname: 'UniIcons',\r\n\t\temits: ['click'],\r\n\t\tprops: {\r\n\t\t\ttype: {\r\n\t\t\t\ttype: String,\r\n\t\t\t\tdefault: ''\r\n\t\t\t},\r\n\t\t\tcolor: {\r\n\t\t\t\ttype: String,\r\n\t\t\t\tdefault: '#333333'\r\n\t\t\t},\r\n\t\t\tsize: {\r\n\t\t\t\ttype: [Number, String],\r\n\t\t\t\tdefault: 16\r\n\t\t\t},\r\n\t\t\tcustomPrefix: {\r\n\t\t\t\ttype: String,\r\n\t\t\t\tdefault: ''\r\n\t\t\t},\r\n\t\t\tfontFamily: {\r\n\t\t\t\ttype: String,\r\n\t\t\t\tdefault: ''\r\n\t\t\t}\r\n\t\t},\r\n\t\tdata() {\r\n\t\t\treturn {\r\n\t\t\t\ticons: fontData\r\n\t\t\t}\r\n\t\t},\r\n\t\tcomputed: {\r\n\t\t\tunicode() {\r\n\t\t\t\tlet code = this.icons.find(v => v.font_class === this.type)\r\n\t\t\t\tif (code) {\r\n\t\t\t\t\treturn code.unicode\r\n\t\t\t\t}\r\n\t\t\t\treturn ''\r\n\t\t\t},\r\n\t\t\ticonSize() {\r\n\t\t\t\treturn getVal(this.size)\r\n\t\t\t},\r\n\t\t\tstyleObj() {\r\n\t\t\t\tif (this.fontFamily !== '') {\r\n\t\t\t\t\treturn `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`\r\n\t\t\t\t}\r\n\t\t\t\treturn `color: ${this.color}; font-size: ${this.iconSize};`\r\n\t\t\t}\r\n\t\t},\r\n\t\tmethods: {\r\n\t\t\t_onClick(e) {\r\n\t\t\t\tthis.$emit('click', e)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n\t/* #ifndef APP-NVUE */\r\n\t@import './uniicons.css';\r\n\r\n\t@font-face {\r\n\t\tfont-family: uniicons;\r\n\t\tsrc: url('./uniicons.ttf');\r\n\t}\r\n\r\n\t/* #endif */\r\n\t.uni-icons {\r\n\t\tfont-family: uniicons;\r\n\t\ttext-decoration: none;\r\n\t\ttext-align: center;\r\n\t}\r\n</style>","import Component from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/node_modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.vue'\nwx.createComponent(Component)"],"names":["fontData"],"mappings":";;AAcC,MAAM,SAAS,CAAC,QAAQ;AACvB,QAAM,MAAM;AACZ,SAAQ,OAAO,QAAQ,YAAY,IAAI,KAAK,GAAG,IAAK,MAAM,OAAO;AAClE;AAqBA,MAAK,YAAU;AAAA,EACd,MAAM;AAAA,EACN,OAAO,CAAC,OAAO;AAAA,EACf,OAAO;AAAA,IACN,MAAM;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACT;AAAA,IACD,OAAO;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IACT;AAAA,IACD,MAAM;AAAA,MACL,MAAM,CAAC,QAAQ,MAAM;AAAA,MACrB,SAAS;AAAA,IACT;AAAA,IACD,cAAc;AAAA,MACb,MAAM;AAAA,MACN,SAAS;AAAA,IACT;AAAA,IACD,YAAY;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,IACV;AAAA,EACA;AAAA,EACD,OAAO;AACN,WAAO;AAAA,MACN,OAAOA,cAAO;AAAA,IACf;AAAA,EACA;AAAA,EACD,UAAU;AAAA,IACT,UAAU;AACT,UAAI,OAAO,KAAK,MAAM,KAAK,OAAK,EAAE,eAAe,KAAK,IAAI;AAC1D,UAAI,MAAM;AACT,eAAO,KAAK;AAAA,MACb;AACA,aAAO;AAAA,IACP;AAAA,IACD,WAAW;AACV,aAAO,OAAO,KAAK,IAAI;AAAA,IACvB;AAAA,IACD,WAAW;AACV,UAAI,KAAK,eAAe,IAAI;AAC3B,eAAO,UAAU,KAAK,KAAK,gBAAgB,KAAK,QAAQ,kBAAkB,KAAK,UAAU;AAAA,MAC1F;AACA,aAAO,UAAU,KAAK,KAAK,gBAAgB,KAAK,QAAQ;AAAA,IACzD;AAAA,EACA;AAAA,EACD,SAAS;AAAA,IACR,SAAS,GAAG;AACX,WAAK,MAAM,SAAS,CAAC;AAAA,IACtB;AAAA,EACD;AACD;;;;;;;;;;;AC1FD,GAAG,gBAAgB,SAAS;","x_google_ignoreList":[0]}

View File

@@ -1 +0,0 @@
{"version":3,"file":"acceptance-detail.js","sources":["pages/acceptance/acceptance-detail.vue","pages/acceptance/acceptance-detail.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { fetchAcceptanceDetail } from '@/api/acceptance';\n\nconst orderStore = useOrderStore();\nconst acceptanceDetail = ref<any>(null);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取验收详情\nconst getAcceptanceDetail = async (acceptanceId: string) => {\n try {\n loading.value = true;\n acceptanceDetail.value = await fetchAcceptanceDetail(acceptanceId);\n } catch (err) {\n error.value = '获取验收详情失败';\n uni.__f__('error','at pages/acceptance/acceptance-detail.vue:18','获取验收详情失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n const acceptanceId = ''; // 从路由参数获取\n if (acceptanceId) {\n getAcceptanceDetail(acceptanceId);\n }\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 验收详情 -->\n <view v-if=\"acceptanceDetail\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ acceptanceDetail.orderId }}</text>\n <text :class=\"acceptanceDetail.status === 'passed' ? 'text-primary' : 'text-danger'\">\n {{ acceptanceDetail.status === 'passed' ? '验收通过' : '验收未通过' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n <text>验收时间: {{ acceptanceDetail.acceptanceTime }}</text>\n <view class=\"margin-top-sm\">\n <text>验收人: {{ acceptanceDetail.acceptor }}</text>\n </view>\n <view class=\"margin-top-sm\">\n <text>验收结果: {{ acceptanceDetail.result }}</text>\n </view>\n <view class=\"margin-top-sm\" v-if=\"acceptanceDetail.images\">\n <text>验收照片:</text>\n <!-- 图片展示 -->\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/acceptance/acceptance-detail.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","onMounted","MiniProgramPage"],"mappings":";;;;;;AAKmBA,+BAAc;AAC3B,UAAA,mBAAmBC,kBAAS,IAAI;AAChC,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAepBC,kBAAAA,UAAU,MAAM;AAAA,IAId,CACD;;;;;;;;;;;;;;;;;;;;;;AC3BD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"acceptance-list.js","sources":["pages/acceptance/acceptance-list.vue","pages/acceptance/acceptance-list.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { fetchAcceptanceList } from '@/api/acceptance';\n\nconst orderStore = useOrderStore();\nconst acceptanceList = ref<any[]>([]);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取验收列表\nconst getAcceptanceList = async () => {\n try {\n loading.value = true;\n acceptanceList.value = await fetchAcceptanceList();\n } catch (err) {\n error.value = '获取验收列表失败';\n uni.__f__('error','at pages/acceptance/acceptance-list.vue:18','获取验收列表失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n getAcceptanceList();\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 验收列表 -->\n <view v-for=\"item in acceptanceList\" :key=\"item.id\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ item.orderId }}</text>\n <text :class=\"item.status === 'passed' ? 'text-primary' : 'text-danger'\">\n {{ item.status === 'passed' ? '验收通过' : '验收未通过' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n <text>验收时间: {{ item.acceptanceTime }}</text>\n <view class=\"margin-top-sm\">\n <text>验收结果: {{ item.result }}</text>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/acceptance/acceptance-list.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","fetchAcceptanceList","uni","onMounted","MiniProgramPage"],"mappings":";;;;;;;AAKmBA,+BAAc;AAC3B,UAAA,iBAAiBC,kBAAW,CAAA,CAAE;AAC9B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,oBAAoB,YAAY;AAChC,UAAA;AACF,gBAAQ,QAAQ;AACD,uBAAA,QAAQ,MAAMC,eAAAA;eACtB,KAAK;AACZ,cAAM,QAAQ;AACdC,sBAAA,MAAI,MAAM,SAAQ,8CAA6C,aAAa,GAAG;AAAA,MAAA,UAC/E;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;AAGFC,kBAAAA,UAAU,MAAM;AACI;IAAA,CACnB;;;;;;;;;;;;;;;;;;;;;;ACxBD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"login.js","sources":["pages/auth/login.vue","pages/auth/login.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { useUserStore } from '@/stores/user';\nimport { login } from '@/api/auth';\n\nconst userStore = useUserStore();\nconst username = ref('');\nconst password = ref('');\nconst loading = ref(false);\nconst error = ref('');\n\n// 登录\nconst handleLogin = async () => {\n try {\n loading.value = true;\n error.value = '';\n const user = await login(username.value, password.value);\n userStore.setUser(user);\n uni.showToast({\n title: '登录成功',\n icon: 'success'\n });\n uni.switchTab({\n url: '/pages/index/index'\n });\n } catch (err) {\n error.value = '用户名或密码错误';\n uni.__f__('error','at pages/auth/login.vue:28','登录失败:', err);\n } finally {\n loading.value = false;\n }\n};\n</script>\n\n<template>\n <view class=\"container\">\n <view class=\"card\">\n <text class=\"text-bold\">登录</text>\n <view class=\"divider\"></view>\n \n <view class=\"margin-top\">\n <text>用户名</text>\n <input v-model=\"username\" placeholder=\"请输入用户名\" />\n </view>\n \n <view class=\"margin-top\">\n <text>密码</text>\n <input v-model=\"password\" placeholder=\"请输入密码\" type=\"password\" />\n </view>\n \n <button \n class=\"margin-top\" \n type=\"primary\" \n :loading=\"loading\"\n @click=\"handleLogin\"\n >\n 登录\n </button>\n \n <view class=\"margin-top text-center\">\n <text>还没有账号?</text>\n <text class=\"text-primary\" @click=\"uni.navigateTo({ url: '/pages/auth/register' })\">立即注册</text>\n </view>\n </view>\n \n <view v-if=\"error\" class=\"text-danger text-center margin-top\">\n {{ error }}\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\ninput {\n border: 1rpx solid #eee;\n border-radius: 8rpx;\n padding: 10rpx;\n margin-top: 10rpx;\n width: 100%;\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/auth/login.vue'\nwx.createPage(MiniProgramPage)"],"names":["useUserStore","ref","login","uni","MiniProgramPage"],"mappings":";;;;;;;AAKA,UAAM,YAAYA,YAAAA;AACZ,UAAA,WAAWC,kBAAI,EAAE;AACjB,UAAA,WAAWA,kBAAI,EAAE;AACjB,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,cAAc,YAAY;AAC1B,UAAA;AACF,gBAAQ,QAAQ;AAChB,cAAM,QAAQ;AACd,cAAM,OAAO,MAAMC,eAAM,SAAS,OAAO,SAAS,KAAK;AACvD,kBAAU,QAAQ,IAAI;AACtBC,sBAAAA,MAAI,UAAU;AAAA,UACZ,OAAO;AAAA,UACP,MAAM;AAAA,QAAA,CACP;AACDA,sBAAAA,MAAI,UAAU;AAAA,UACZ,KAAK;AAAA,QAAA,CACN;AAAA,eACM,KAAK;AACZ,cAAM,QAAQ;AACdA,sBAAA,MAAI,MAAM,SAAQ,8BAA6B,SAAS,GAAG;AAAA,MAAA,UAC3D;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;AC7BF,GAAG,WAAWC,SAAe;"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"payment-detail.js","sources":["pages/payment/payment-detail.vue","pages/payment/payment-detail.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { fetchPaymentDetail } from '@/api/payment';\n\nconst orderStore = useOrderStore();\nconst paymentDetail = ref<any>(null);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取支付详情\nconst getPaymentDetail = async (paymentId: string) => {\n try {\n loading.value = true;\n paymentDetail.value = await fetchPaymentDetail(paymentId);\n } catch (err) {\n error.value = '获取支付详情失败';\n uni.__f__('error','at pages/payment/payment-detail.vue:18','获取支付详情失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n const paymentId = ''; // 从路由参数获取\n if (paymentId) {\n getPaymentDetail(paymentId);\n }\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 支付详情 -->\n <view v-if=\"paymentDetail\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ paymentDetail.orderId }}</text>\n <text :class=\"paymentDetail.status === 'paid' ? 'text-primary' : 'text-warning'\">\n {{ paymentDetail.status === 'paid' ? '已支付' : '待支付' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n <text>金额: ¥{{ paymentDetail.amount }}</text>\n <view class=\"margin-top-sm\">\n <text>支付方式: {{ paymentDetail.paymentMethod }}</text>\n </view>\n <view class=\"margin-top-sm\" v-if=\"paymentDetail.status === 'paid'\">\n <text>支付时间: {{ paymentDetail.paidTime }}</text>\n </view>\n <view class=\"margin-top-sm\">\n <button type=\"primary\" v-if=\"paymentDetail.status === 'pending'\">立即支付</button>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/payment/payment-detail.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","onMounted","MiniProgramPage"],"mappings":";;;;;;AAKmBA,+BAAc;AAC3B,UAAA,gBAAgBC,kBAAS,IAAI;AAC7B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAepBC,kBAAAA,UAAU,MAAM;AAAA,IAId,CACD;;;;;;;;;;;;;;;;;;;;;;;;;AC3BD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"payment-list.js","sources":["pages/payment/payment-list.vue","pages/payment/payment-list.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { fetchPaymentList } from '@/api/payment';\n\nconst orderStore = useOrderStore();\nconst paymentList = ref<any[]>([]);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取支付列表\nconst getPaymentList = async () => {\n try {\n loading.value = true;\n paymentList.value = await fetchPaymentList();\n } catch (err) {\n error.value = '获取支付列表失败';\n uni.__f__('error','at pages/payment/payment-list.vue:18','获取支付列表失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n getPaymentList();\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 支付列表 -->\n <view v-for=\"item in paymentList\" :key=\"item.id\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ item.orderId }}</text>\n <text :class=\"item.status === 'paid' ? 'text-primary' : 'text-warning'\">\n {{ item.status === 'paid' ? '已支付' : '待支付' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n <text>金额: ¥{{ item.amount }}</text>\n <view class=\"margin-top-sm\">\n <text>支付方式: {{ item.paymentMethod }}</text>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/payment/payment-list.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","fetchPaymentList","uni","onMounted","MiniProgramPage"],"mappings":";;;;;;;AAKmBA,+BAAc;AAC3B,UAAA,cAAcC,kBAAW,CAAA,CAAE;AAC3B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,iBAAiB,YAAY;AAC7B,UAAA;AACF,gBAAQ,QAAQ;AACJ,oBAAA,QAAQ,MAAMC,YAAAA;eACnB,KAAK;AACZ,cAAM,QAAQ;AACdC,sBAAA,MAAI,MAAM,SAAQ,wCAAuC,aAAa,GAAG;AAAA,MAAA,UACzE;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;AAGFC,kBAAAA,UAAU,MAAM;AACC;IAAA,CAChB;;;;;;;;;;;;;;;;;;;;;;ACxBD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"statistics.js","sources":["pages/statistics/statistics.vue","pages/statistics/statistics.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { getPurchaseStats, getTransportStats, getFinancialStats } from '@/api/statistics';\n\nconst statistics = ref<any>(null);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取统计数据\nconst getStatistics = async () => {\n try {\n loading.value = true;\n const [purchase, transport, financial] = await Promise.all([\n getPurchaseStats(),\n getTransportStats(),\n getFinancialStats()\n ]);\n statistics.value = {\n ...purchase,\n ...transport,\n ...financial\n };\n } catch (err) {\n error.value = '获取统计数据失败';\n uni.__f__('error','at pages/statistics/statistics.vue:25','获取统计数据失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n getStatistics();\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 统计数据 -->\n <view v-if=\"statistics\" class=\"card\">\n <text class=\"text-bold\">采购统计</text>\n <view class=\"divider\"></view>\n <view class=\"flex-between margin-top-sm\">\n <text>总采购量: {{ statistics.totalPurchase }}头</text>\n <text>总金额: ¥{{ statistics.totalAmount }}</text>\n </view>\n <view class=\"flex-between margin-top-sm\">\n <text>平均价格: ¥{{ statistics.averagePrice }}/头</text>\n <text>平均重量: {{ statistics.averageWeight }}kg</text>\n </view>\n </view>\n\n <!-- 图表区域 -->\n <view class=\"card margin-top\">\n <text class=\"text-bold\">采购趋势</text>\n <view class=\"divider\"></view>\n <!-- 这里将集成图表组件 -->\n <view class=\"chart-placeholder\">\n <text>采购趋势图表</text>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\n.chart-placeholder {\n height: 300rpx;\n background-color: #f5f5f5;\n border-radius: 8rpx;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-top: 20rpx;\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/statistics/statistics.vue'\nwx.createPage(MiniProgramPage)"],"names":["ref","getPurchaseStats","getTransportStats","getFinancialStats","uni","onMounted","MiniProgramPage"],"mappings":";;;;;;AAIM,UAAA,aAAaA,kBAAS,IAAI;AAC1B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,gBAAgB,YAAY;AAC5B,UAAA;AACF,gBAAQ,QAAQ;AAChB,cAAM,CAAC,UAAU,WAAW,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,UACzDC,gCAAiB;AAAA,UACjBC,iCAAkB;AAAA,UAClBC,iCAAkB;AAAA,QAAA,CACnB;AACD,mBAAW,QAAQ;AAAA,UACjB,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,QAAA;AAAA,eAEE,KAAK;AACZ,cAAM,QAAQ;AACdC,sBAAA,MAAI,MAAM,SAAQ,yCAAwC,aAAa,GAAG;AAAA,MAAA,UAC1E;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;AAGFC,kBAAAA,UAAU,MAAM;AACA;IAAA,CACf;;;;;;;;;;;;;;;;;;;AC/BD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"tracking-detail.js","sources":["pages/tracking/tracking-detail.vue","pages/tracking/tracking-detail.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { \n fetchTrackingDetail,\n updateTrackingStatus,\n subscribeTracking\n} from '@/api/tracking';\n\nconst orderStore = useOrderStore();\nconst trackingDetail = ref<any>(null);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取运输详情\nconst getTrackingDetail = async (trackingId: string) => {\n try {\n loading.value = true;\n trackingDetail.value = await fetchTrackingDetail(trackingId);\n } catch (err) {\n error.value = '获取运输详情失败';\n uni.__f__('error','at pages/tracking/tracking-detail.vue:22','获取运输详情失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n const trackingId = ''; // 从路由参数获取\n if (trackingId) {\n getTrackingDetail(trackingId);\n }\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 运输详情 -->\n <view v-if=\"trackingDetail\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ trackingDetail.orderId }}</text>\n <text :class=\"trackingDetail.status === 'completed' ? 'text-primary' : 'text-warning'\">\n {{ trackingDetail.status === 'completed' ? '已完成' : '运输中' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n \n <view class=\"margin-top-sm\">\n <text>司机: {{ trackingDetail.driverName }}</text>\n </view>\n \n <view class=\"margin-top-sm\">\n <text>联系电话: {{ trackingDetail.driverPhone }}</text>\n </view>\n \n <view class=\"margin-top-sm\">\n <text>当前位置: {{ trackingDetail.currentLocation }}</text>\n </view>\n \n <view class=\"margin-top-sm\">\n <text>预计到达: {{ trackingDetail.estimatedArrival }}</text>\n </view>\n \n <view class=\"margin-top-sm\">\n <text>已行驶距离: {{ trackingDetail.distanceTraveled }}公里</text>\n </view>\n \n <view class=\"margin-top-sm\">\n <text>剩余距离: {{ trackingDetail.remainingDistance }}公里</text>\n </view>\n \n <!-- 地图容器 -->\n <view class=\"map-container margin-top\">\n <text>地图显示区域</text>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\n.map-container {\n height: 300rpx;\n background-color: #f5f5f5;\n border-radius: 8rpx;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-top: 20rpx;\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/tracking/tracking-detail.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","onMounted","MiniProgramPage"],"mappings":";;;;;;AASmBA,+BAAc;AAC3B,UAAA,iBAAiBC,kBAAS,IAAI;AAC9B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAepBC,kBAAAA,UAAU,MAAM;AAAA,IAId,CACD;;;;;;;;;;;;;;;;;;;;;;;;AC/BD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"tracking-list.js","sources":["pages/tracking/tracking-list.vue","pages/tracking/tracking-list.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useOrderStore } from '@/stores/order';\nimport { fetchTrackingList } from '@/api/tracking';\n\nconst orderStore = useOrderStore();\nconst trackingList = ref<any[]>([]);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取运输跟踪列表\nconst getTrackingList = async () => {\n try {\n loading.value = true;\n trackingList.value = await fetchTrackingList();\n } catch (err) {\n error.value = '获取运输跟踪列表失败';\n uni.__f__('error','at pages/tracking/tracking-list.vue:18','获取运输跟踪列表失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\nonMounted(() => {\n getTrackingList();\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 运输跟踪列表 -->\n <view v-for=\"item in trackingList\" :key=\"item.id\" class=\"card\">\n <view class=\"flex-between\">\n <text class=\"text-bold\">订单号: {{ item.orderId }}</text>\n <text :class=\"item.status === 'completed' ? 'text-primary' : 'text-warning'\">\n {{ item.status === 'completed' ? '已完成' : '运输中' }}\n </text>\n </view>\n <view class=\"divider\"></view>\n <text>司机: {{ item.driverName }}</text>\n <view class=\"margin-top-sm\">\n <text>当前位置: {{ item.currentLocation }}</text>\n </view>\n <view class=\"margin-top-sm\">\n <text>预计到达: {{ item.estimatedArrival }}</text>\n </view>\n </view>\n\n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n margin-bottom: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/tracking/tracking-list.vue'\nwx.createPage(MiniProgramPage)"],"names":["useOrderStore","ref","fetchTrackingList","uni","onMounted","MiniProgramPage"],"mappings":";;;;;;;AAKmBA,+BAAc;AAC3B,UAAA,eAAeC,kBAAW,CAAA,CAAE;AAC5B,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,kBAAkB,YAAY;AAC9B,UAAA;AACF,gBAAQ,QAAQ;AACH,qBAAA,QAAQ,MAAMC,aAAAA;eACpB,KAAK;AACZ,cAAM,QAAQ;AACdC,sBAAA,MAAI,MAAM,SAAQ,0CAAyC,eAAe,GAAG;AAAA,MAAA,UAC7E;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;AAGFC,kBAAAA,UAAU,MAAM;AACE;IAAA,CACjB;;;;;;;;;;;;;;;;;;;;;;;ACxBD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"profile.js","sources":["pages/user/profile.vue","pages/user/profile.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\nimport { useUserStore } from '@/stores/user';\nimport { fetchUserProfile } from '@/api/user';\n\nconst userStore = useUserStore();\nconst profile = ref<any>(null);\nconst loading = ref(false);\nconst error = ref('');\n\n// 获取用户信息\nconst getUserProfile = async () => {\n try {\n loading.value = true;\n profile.value = await fetchUserProfile();\n } catch (err) {\n error.value = '获取用户信息失败';\n uni.__f__('error','at pages/user/profile.vue:18','获取用户信息失败:', err);\n } finally {\n loading.value = false;\n }\n};\n\n// 退出登录\nconst handleLogout = () => {\n userStore.clearUser();\n uni.redirectTo({\n url: '/pages/auth/login'\n });\n};\n\nonMounted(() => {\n getUserProfile();\n});\n</script>\n\n<template>\n <view class=\"container\">\n <!-- 用户信息 -->\n <view class=\"card\" v-if=\"profile\">\n <view class=\"flex-center\">\n <image \n :src=\"profile.avatar || '/static/default-avatar.png'\" \n mode=\"aspectFill\"\n class=\"avatar\"\n />\n </view>\n \n <view class=\"divider\"></view>\n \n <view class=\"margin-top\">\n <text class=\"text-bold\">用户名: {{ profile.username }}</text>\n </view>\n \n <view class=\"margin-top\">\n <text>手机号: {{ profile.phone }}</text>\n </view>\n \n <view class=\"margin-top\">\n <text>注册时间: {{ profile.createdAt }}</text>\n </view>\n \n <button \n class=\"margin-top\" \n type=\"warn\" \n @click=\"handleLogout\"\n >\n 退出登录\n </button>\n </view>\n \n <!-- 加载状态 -->\n <view class=\"flex-center\" v-if=\"loading\">\n <text>加载中...</text>\n </view>\n \n <!-- 错误信息 -->\n <view class=\"flex-center\" v-if=\"error\">\n <text class=\"text-danger\">{{ error }}</text>\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\n.avatar {\n width: 150rpx;\n height: 150rpx;\n border-radius: 50%;\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/user/profile.vue'\nwx.createPage(MiniProgramPage)"],"names":["useUserStore","ref","fetchUserProfile","uni","onMounted","MiniProgramPage"],"mappings":";;;;;;;AAKA,UAAM,YAAYA,YAAAA;AACZ,UAAA,UAAUC,kBAAS,IAAI;AACvB,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,iBAAiB,YAAY;AAC7B,UAAA;AACF,gBAAQ,QAAQ;AACR,gBAAA,QAAQ,MAAMC,SAAAA;eACf,KAAK;AACZ,cAAM,QAAQ;AACdC,sBAAA,MAAI,MAAM,SAAQ,gCAA+B,aAAa,GAAG;AAAA,MAAA,UACjE;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;AAIF,UAAM,eAAe,MAAM;AACzB,gBAAU,UAAU;AACpBA,oBAAAA,MAAI,WAAW;AAAA,QACb,KAAK;AAAA,MAAA,CACN;AAAA,IAAA;AAGHC,kBAAAA,UAAU,MAAM;AACC;IAAA,CAChB;;;;;;;;;;;;;;;;;;;;AChCD,GAAG,WAAWC,SAAe;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"settings.js","sources":["pages/user/settings.vue","pages/user/settings.vue?type=page"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { useUserStore } from '@/stores/user';\nimport { updateUserSettings } from '@/api/user';\n\nconst userStore = useUserStore();\nconst settings = ref({\n notification: true,\n darkMode: false,\n language: 'zh-CN'\n});\nconst loading = ref(false);\nconst error = ref('');\n\n// 保存设置\nconst saveSettings = async () => {\n try {\n loading.value = true;\n await updateUserSettings(settings.value);\n uni.showToast({\n title: '设置已保存',\n icon: 'success'\n });\n } catch (err) {\n error.value = '保存设置失败';\n uni.__f__('error','at pages/user/settings.vue:26','保存设置失败:', err);\n } finally {\n loading.value = false;\n }\n};\n</script>\n\n<template>\n <view class=\"container\">\n <view class=\"card\">\n <text class=\"text-bold\">系统设置</text>\n <view class=\"divider\"></view>\n \n <view class=\"setting-item\">\n <text>消息通知</text>\n <switch :checked=\"settings.notification\" @change=\"(e: any) => settings.notification = e.detail.value\" />\n </view>\n \n <view class=\"setting-item\">\n <text>深色模式</text>\n <switch :checked=\"settings.darkMode\" @change=\"(e: any) => settings.darkMode = e.detail.value\" />\n </view>\n \n <view class=\"setting-item\">\n <text>语言设置</text>\n <picker mode=\"selector\" :range=\"['简体中文', 'English']\">\n <text>{{ settings.language === 'zh-CN' ? '简体中文' : 'English' }}</text>\n </picker>\n </view>\n \n <button \n class=\"margin-top\" \n type=\"primary\" \n :loading=\"loading\"\n @click=\"saveSettings\"\n >\n 保存设置\n </button>\n </view>\n \n <view v-if=\"error\" class=\"text-danger text-center margin-top\">\n {{ error }}\n </view>\n </view>\n</template>\n\n<style lang=\"scss\">\n.container {\n padding: 20rpx;\n}\n\n.card {\n background-color: #fff;\n border-radius: 8rpx;\n padding: 20rpx;\n box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\n.setting-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 20rpx 0;\n border-bottom: 1rpx solid #eee;\n}\n</style>","import MiniProgramPage from '/Users/ainongkeji/code/vue/niumall/mini_program/client-mp/src/pages/user/settings.vue'\nwx.createPage(MiniProgramPage)"],"names":["useUserStore","ref","updateUserSettings","uni","MiniProgramPage"],"mappings":";;;;;;;AAKkBA,6BAAa;AAC/B,UAAM,WAAWC,cAAAA,IAAI;AAAA,MACnB,cAAc;AAAA,MACd,UAAU;AAAA,MACV,UAAU;AAAA,IAAA,CACX;AACK,UAAA,UAAUA,kBAAI,KAAK;AACnB,UAAA,QAAQA,kBAAI,EAAE;AAGpB,UAAM,eAAe,YAAY;AAC3B,UAAA;AACF,gBAAQ,QAAQ;AACV,cAAAC,SAAA,mBAAmB,SAAS,KAAK;AACvCC,sBAAAA,MAAI,UAAU;AAAA,UACZ,OAAO;AAAA,UACP,MAAM;AAAA,QAAA,CACP;AAAA,eACM,KAAK;AACZ,cAAM,QAAQ;AACdA,sBAAA,MAAI,MAAM,SAAQ,iCAAgC,WAAW,GAAG;AAAA,MAAA,UAChE;AACA,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IAAA;;;;;;;;;;;;;;;;;;AC3BF,GAAG,WAAWC,SAAe;"}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"version":3,"file":"supplier.js","sources":["stores/supplier.ts"],"sourcesContent":["import { defineStore } from 'pinia';\nimport { ref } from 'vue';\nimport type { ISupplier, ICattleBreed } from '@/types/supplier';\nimport { fetchSuppliers, fetchCattleBreeds } from '@/api/supplier';\n\nexport const useSupplierStore = defineStore('supplier', () => {\n // 供应商列表\n const suppliers = ref<ISupplier[]>([]);\n \n // 牛只品种列表\n const cattleBreeds = ref<ICattleBreed[]>([]);\n \n // 获取供应商列表\n const fetchSuppliers = async () => {\n try {\n const data = await fetchSuppliers();\n suppliers.value = data;\n } catch (error) {\n console.error('获取供应商列表失败:', error);\n throw error;\n }\n };\n \n // 获取牛只品种列表\n const fetchCattleBreeds = async () => {\n try {\n const data = await fetchCattleBreeds();\n cattleBreeds.value = data;\n } catch (error) {\n console.error('获取牛只品种列表失败:', error);\n throw error;\n }\n };\n \n return {\n suppliers,\n cattleBreeds,\n fetchSuppliers,\n fetchCattleBreeds\n };\n});"],"names":["defineStore","ref","fetchSuppliers","uni","fetchCattleBreeds"],"mappings":";;AAKa,MAAA,mBAAmBA,cAAAA,YAAY,YAAY,MAAM;AAEtD,QAAA,YAAYC,kBAAiB,CAAA,CAAE;AAG/B,QAAA,eAAeA,kBAAoB,CAAA,CAAE;AAG3C,QAAMC,kBAAiB,YAAY;AAC7B,QAAA;AACI,YAAA,OAAO,MAAMA;AACnB,gBAAU,QAAQ;AAAA,aACX,OAAO;AACdC,oBAAA,MAAc,MAAA,SAAA,4BAAA,cAAc,KAAK;AAC3B,YAAA;AAAA,IACR;AAAA,EAAA;AAIF,QAAMC,qBAAoB,YAAY;AAChC,QAAA;AACI,YAAA,OAAO,MAAMA;AACnB,mBAAa,QAAQ;AAAA,aACd,OAAO;AACdD,oBAAA,MAAc,MAAA,SAAA,4BAAA,eAAe,KAAK;AAC5B,YAAA;AAAA,IACR;AAAA,EAAA;AAGK,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAAD;AAAAA,IACA,mBAAAE;AAAAA,EAAA;AAEJ,CAAC;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"user.js","sources":["stores/user.ts"],"sourcesContent":["import { defineStore } from 'pinia';\nimport { ref } from 'vue';\nimport type { IUser } from '@/types/user';\nimport { fetchUserInfo } from '@/api/user';\n\nexport const useUserStore = defineStore('user', () => {\n // 用户信息\n const userInfo = ref<IUser>({\n id: '',\n name: '加载中...',\n avatar: '/static/images/default-avatar.png',\n lastLogin: '',\n phone: '',\n company: '',\n role: 'client'\n });\n \n // 获取用户信息\n const fetchUserInfo = async () => {\n try {\n const info = await fetchUserInfo();\n userInfo.value = info;\n } catch (error) {\n console.error('获取用户信息失败:', error);\n throw error;\n }\n };\n \n return {\n userInfo,\n fetchUserInfo\n };\n});"],"names":["defineStore","ref","fetchUserInfo","uni"],"mappings":";;AAKa,MAAA,eAAeA,cAAAA,YAAY,QAAQ,MAAM;AAEpD,QAAM,WAAWC,cAAAA,IAAW;AAAA,IAC1B,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,EAAA,CACP;AAGD,QAAMC,iBAAgB,YAAY;AAC5B,QAAA;AACI,YAAA,OAAO,MAAMA;AACnB,eAAS,QAAQ;AAAA,aACV,OAAO;AACdC,oBAAA,6CAAc,aAAa,KAAK;AAC1B,YAAA;AAAA,IACR;AAAA,EAAA;AAGK,SAAA;AAAA,IACL;AAAA,IACA,eAAAD;AAAAA,EAAA;AAEJ,CAAC;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"feedback.js","sources":["utils/feedback.ts"],"sourcesContent":["// 显示成功提示\nexport const showSuccess = (title: string, duration = 1500) => {\n uni.showToast({\n title,\n icon: 'success',\n duration\n });\n};\n\n// 显示错误提示\nexport const showError = (title: string, duration = 1500) => {\n uni.showToast({\n title,\n icon: 'none',\n duration\n });\n};\n\n// 显示加载中\nexport const showLoading = (title = '加载中...') => {\n uni.showLoading({ title });\n};\n\n// 隐藏加载中\nexport const hideLoading = () => {\n uni.hideLoading();\n};\n\n// 显示确认对话框\nexport const showConfirm = (options: {\n title?: string;\n content: string;\n confirmText?: string;\n cancelText?: string;\n}) => {\n return new Promise<boolean>((resolve) => {\n uni.showModal({\n ...options,\n success: (res) => {\n resolve(res.confirm);\n }\n });\n });\n};"],"names":["uni"],"mappings":";;AACO,MAAM,cAAc,CAAC,OAAe,WAAW,SAAS;AAC7DA,gBAAAA,MAAI,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EAAA,CACD;AACH;AAGO,MAAM,YAAY,CAAC,OAAe,WAAW,SAAS;AAC3DA,gBAAAA,MAAI,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EAAA,CACD;AACH;;;"}

View File

@@ -1 +0,0 @@
{"version":3,"file":"request.js","sources":["utils/request.ts"],"sourcesContent":["import type { RequestOptions } from '@/types/request';\n\n// 环境配置\nconst config = {\n development: {\n baseURL: 'http://localhost:3001/api',\n wsURL: 'ws://localhost:3001'\n },\n production: {\n baseURL: 'https://api.niumall.com/api',\n wsURL: 'wss://api.niumall.com'\n }\n};\n\n// 当前环境\nconst env = process.env.NODE_ENV === 'production' ? 'production' : 'development';\nconst { baseURL, wsURL } = config[env];\n\n// 请求封装\nexport const request = (options: RequestOptions) => {\n return new Promise((resolve, reject) => {\n uni.request({\n url: baseURL + options.url,\n method: options.method || 'GET',\n data: options.data,\n header: {\n 'Authorization': `Bearer ${getToken()}`,\n 'Content-Type': 'application/json',\n ...options.header\n },\n success: (res) => {\n if (res.statusCode >= 200 && res.statusCode < 300) {\n resolve(res.data);\n } else {\n handleError(res);\n reject(res);\n }\n },\n fail: (err) => {\n handleError(err);\n reject(err);\n }\n });\n });\n};\n\n// WebSocket连接\nexport const connectWebSocket = () => {\n return uni.connectSocket({\n url: wsURL,\n success: () => {\n console.log('WebSocket连接成功');\n },\n fail: (err) => {\n console.error('WebSocket连接失败:', err);\n }\n });\n};\n\n// 获取token\nconst getToken = (): string => {\n try {\n const token = uni.getStorageSync('token');\n return token || '';\n } catch (e) {\n return '';\n }\n};\n\n// 错误处理\nconst handleError = (error: any) => {\n console.error('请求错误:', error);\n \n // 未授权\n if (error.statusCode === 401) {\n uni.redirectTo({\n url: '/pages/auth/login'\n });\n }\n \n // 其他错误\n uni.showToast({\n title: error.data?.message || '请求失败',\n icon: 'none'\n });\n};"],"names":["uni"],"mappings":";;AAGA,MAAM,SAAS;AAAA,EACb,aAAa;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,YAAY;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AACF;AAGA,MAAM,MAA6D;AACnE,MAAM,EAAE,SAAS,MAAM,IAAI,OAAO,GAAG;AAGxB,MAAA,UAAU,CAAC,YAA4B;AAClD,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtCA,kBAAAA,MAAI,QAAQ;AAAA,MACV,KAAK,UAAU,QAAQ;AAAA,MACvB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,MAAM,QAAQ;AAAA,MACd,QAAQ;AAAA,QACN,iBAAiB,UAAU,SAAA,CAAU;AAAA,QACrC,gBAAgB;AAAA,QAChB,GAAG,QAAQ;AAAA,MACb;AAAA,MACA,SAAS,CAAC,QAAQ;AAChB,YAAI,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACjD,kBAAQ,IAAI,IAAI;AAAA,QAAA,OACX;AACL,sBAAY,GAAG;AACf,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF;AAAA,MACA,MAAM,CAAC,QAAQ;AACb,oBAAY,GAAG;AACf,eAAO,GAAG;AAAA,MACZ;AAAA,IAAA,CACD;AAAA,EAAA,CACF;AACH;AAgBA,MAAM,WAAW,MAAc;AACzB,MAAA;AACI,UAAA,QAAQA,cAAAA,MAAI,eAAe,OAAO;AACxC,WAAO,SAAS;AAAA,WACT,GAAG;AACH,WAAA;AAAA,EACT;AACF;AAGA,MAAM,cAAc,CAAC,UAAe;;AAClCA,gBAAA,MAAc,MAAA,SAAA,0BAAA,SAAS,KAAK;AAGxB,MAAA,MAAM,eAAe,KAAK;AAC5BA,kBAAAA,MAAI,WAAW;AAAA,MACb,KAAK;AAAA,IAAA,CACN;AAAA,EACH;AAGAA,gBAAAA,MAAI,UAAU;AAAA,IACZ,SAAO,WAAM,SAAN,mBAAY,YAAW;AAAA,IAC9B,MAAM;AAAA,EAAA,CACP;AACH;;"}

View File

@@ -1 +0,0 @@
<view><slot/></view>

View File

@@ -1,17 +0,0 @@
"use strict";
const common_vendor = require("../common/vendor.js");
const utils_request = require("../utils/request.js");
const fetchAcceptanceList = async () => {
try {
const res = await utils_request.request({
url: "/acceptance/list",
method: "GET"
});
return res.data;
} catch (error) {
common_vendor.index.__f__("error", "at api/acceptance.ts:13", "获取验收列表失败:", error);
throw error;
}
};
exports.fetchAcceptanceList = fetchAcceptanceList;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/acceptance.js.map

View File

@@ -1,27 +0,0 @@
"use strict";
const utils_request = require("../utils/request.js");
const login = async (data) => {
return utils_request.request({
url: "/auth/login",
method: "POST",
data
});
};
const register = async (data) => {
return utils_request.request({
url: "/auth/register",
method: "POST",
data
});
};
const getCaptcha = async (phone) => {
return utils_request.request({
url: "/auth/captcha",
method: "GET",
data: { phone }
});
};
exports.getCaptcha = getCaptcha;
exports.login = login;
exports.register = register;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/auth.js.map

View File

@@ -1,17 +0,0 @@
"use strict";
const common_vendor = require("../common/vendor.js");
const utils_request = require("../utils/request.js");
const fetchPaymentList = async () => {
try {
const res = await utils_request.request({
url: "/payment/list",
method: "GET"
});
return res.data;
} catch (error) {
common_vendor.index.__f__("error", "at api/payment.ts:13", "获取支付列表失败:", error);
throw error;
}
};
exports.fetchPaymentList = fetchPaymentList;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/payment.js.map

View File

@@ -1,25 +0,0 @@
"use strict";
const utils_request = require("../utils/request.js");
const getPurchaseStats = async (params) => {
return utils_request.request({
url: "/stats/purchase",
method: "GET",
data: params
});
};
const getTransportStats = async () => {
return utils_request.request({
url: "/stats/transport",
method: "GET"
});
};
const getFinancialStats = async () => {
return utils_request.request({
url: "/stats/financial",
method: "GET"
});
};
exports.getFinancialStats = getFinancialStats;
exports.getPurchaseStats = getPurchaseStats;
exports.getTransportStats = getTransportStats;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/statistics.js.map

View File

@@ -1,11 +0,0 @@
"use strict";
const utils_request = require("../utils/request.js");
const fetchTrackingList = (params) => {
return utils_request.request({
url: "/api/tracking/list",
method: "GET",
params
});
};
exports.fetchTrackingList = fetchTrackingList;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/tracking.js.map

View File

@@ -1,31 +0,0 @@
"use strict";
const common_vendor = require("../common/vendor.js");
const utils_request = require("../utils/request.js");
const updateUserSettings = async (settings) => {
try {
const res = await utils_request.request({
url: "/user/settings",
method: "POST",
data: settings
});
return res.data;
} catch (error) {
common_vendor.index.__f__("error", "at api/user.ts:14", "更新用户设置失败:", error);
throw error;
}
};
const fetchUserProfile = async () => {
try {
const res = await utils_request.request({
url: "/user/profile",
method: "GET"
});
return res.data;
} catch (error) {
common_vendor.index.__f__("error", "at api/user.ts:28", "获取用户资料失败:", error);
throw error;
}
};
exports.fetchUserProfile = fetchUserProfile;
exports.updateUserSettings = updateUserSettings;
//# sourceMappingURL=../../.sourcemap/mp-weixin/api/user.js.map

View File

@@ -1,62 +0,0 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const common_vendor = require("./common/vendor.js");
const stores_user = require("./stores/user.js");
if (!Math) {
"./pages/index/index.js";
"./pages/order/order-list.js";
"./pages/order/order-detail.js";
"./pages/order/order-create.js";
"./pages/tracking/tracking-list.js";
"./pages/tracking/tracking-detail.js";
"./pages/acceptance/acceptance-list.js";
"./pages/acceptance/acceptance-detail.js";
"./pages/payment/payment-list.js";
"./pages/payment/payment-detail.js";
"./pages/statistics/statistics.js";
"./pages/auth/login.js";
"./pages/auth/register.js";
"./pages/user/profile.js";
"./pages/user/settings.js";
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "App",
setup(__props) {
const userStore = stores_user.useUserStore();
common_vendor.onLaunch(() => {
common_vendor.index.__f__("log", "at App.vue:8", "App Launch");
userStore.checkLoginStatus();
});
common_vendor.onShow(() => {
common_vendor.index.__f__("log", "at App.vue:14", "App Show");
});
common_vendor.onHide(() => {
common_vendor.index.__f__("log", "at App.vue:18", "App Hide");
});
return (_ctx, _cache) => {
return {};
};
}
});
function createApp() {
const app = common_vendor.createSSRApp(_sfc_main);
const pinia = common_vendor.createPinia();
pinia.use(({ store }) => {
const storageKey = `pinia_${store.$id}`;
const savedState = common_vendor.index.getStorageSync(storageKey);
if (savedState) {
store.$patch(JSON.parse(savedState));
}
store.$subscribe((mutation, state) => {
common_vendor.index.setStorageSync(storageKey, JSON.stringify(state));
});
});
app.use(pinia);
return {
app,
pinia
};
}
createApp().app.mount("#app");
exports.createApp = createApp;
//# sourceMappingURL=../.sourcemap/mp-weixin/app.js.map

View File

@@ -1,67 +0,0 @@
{
"pages": [
"pages/index/index",
"pages/order/order-list",
"pages/order/order-detail",
"pages/order/order-create",
"pages/tracking/tracking-list",
"pages/tracking/tracking-detail",
"pages/acceptance/acceptance-list",
"pages/acceptance/acceptance-detail",
"pages/payment/payment-list",
"pages/payment/payment-detail",
"pages/statistics/statistics",
"pages/auth/login",
"pages/auth/register",
"pages/user/profile",
"pages/user/settings"
],
"window": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "活牛采购",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home-active.png",
"text": "首页"
},
{
"pagePath": "pages/order/order-list",
"iconPath": "static/images/tabbar/order.png",
"selectedIconPath": "static/images/tabbar/order-active.png",
"text": "订单"
},
{
"pagePath": "pages/tracking/tracking-list",
"iconPath": "static/images/tabbar/tracking.png",
"selectedIconPath": "static/images/tabbar/tracking-active.png",
"text": "跟踪"
},
{
"pagePath": "pages/user/profile",
"iconPath": "static/images/tabbar/user.png",
"selectedIconPath": "static/images/tabbar/user-active.png",
"text": "我的"
}
]
},
"permission": {
"scope.userLocation": {
"desc": "您的位置信息将用于运输跟踪服务"
}
},
"requiredPrivateInfos": [
"getLocation",
"chooseLocation"
],
"usingComponents": {}
}

View File

@@ -1,14 +0,0 @@
/* 全局样式 */
page {
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica,
Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-weight: 400;
font-size: 14px;
color: #333;
background-color: #f8f8f8;
}
page{--status-bar-height:25px;--top-window-height:0px;--window-top:0px;--window-bottom:0px;--window-left:0px;--window-right:0px;--window-magin:0px}[data-c-h="true"]{display: none !important;}

View File

@@ -1,4 +0,0 @@
"use strict";
const _imports_0 = "/static/images/empty-order.png";
exports._imports_0 = _imports_0;
//# sourceMappingURL=../../.sourcemap/mp-weixin/common/assets.js.map

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +0,0 @@
"use strict";
const common_vendor = require("../../../../../common/vendor.js");
const getVal = (val) => {
const reg = /^[0-9]*$/g;
return typeof val === "number" || reg.test(val) ? val + "px" : val;
};
const _sfc_main = {
name: "UniIcons",
emits: ["click"],
props: {
type: {
type: String,
default: ""
},
color: {
type: String,
default: "#333333"
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ""
},
fontFamily: {
type: String,
default: ""
}
},
data() {
return {
icons: common_vendor.fontData
};
},
computed: {
unicode() {
let code = this.icons.find((v) => v.font_class === this.type);
if (code) {
return code.unicode;
}
return "";
},
iconSize() {
return getVal(this.size);
},
styleObj() {
if (this.fontFamily !== "") {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`;
}
return `color: ${this.color}; font-size: ${this.iconSize};`;
}
},
methods: {
_onClick(e) {
this.$emit("click", e);
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {
a: common_vendor.s($options.styleObj),
b: common_vendor.n("uniui-" + $props.type),
c: common_vendor.n($props.customPrefix),
d: common_vendor.n($props.customPrefix ? $props.type : ""),
e: common_vendor.o((...args) => $options._onClick && $options._onClick(...args))
};
}
const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createComponent(Component);
//# sourceMappingURL=../../../../../../.sourcemap/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.js.map

View File

@@ -1,4 +0,0 @@
{
"component": true,
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<text style="{{a}}" class="{{['uni-icons', b, c, d]}}" bindtap="{{e}}"><slot></slot></text>

View File

@@ -1,35 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "acceptance-detail",
setup(__props) {
stores_order.useOrderStore();
const acceptanceDetail = common_vendor.ref(null);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
common_vendor.onMounted(() => {
});
return (_ctx, _cache) => {
return common_vendor.e({
a: acceptanceDetail.value
}, acceptanceDetail.value ? common_vendor.e({
b: common_vendor.t(acceptanceDetail.value.orderId),
c: common_vendor.t(acceptanceDetail.value.status === "passed" ? "验收通过" : "验收未通过"),
d: common_vendor.n(acceptanceDetail.value.status === "passed" ? "text-primary" : "text-danger"),
e: common_vendor.t(acceptanceDetail.value.acceptanceTime),
f: common_vendor.t(acceptanceDetail.value.acceptor),
g: common_vendor.t(acceptanceDetail.value.result),
h: acceptanceDetail.value.images
}, acceptanceDetail.value.images ? {} : {}) : {}, {
i: loading.value
}, loading.value ? {} : {}, {
j: error.value
}, error.value ? {
k: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/acceptance/acceptance-detail.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "验收详情",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:if="{{a}}" class="card"><view class="flex-between"><text class="text-bold">订单号: {{b}}</text><text class="{{d}}">{{c}}</text></view><view class="divider"></view><text>验收时间: {{e}}</text><view class="margin-top-sm"><text>验收人: {{f}}</text></view><view class="margin-top-sm"><text>验收结果: {{g}}</text></view><view wx:if="{{h}}" class="margin-top-sm"><text>验收照片:</text></view></view><view wx:if="{{i}}" class="flex-center"><text>加载中...</text></view><view wx:if="{{j}}" class="flex-center"><text class="text-danger">{{k}}</text></view></view>

View File

@@ -1,10 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

View File

@@ -1,48 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const api_acceptance = require("../../api/acceptance.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "acceptance-list",
setup(__props) {
stores_order.useOrderStore();
const acceptanceList = common_vendor.ref([]);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
const getAcceptanceList = async () => {
try {
loading.value = true;
acceptanceList.value = await api_acceptance.fetchAcceptanceList();
} catch (err) {
error.value = "获取验收列表失败";
common_vendor.index.__f__("error", "at pages/acceptance/acceptance-list.vue:18", "获取验收列表失败:", err);
} finally {
loading.value = false;
}
};
common_vendor.onMounted(() => {
getAcceptanceList();
});
return (_ctx, _cache) => {
return common_vendor.e({
a: common_vendor.f(acceptanceList.value, (item, k0, i0) => {
return {
a: common_vendor.t(item.orderId),
b: common_vendor.t(item.status === "passed" ? "验收通过" : "验收未通过"),
c: common_vendor.n(item.status === "passed" ? "text-primary" : "text-danger"),
d: common_vendor.t(item.acceptanceTime),
e: common_vendor.t(item.result),
f: item.id
};
}),
b: loading.value
}, loading.value ? {} : {}, {
c: error.value
}, error.value ? {
d: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/acceptance/acceptance-list.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "验收管理",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:for="{{a}}" wx:for-item="item" wx:key="f" class="card"><view class="flex-between"><text class="text-bold">订单号: {{item.a}}</text><text class="{{item.c}}">{{item.b}}</text></view><view class="divider"></view><text>验收时间: {{item.d}}</text><view class="margin-top-sm"><text>验收结果: {{item.e}}</text></view></view><view wx:if="{{b}}" class="flex-center"><text>加载中...</text></view><view wx:if="{{c}}" class="flex-center"><text class="text-danger">{{d}}</text></view></view>

View File

@@ -1,10 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

View File

@@ -1,52 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_user = require("../../stores/user.js");
const api_auth = require("../../api/auth.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "login",
setup(__props) {
const userStore = stores_user.useUserStore();
const username = common_vendor.ref("");
const password = common_vendor.ref("");
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
const handleLogin = async () => {
try {
loading.value = true;
error.value = "";
const user = await api_auth.login(username.value, password.value);
userStore.setUser(user);
common_vendor.index.showToast({
title: "登录成功",
icon: "success"
});
common_vendor.index.switchTab({
url: "/pages/index/index"
});
} catch (err) {
error.value = "用户名或密码错误";
common_vendor.index.__f__("error", "at pages/auth/login.vue:28", "登录失败:", err);
} finally {
loading.value = false;
}
};
return (_ctx, _cache) => {
return common_vendor.e({
a: username.value,
b: common_vendor.o(($event) => username.value = $event.detail.value),
c: password.value,
d: common_vendor.o(($event) => password.value = $event.detail.value),
e: loading.value,
f: common_vendor.o(handleLogin),
g: common_vendor.o(($event) => common_vendor.index.navigateTo({
url: "/pages/auth/register"
})),
h: error.value
}, error.value ? {
i: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/auth/login.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "登录",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view class="card"><text class="text-bold">登录</text><view class="divider"></view><view class="margin-top"><text>用户名</text><input placeholder="请输入用户名" value="{{a}}" bindinput="{{b}}"/></view><view class="margin-top"><text>密码</text><input placeholder="请输入密码" type="password" value="{{c}}" bindinput="{{d}}"/></view><button class="margin-top" type="primary" loading="{{e}}" bindtap="{{f}}"> 登录 </button><view class="margin-top text-center"><text>还没有账号?</text><text class="text-primary" bindtap="{{g}}">立即注册</text></view></view><view wx:if="{{h}}" class="text-danger text-center margin-top">{{i}}</view></view>

View File

@@ -1,16 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
input {
border: 1rpx solid #eee;
border-radius: 8rpx;
padding: 10rpx;
margin-top: 10rpx;
width: 100%;
}

View File

@@ -1,94 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_user = require("../../stores/user.js");
const api_auth = require("../../api/auth.js");
const utils_feedback = require("../../utils/feedback.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "register",
setup(__props) {
const userStore = stores_user.useUserStore();
const form = common_vendor.ref({
username: "",
password: "",
confirmPassword: "",
phone: "",
captcha: "",
role: "client"
});
const captchaSent = common_vendor.ref(false);
const countdown = common_vendor.ref(0);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
const sendCaptcha = async () => {
if (!form.value.phone) {
utils_feedback.showError("请输入手机号");
return;
}
try {
await api_auth.getCaptcha(form.value.phone);
captchaSent.value = true;
countdown.value = 60;
const timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer);
captchaSent.value = false;
}
}, 1e3);
utils_feedback.showSuccess("验证码已发送");
} catch (error2) {
utils_feedback.showError("发送验证码失败");
common_vendor.index.__f__("error", "at pages/auth/register.vue:41", "发送验证码失败:", error2);
}
};
const submitRegister = async () => {
if (form.value.password !== form.value.confirmPassword) {
utils_feedback.showError("两次输入的密码不一致");
return;
}
try {
loading.value = true;
error.value = "";
const user = await api_auth.register(form.value);
userStore.setUser(user);
utils_feedback.showSuccess("注册成功");
setTimeout(() => {
common_vendor.index.navigateBack();
}, 1500);
} catch (err) {
error.value = "注册失败,请稍后再试";
utils_feedback.showError("注册失败");
common_vendor.index.__f__("error", "at pages/auth/register.vue:63", "注册失败:", err);
} finally {
loading.value = false;
}
};
return (_ctx, _cache) => {
return common_vendor.e({
a: form.value.username,
b: common_vendor.o(($event) => form.value.username = $event.detail.value),
c: form.value.password,
d: common_vendor.o(($event) => form.value.password = $event.detail.value),
e: form.value.confirmPassword,
f: common_vendor.o(($event) => form.value.confirmPassword = $event.detail.value),
g: form.value.phone,
h: common_vendor.o(($event) => form.value.phone = $event.detail.value),
i: form.value.captcha,
j: common_vendor.o(($event) => form.value.captcha = $event.detail.value),
k: common_vendor.t(captchaSent.value ? `${countdown.value}秒后重试` : "获取验证码"),
l: captchaSent.value,
m: common_vendor.o(sendCaptcha),
n: loading.value,
o: common_vendor.o(submitRegister),
p: common_vendor.o(($event) => common_vendor.index.navigateTo({
url: "/pages/auth/login"
})),
q: error.value
}, error.value ? {
r: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/auth/register.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "注册",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view class="card"><text class="text-bold">注册</text><view class="divider"></view><view class="form-item"><text class="label">用户名</text><input placeholder="请输入用户名" value="{{a}}" bindinput="{{b}}"/></view><view class="form-item"><text class="label">密码</text><input placeholder="请输入密码" type="password" value="{{c}}" bindinput="{{d}}"/></view><view class="form-item"><text class="label">确认密码</text><input placeholder="请再次输入密码" type="password" value="{{e}}" bindinput="{{f}}"/></view><view class="form-item"><text class="label">手机号</text><input placeholder="请输入手机号" type="number" value="{{g}}" bindinput="{{h}}"/></view><view class="form-item"><text class="label">验证码</text><view class="captcha-input"><input placeholder="请输入验证码" value="{{i}}" bindinput="{{j}}"/><button size="mini" disabled="{{l}}" bindtap="{{m}}">{{k}}</button></view></view><button type="primary" loading="{{n}}" bindtap="{{o}}"> 注册 </button><view class="login-link"><text>已有账号?</text><text class="text-primary" bindtap="{{p}}">立即登录</text></view></view><view wx:if="{{q}}" class="error-message">{{r}}</view></view>

View File

@@ -1,41 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 20rpx;
}
.form-item .label {
display: block;
margin-bottom: 10rpx;
font-weight: bold;
}
.form-item input {
border: 1rpx solid #eee;
border-radius: 8rpx;
padding: 20rpx;
width: 100%;
box-sizing: border-box;
}
.captcha-input {
display: flex;
align-items: center;
}
.captcha-input input {
flex: 1;
margin-right: 20rpx;
}
.login-link {
margin-top: 20rpx;
text-align: center;
}
.error-message {
margin-top: 20rpx;
color: #ff3b30;
text-align: center;
}

View File

@@ -1,107 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const stores_user = require("../../stores/user.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "index",
setup(__props) {
const orderStore = stores_order.useOrderStore();
const userStore = stores_user.useUserStore();
const homeData = common_vendor.ref({
pendingOrders: 0,
inTransitOrders: 0,
pendingAcceptance: 0,
pendingPayment: 0,
recentOrders: [],
statistics: {
totalAmount: 0,
totalWeight: 0,
averagePrice: 0
}
});
const loading = common_vendor.ref(false);
const loadData = async () => {
try {
loading.value = true;
await Promise.all([
orderStore.fetchOrderStats(),
orderStore.fetchRecentOrders(),
userStore.fetchUserInfo()
]);
homeData.value = {
pendingOrders: orderStore.pendingCount,
inTransitOrders: orderStore.inTransitCount,
pendingAcceptance: orderStore.pendingAcceptanceCount,
pendingPayment: orderStore.pendingPaymentCount,
recentOrders: orderStore.recentOrders.slice(0, 5),
statistics: {
totalAmount: orderStore.totalAmount,
totalWeight: orderStore.totalWeight,
averagePrice: orderStore.averagePrice
}
};
} catch (error) {
common_vendor.index.showToast({
title: "加载数据失败",
icon: "none"
});
common_vendor.index.__f__("error", "at pages/index/index.vue:53", "加载首页数据失败:", error);
} finally {
loading.value = false;
}
};
common_vendor.onMounted(() => {
loadData();
});
const onRefresh = () => {
loadData();
};
const navigateToOrderList = (type) => {
common_vendor.index.navigateTo({
url: `/pages/order/order-list?type=${type}`
});
};
const navigateToOrderDetail = (id) => {
common_vendor.index.navigateTo({
url: `/pages/order/order-detail?id=${id}`
});
};
return (_ctx, _cache) => {
return {
a: common_vendor.t(common_vendor.unref(userStore).userInfo.name),
b: common_vendor.t(common_vendor.unref(userStore).userInfo.lastLogin),
c: common_vendor.unref(userStore).userInfo.avatar,
d: common_vendor.o(($event) => navigateToOrderList("all")),
e: common_vendor.t(homeData.value.pendingOrders),
f: common_vendor.o(($event) => navigateToOrderList("pending")),
g: common_vendor.t(homeData.value.inTransitOrders),
h: common_vendor.o(($event) => navigateToOrderList("in_transit")),
i: common_vendor.t(homeData.value.pendingAcceptance),
j: common_vendor.o(($event) => navigateToOrderList("pending_acceptance")),
k: common_vendor.t(homeData.value.pendingPayment),
l: common_vendor.o(($event) => navigateToOrderList("pending_payment")),
m: common_vendor.t(homeData.value.statistics.totalAmount),
n: common_vendor.t(homeData.value.statistics.totalWeight),
o: common_vendor.t(homeData.value.statistics.averagePrice),
p: common_vendor.o(($event) => navigateToOrderList("all")),
q: common_vendor.f(homeData.value.recentOrders, (order, k0, i0) => {
return {
a: common_vendor.t(order.orderNo),
b: common_vendor.t(order.statusText),
c: common_vendor.n(`status-${order.status}`),
d: common_vendor.t(order.supplierName),
e: common_vendor.t(order.createTime),
f: common_vendor.t(order.quantity),
g: common_vendor.t(order.weight),
h: order.id,
i: common_vendor.o(($event) => navigateToOrderDetail(order.id), order.id)
};
}),
r: loading.value,
s: common_vendor.o(onRefresh)
};
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/index/index.js.map

View File

@@ -1,5 +0,0 @@
{
"navigationBarTitleText": "活牛采购",
"enablePullDownRefresh": true,
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><scroll-view scroll-y refresher-enabled refresher-triggered="{{r}}" bindrefresherrefresh="{{s}}"><view class="user-info card"><view class="flex-between"><view><text class="text-bold">欢迎回来,{{a}}</text><view class="margin-top-sm text-gray"><text>上次登录: {{b}}</text></view></view><image src="{{c}}" mode="aspectFill" class="avatar"/></view></view><view class="order-overview card"><view class="flex-between"><text class="text-bold">订单概览</text><text class="text-primary" bindtap="{{d}}">查看全部</text></view><view class="flex-between margin-top"><view class="overview-item" bindtap="{{f}}"><text class="overview-count">{{e}}</text><text class="overview-label">待处理</text></view><view class="overview-item" bindtap="{{h}}"><text class="overview-count">{{g}}</text><text class="overview-label">运输中</text></view><view class="overview-item" bindtap="{{j}}"><text class="overview-count">{{i}}</text><text class="overview-label">待验收</text></view><view class="overview-item" bindtap="{{l}}"><text class="overview-count">{{k}}</text><text class="overview-label">待支付</text></view></view></view><view class="statistics card"><view class="flex-between"><text class="text-bold">采购统计</text><text class="text-primary">本月</text></view><view class="flex-between margin-top"><view class="stat-item"><text class="stat-value">¥{{m}}</text><text class="stat-label">总金额</text></view><view class="stat-item"><text class="stat-value">{{n}}kg</text><text class="stat-label">总重量</text></view><view class="stat-item"><text class="stat-value">¥{{o}}</text><text class="stat-label">均价/kg</text></view></view></view><view class="recent-orders card"><view class="flex-between"><text class="text-bold">最近订单</text><text class="text-primary" bindtap="{{p}}">查看全部</text></view><view class="margin-top"><view wx:for="{{q}}" wx:for-item="order" wx:key="h" class="order-item" bindtap="{{order.i}}"><view class="flex-between"><text class="text-bold">订单号: {{order.a}}</text><text class="{{order.c}}">{{order.b}}</text></view><view class="flex-between margin-top-sm"><text>供应商: {{order.d}}</text><text>{{order.e}}</text></view><view class="flex-between margin-top-sm"><text>数量: {{order.f}}头</text><text>重量: {{order.g}}kg</text></view></view></view></view></scroll-view></view>

View File

@@ -1,66 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
margin-bottom: 20rpx;
padding: 20rpx;
}
.user-info .avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.overview-item {
display: flex;
flex-direction: column;
align-items: center;
}
.overview-item .overview-count {
font-size: 36rpx;
font-weight: bold;
color: #3cc51f;
}
.overview-item .overview-label {
font-size: 24rpx;
color: #666;
margin-top: 10rpx;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-item .stat-value {
font-size: 28rpx;
font-weight: bold;
}
.stat-item .stat-label {
font-size: 24rpx;
color: #666;
margin-top: 10rpx;
}
.order-item {
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.order-item:last-child {
border-bottom: none;
}
.order-item .status-pending {
color: #ff9900;
}
.order-item .status-in_transit {
color: #1989fa;
}
.order-item .status-pending_acceptance {
color: #ff9900;
}
.order-item .status-completed {
color: #3cc51f;
}
.order-item .status-canceled {
color: #999;
}

View File

@@ -1,122 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const stores_supplier = require("../../stores/supplier.js");
if (!Array) {
const _easycom_uni_icons2 = common_vendor.resolveComponent("uni-icons");
_easycom_uni_icons2();
}
const _easycom_uni_icons = () => "../../node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.js";
if (!Math) {
_easycom_uni_icons();
}
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "order-create",
setup(__props) {
const orderStore = stores_order.useOrderStore();
const supplierStore = stores_supplier.useSupplierStore();
const form = common_vendor.ref({
supplierId: "",
cattleBreed: "",
quantity: 1,
estimatedWeight: 0,
price: 0,
prepaymentRatio: 30,
notes: ""
});
const loading = common_vendor.ref(false);
const loadData = async () => {
try {
loading.value = true;
await supplierStore.fetchSuppliers();
await supplierStore.fetchCattleBreeds();
} catch (error) {
common_vendor.index.showToast({
title: "加载数据失败",
icon: "none"
});
common_vendor.index.__f__("error", "at pages/order/order-create.vue:33", "加载供应商和品种数据失败:", error);
} finally {
loading.value = false;
}
};
const totalAmount = common_vendor.computed(() => {
return form.value.estimatedWeight * form.value.price;
});
const prepaymentAmount = common_vendor.computed(() => {
return totalAmount.value * (form.value.prepaymentRatio / 100);
});
const submitOrder = async () => {
try {
loading.value = true;
await orderStore.createOrder(form.value);
common_vendor.index.showToast({
title: "订单创建成功",
icon: "success"
});
setTimeout(() => {
common_vendor.index.navigateBack();
}, 1500);
} catch (error) {
common_vendor.index.showToast({
title: "订单创建失败",
icon: "none"
});
common_vendor.index.__f__("error", "at pages/order/order-create.vue:66", "订单创建失败:", error);
} finally {
loading.value = false;
}
};
common_vendor.onMounted(() => {
loadData();
});
return (_ctx, _cache) => {
var _a;
return common_vendor.e({
a: loading.value
}, loading.value ? {} : common_vendor.e({
b: form.value.supplierId
}, form.value.supplierId ? {
c: common_vendor.t(((_a = common_vendor.unref(supplierStore).suppliers.find((s) => s.id === form.value.supplierId)) == null ? void 0 : _a.name) || "请选择供应商")
} : {}, {
d: common_vendor.p({
type: "arrowright",
size: "16",
color: "#999"
}),
e: common_vendor.unref(supplierStore).suppliers,
f: common_vendor.o((e) => form.value.supplierId = common_vendor.unref(supplierStore).suppliers[e.detail.value].id),
g: form.value.cattleBreed
}, form.value.cattleBreed ? {
h: common_vendor.t(form.value.cattleBreed),
i: common_vendor.t(form.value.price)
} : {}, {
j: common_vendor.p({
type: "arrowright",
size: "16",
color: "#999"
}),
k: common_vendor.unref(supplierStore).cattleBreeds,
l: common_vendor.o((e) => {
form.value.cattleBreed = common_vendor.unref(supplierStore).cattleBreeds[e.detail.value].name;
form.value.price = common_vendor.unref(supplierStore).cattleBreeds[e.detail.value].price;
}),
m: form.value.quantity,
n: common_vendor.o(($event) => form.value.quantity = $event.detail.value),
o: form.value.estimatedWeight,
p: common_vendor.o(($event) => form.value.estimatedWeight = $event.detail.value),
q: common_vendor.t(form.value.price),
r: common_vendor.t(totalAmount.value),
s: form.value.prepaymentRatio,
t: common_vendor.o((e) => form.value.prepaymentRatio = e.detail.value),
v: common_vendor.t(prepaymentAmount.value),
w: form.value.notes,
x: common_vendor.o(($event) => form.value.notes = $event.detail.value),
y: !form.value.supplierId || !form.value.cattleBreed || !form.value.estimatedWeight,
z: common_vendor.o(submitOrder)
}));
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/order/order-create.js.map

View File

@@ -1,6 +0,0 @@
{
"navigationBarTitleText": "创建订单",
"usingComponents": {
"uni-icons": "../../node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons"
}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:if="{{a}}" class="loading"><text>加载中...</text></view><view wx:else class="form"><view class="form-item"><text class="label">选择供应商</text><picker mode="selector" range="{{e}}" range-key="name" bindchange="{{f}}"><view class="picker"><text wx:if="{{b}}">{{c}}</text><text wx:else class="placeholder">请选择供应商</text><uni-icons wx:if="{{d}}" u-i="03edf24f-0" bind:__l="__l" u-p="{{d}}"></uni-icons></view></picker></view><view class="form-item"><text class="label">牛只品种</text><picker mode="selector" range="{{k}}" range-key="name" bindchange="{{l}}"><view class="picker"><text wx:if="{{g}}">{{h}} (¥{{i}}/kg) </text><text wx:else class="placeholder">请选择牛只品种</text><uni-icons wx:if="{{j}}" u-i="03edf24f-1" bind:__l="__l" u-p="{{j}}"></uni-icons></view></picker></view><view class="form-item"><text class="label">数量(头)</text><input type="number" placeholder="请输入数量" class="input" value="{{m}}" bindinput="{{n}}"/></view><view class="form-item"><text class="label">预估重量(kg)</text><input type="number" placeholder="请输入预估重量" class="input" value="{{o}}" bindinput="{{p}}"/></view><view class="form-item"><text class="label">单价</text><text class="value">¥{{q}}/kg</text></view><view class="form-item"><text class="label">总金额</text><text class="value">¥{{r}}</text></view><view class="form-item"><text class="label">预付款比例</text><slider value="{{s}}" min="0" max="100" show-value activeColor="#3cc51f" bindchange="{{t}}"/><text class="hint">预付款金额: ¥{{v}}</text></view><view class="form-item"><text class="label">备注</text><block wx:if="{{r0}}"><textarea placeholder="请输入备注信息" class="textarea" value="{{w}}" bindinput="{{x}}"/></block></view><button type="primary" disabled="{{y}}" bindtap="{{z}}"> 提交订单 </button></view></view>

View File

@@ -1,53 +0,0 @@
.container {
padding: 20rpx;
}
.loading {
display: flex;
justify-content: center;
padding: 40rpx;
color: #999;
}
.form .form-item {
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
}
.form .form-item .label {
display: block;
margin-bottom: 20rpx;
font-weight: bold;
}
.form .form-item .picker {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 0;
}
.form .form-item .picker .placeholder {
color: #999;
}
.form .form-item .input {
border: 1rpx solid #eee;
padding: 20rpx;
border-radius: 8rpx;
}
.form .form-item .value {
color: #3cc51f;
font-weight: bold;
}
.form .form-item .hint {
display: block;
margin-top: 10rpx;
color: #999;
font-size: 24rpx;
}
.form .form-item .textarea {
width: 100%;
height: 200rpx;
border: 1rpx solid #eee;
padding: 20rpx;
border-radius: 8rpx;
box-sizing: border-box;
}

View File

@@ -1,127 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_assets = require("../../common/assets.js");
const stores_order = require("../../stores/order.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "order-detail",
setup(__props) {
const orderStore = stores_order.useOrderStore();
const loading = common_vendor.ref(false);
const orderId = common_vendor.ref("");
const order = common_vendor.ref(null);
common_vendor.onLoad((options) => {
orderId.value = options.id || "";
loadOrderDetail();
});
const loadOrderDetail = async () => {
try {
loading.value = true;
await orderStore.fetchOrderDetail(orderId.value);
order.value = orderStore.currentOrder;
} catch (error) {
common_vendor.index.showToast({
title: "加载订单详情失败",
icon: "none"
});
common_vendor.index.__f__("error", "at pages/order/order-detail.vue:29", "加载订单详情失败:", error);
} finally {
loading.value = false;
}
};
common_vendor.computed(() => {
if (!order.value)
return "";
switch (order.value.status) {
case "pending":
return "warning";
case "confirmed":
return "primary";
case "in_transit":
return "primary";
case "pending_acceptance":
return "warning";
case "completed":
return "success";
case "canceled":
return "gray";
default:
return "";
}
});
const handleCancelOrder = async () => {
try {
await orderStore.cancelOrder(orderId.value);
order.value = orderStore.currentOrder;
common_vendor.index.showToast({
title: "订单已取消",
icon: "success"
});
} catch (error) {
common_vendor.index.showToast({
title: "取消订单失败",
icon: "none"
});
}
};
const handleAcceptOrder = async () => {
try {
await orderStore.acceptOrder(orderId.value);
order.value = orderStore.currentOrder;
common_vendor.index.showToast({
title: "订单已确认收货",
icon: "success"
});
} catch (error) {
common_vendor.index.showToast({
title: "确认收货失败",
icon: "none"
});
}
};
return (_ctx, _cache) => {
return common_vendor.e({
a: loading.value
}, loading.value ? {} : {}, {
b: order.value
}, order.value ? common_vendor.e({
c: common_vendor.t(order.value.statusText),
d: order.value.statusDesc
}, order.value.statusDesc ? {
e: common_vendor.t(order.value.statusDesc)
} : {}, {
f: common_vendor.n(`status-${order.value.status}`),
g: common_vendor.t(order.value.orderNo),
h: common_vendor.t(order.value.createTime),
i: common_vendor.t(order.value.updateTime),
j: common_vendor.t(order.value.supplierName),
k: common_vendor.t(order.value.supplierContact),
l: common_vendor.t(order.value.supplierPhone),
m: common_vendor.t(order.value.cattleBreed),
n: common_vendor.t(order.value.quantity),
o: common_vendor.t(order.value.weight),
p: common_vendor.t(order.value.price),
q: common_vendor.t(order.value.totalAmount),
r: order.value.transportInfo
}, order.value.transportInfo ? {
s: common_vendor.t(order.value.transportInfo.driverName),
t: common_vendor.t(order.value.transportInfo.driverPhone),
v: common_vendor.t(order.value.transportInfo.licensePlate),
w: common_vendor.t(order.value.transportInfo.estimatedArrival)
} : {}, {
x: order.value.status === "pending"
}, order.value.status === "pending" ? {
y: common_vendor.o(handleCancelOrder)
} : {}, {
z: order.value.status === "pending_acceptance"
}, order.value.status === "pending_acceptance" ? {
A: common_vendor.o(handleAcceptOrder)
} : {}) : {}, {
B: !loading.value && !order.value
}, !loading.value && !order.value ? {
C: common_assets._imports_0
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/order/order-detail.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "订单详情",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:if="{{a}}" class="loading"><text>加载中...</text></view><view wx:if="{{b}}" class="order-detail"><view class="{{['status-card', f]}}"><text class="status-text">{{c}}</text><text wx:if="{{d}}" class="status-desc">{{e}}</text></view><view class="card"><view class="section-title"><text class="text-bold">订单信息</text></view><view class="info-item"><text class="info-label">订单编号:</text><text class="info-value">{{g}}</text></view><view class="info-item"><text class="info-label">创建时间:</text><text class="info-value">{{h}}</text></view><view class="info-item"><text class="info-label">更新时间:</text><text class="info-value">{{i}}</text></view></view><view class="card"><view class="section-title"><text class="text-bold">供应商信息</text></view><view class="info-item"><text class="info-label">供应商名称:</text><text class="info-value">{{j}}</text></view><view class="info-item"><text class="info-label">联系人:</text><text class="info-value">{{k}}</text></view><view class="info-item"><text class="info-label">联系电话:</text><text class="info-value">{{l}}</text></view></view><view class="card"><view class="section-title"><text class="text-bold">牛只信息</text></view><view class="info-item"><text class="info-label">品种:</text><text class="info-value">{{m}}</text></view><view class="info-item"><text class="info-label">数量:</text><text class="info-value">{{n}}头</text></view><view class="info-item"><text class="info-label">总重量:</text><text class="info-value">{{o}}kg</text></view><view class="info-item"><text class="info-label">单价:</text><text class="info-value">¥{{p}}/kg</text></view><view class="info-item"><text class="info-label">总金额:</text><text class="info-value">¥{{q}}</text></view></view><view wx:if="{{r}}" class="card"><view class="section-title"><text class="text-bold">运输信息</text></view><view class="info-item"><text class="info-label">司机姓名:</text><text class="info-value">{{s}}</text></view><view class="info-item"><text class="info-label">司机电话:</text><text class="info-value">{{t}}</text></view><view class="info-item"><text class="info-label">车牌号:</text><text class="info-value">{{v}}</text></view><view class="info-item"><text class="info-label">预计到达:</text><text class="info-value">{{w}}</text></view></view><view class="action-buttons"><button wx:if="{{x}}" type="warn" bindtap="{{y}}"> 取消订单 </button><button wx:if="{{z}}" type="primary" bindtap="{{A}}"> 确认收货 </button></view></view><view wx:if="{{B}}" class="empty"><image src="{{C}}" mode="aspectFit"></image><text class="empty-text">订单不存在</text></view></view>

View File

@@ -1,88 +0,0 @@
.container {
padding: 20rpx;
}
.loading {
display: flex;
justify-content: center;
padding: 40rpx;
color: #999;
}
.status-card {
padding: 30rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
color: #fff;
text-align: center;
}
.status-card .status-text {
font-size: 36rpx;
font-weight: bold;
}
.status-card .status-desc {
display: block;
margin-top: 10rpx;
font-size: 24rpx;
opacity: 0.8;
}
.status-card.status-pending {
background-color: #ff9900;
}
.status-card.status-confirmed {
background-color: #1989fa;
}
.status-card.status-in_transit {
background-color: #1989fa;
}
.status-card.status-pending_acceptance {
background-color: #ff9900;
}
.status-card.status-completed {
background-color: #3cc51f;
}
.status-card.status-canceled {
background-color: #999;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
}
.card .section-title {
padding-bottom: 20rpx;
margin-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.info-item {
display: flex;
margin-bottom: 15rpx;
}
.info-item .info-label {
width: 150rpx;
color: #666;
}
.info-item .info-value {
flex: 1;
}
.action-buttons {
margin-top: 40rpx;
}
.action-buttons button {
margin-bottom: 20rpx;
}
.empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
.empty .empty-text {
color: #999;
}

View File

@@ -1,114 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_assets = require("../../common/assets.js");
const stores_order = require("../../stores/order.js");
if (!Math) {
uniIcons();
}
const uniIcons = () => "../../node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons.js";
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "order-list",
setup(__props) {
const orderStore = stores_order.useOrderStore();
const loading = common_vendor.ref(false);
const refreshing = common_vendor.ref(false);
const statusFilter = common_vendor.ref("all");
const loadOrders = async () => {
try {
loading.value = true;
await orderStore.fetchOrders(statusFilter.value);
} catch (error) {
common_vendor.index.showToast({
title: "加载订单失败",
icon: "none"
});
common_vendor.index.__f__("error", "at pages/order/order-list.vue:23", "加载订单列表失败:", error);
} finally {
loading.value = false;
refreshing.value = false;
}
};
const onRefresh = () => {
refreshing.value = true;
loadOrders();
};
common_vendor.onMounted(() => {
loadOrders();
});
const filteredOrders = common_vendor.computed(() => {
if (statusFilter.value === "all") {
return orderStore.orders;
}
return orderStore.orders.filter(
(order) => order.status === statusFilter.value
);
});
const navigateToDetail = (id) => {
common_vendor.index.navigateTo({
url: `/pages/order/order-detail?id=${id}`
});
};
const navigateToCreate = () => {
common_vendor.index.navigateTo({
url: "/pages/order/order-create"
});
};
const statusOptions = [
{ value: "all", label: "全部订单" },
{ value: "pending", label: "待确认" },
{ value: "confirmed", label: "已确认" },
{ value: "in_transit", label: "运输中" },
{ value: "pending_acceptance", label: "待验收" },
{ value: "completed", label: "已完成" },
{ value: "canceled", label: "已取消" }
];
return (_ctx, _cache) => {
var _a;
return common_vendor.e({
a: common_vendor.t((_a = statusOptions.find((opt) => opt.value === statusFilter.value)) == null ? void 0 : _a.label),
b: common_vendor.p({
type: "arrowdown",
size: "16",
color: "#666"
}),
c: statusOptions,
d: common_vendor.o((e) => statusFilter.value = statusOptions[e.detail.value].value),
e: !loading.value && filteredOrders.value.length === 0
}, !loading.value && filteredOrders.value.length === 0 ? {
f: common_assets._imports_0,
g: common_vendor.o(navigateToCreate)
} : {}, {
h: common_vendor.f(filteredOrders.value, (order, k0, i0) => {
return common_vendor.e({
a: common_vendor.t(order.orderNo),
b: common_vendor.t(order.statusText),
c: common_vendor.n(`status-${order.status}`),
d: common_vendor.t(order.supplierName),
e: common_vendor.t(order.quantity),
f: common_vendor.t(order.weight),
g: common_vendor.t(order.totalAmount),
h: common_vendor.t(order.createTime),
i: order.status === "pending"
}, order.status === "pending" ? {
j: common_vendor.o(($event) => common_vendor.unref(orderStore).cancelOrder(order.id), order.id)
} : {}, {
k: order.id,
l: common_vendor.o(($event) => navigateToDetail(order.id), order.id)
});
}),
i: loading.value
}, loading.value ? {} : {}, {
j: refreshing.value,
k: common_vendor.o(onRefresh),
l: common_vendor.p({
type: "plus",
size: "20",
color: "#fff"
}),
m: common_vendor.o(navigateToCreate)
});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/order/order-list.js.map

View File

@@ -1,7 +0,0 @@
{
"navigationBarTitleText": "订单管理",
"enablePullDownRefresh": true,
"usingComponents": {
"uni-icons": "../../node-modules/@dcloudio/uni-ui/lib/uni-icons/uni-icons"
}
}

View File

@@ -1 +0,0 @@
<view class="container"><view class="filter-bar"><picker mode="selector" range="{{c}}" range-key="label" bindchange="{{d}}"><view class="filter-item"><text>{{a}}</text><uni-icons wx:if="{{b}}" u-i="30e453b1-0" bind:__l="__l" u-p="{{b}}"></uni-icons></view></picker></view><scroll-view scroll-y refresher-enabled refresher-triggered="{{j}}" bindrefresherrefresh="{{k}}"><view wx:if="{{e}}" class="empty"><image src="{{f}}" mode="aspectFit"></image><text class="empty-text">暂无订单</text><button type="button" size="mini" class="empty-btn primary" bindtap="{{g}}"> 创建订单 </button></view><view wx:for="{{h}}" wx:for-item="order" wx:key="k" class="order-item" bindtap="{{order.l}}"><view class="order-header"><text class="order-no">订单号: {{order.a}}</text><text class="{{order.c}}">{{order.b}}</text></view><view class="order-content"><view class="order-info"><text>供应商: {{order.d}}</text><text>数量: {{order.e}}头</text></view><view class="order-info"><text>重量: {{order.f}}kg</text><text>金额: ¥{{order.g}}</text></view></view><view class="order-footer"><text class="order-time">{{order.h}}</text><view class="order-actions"><button wx:if="{{order.i}}" size="mini" type="button" class="warn" catchtap="{{order.j}}"> 取消订单 </button></view></view></view><view wx:if="{{i}}" class="loading"><text>加载中...</text></view></scroll-view><view class="create-btn"><button type="button" class="primary" bindtap="{{m}}"><uni-icons wx:if="{{l}}" u-i="30e453b1-1" bind:__l="__l" u-p="{{l}}"></uni-icons> 创建订单 </button></view></view>

View File

@@ -1,109 +0,0 @@
.container {
padding: 20rpx;
height: 100vh;
box-sizing: border-box;
}
.filter-bar {
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
}
.filter-bar .filter-item {
display: flex;
align-items: center;
justify-content: space-between;
}
.order-item {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1);
}
.order-item .order-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.order-item .order-header .order-no {
font-size: 28rpx;
color: #333;
}
.order-item .order-header .status-pending {
color: #ff9900;
}
.order-item .order-header .status-confirmed {
color: #1989fa;
}
.order-item .order-header .status-in_transit {
color: #1989fa;
}
.order-item .order-header .status-pending_acceptance {
color: #ff9900;
}
.order-item .order-header .status-completed {
color: #3cc51f;
}
.order-item .order-header .status-canceled {
color: #999;
}
.order-item .order-content {
padding: 20rpx 0;
}
.order-item .order-content .order-info {
display: flex;
justify-content: space-between;
margin-bottom: 10rpx;
color: #666;
}
.order-item .order-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20rpx;
border-top: 1rpx solid #eee;
}
.order-item .order-footer .order-time {
color: #999;
font-size: 24rpx;
}
.empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty image {
width: 200rpx;
height: 200rpx;
margin-bottom: 20rpx;
}
.empty .empty-text {
color: #999;
margin-bottom: 30rpx;
}
.loading {
display: flex;
justify-content: center;
padding: 20rpx;
color: #999;
}
.create-btn {
position: fixed;
bottom: 40rpx;
right: 40rpx;
z-index: 999;
}
.create-btn button {
display: flex;
align-items: center;
justify-content: center;
height: 80rpx;
border-radius: 40rpx;
box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.2);
}

View File

@@ -1,38 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "payment-detail",
setup(__props) {
stores_order.useOrderStore();
const paymentDetail = common_vendor.ref(null);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
common_vendor.onMounted(() => {
});
return (_ctx, _cache) => {
return common_vendor.e({
a: paymentDetail.value
}, paymentDetail.value ? common_vendor.e({
b: common_vendor.t(paymentDetail.value.orderId),
c: common_vendor.t(paymentDetail.value.status === "paid" ? "已支付" : "待支付"),
d: common_vendor.n(paymentDetail.value.status === "paid" ? "text-primary" : "text-warning"),
e: common_vendor.t(paymentDetail.value.amount),
f: common_vendor.t(paymentDetail.value.paymentMethod),
g: paymentDetail.value.status === "paid"
}, paymentDetail.value.status === "paid" ? {
h: common_vendor.t(paymentDetail.value.paidTime)
} : {}, {
i: paymentDetail.value.status === "pending"
}, paymentDetail.value.status === "pending" ? {} : {}) : {}, {
j: loading.value
}, loading.value ? {} : {}, {
k: error.value
}, error.value ? {
l: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/payment/payment-detail.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "结算详情",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:if="{{a}}" class="card"><view class="flex-between"><text class="text-bold">订单号: {{b}}</text><text class="{{d}}">{{c}}</text></view><view class="divider"></view><text>金额: ¥{{e}}</text><view class="margin-top-sm"><text>支付方式: {{f}}</text></view><view wx:if="{{g}}" class="margin-top-sm"><text>支付时间: {{h}}</text></view><view class="margin-top-sm"><button wx:if="{{i}}" type="primary">立即支付</button></view></view><view wx:if="{{j}}" class="flex-center"><text>加载中...</text></view><view wx:if="{{k}}" class="flex-center"><text class="text-danger">{{l}}</text></view></view>

View File

@@ -1,10 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

View File

@@ -1,48 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const stores_order = require("../../stores/order.js");
const api_payment = require("../../api/payment.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "payment-list",
setup(__props) {
stores_order.useOrderStore();
const paymentList = common_vendor.ref([]);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
const getPaymentList = async () => {
try {
loading.value = true;
paymentList.value = await api_payment.fetchPaymentList();
} catch (err) {
error.value = "获取支付列表失败";
common_vendor.index.__f__("error", "at pages/payment/payment-list.vue:18", "获取支付列表失败:", err);
} finally {
loading.value = false;
}
};
common_vendor.onMounted(() => {
getPaymentList();
});
return (_ctx, _cache) => {
return common_vendor.e({
a: common_vendor.f(paymentList.value, (item, k0, i0) => {
return {
a: common_vendor.t(item.orderId),
b: common_vendor.t(item.status === "paid" ? "已支付" : "待支付"),
c: common_vendor.n(item.status === "paid" ? "text-primary" : "text-warning"),
d: common_vendor.t(item.amount),
e: common_vendor.t(item.paymentMethod),
f: item.id
};
}),
b: loading.value
}, loading.value ? {} : {}, {
c: error.value
}, error.value ? {
d: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/payment/payment-list.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "结算支付",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:for="{{a}}" wx:for-item="item" wx:key="f" class="card"><view class="flex-between"><text class="text-bold">订单号: {{item.a}}</text><text class="{{item.c}}">{{item.b}}</text></view><view class="divider"></view><text>金额: ¥{{item.d}}</text><view class="margin-top-sm"><text>支付方式: {{item.e}}</text></view></view><view wx:if="{{b}}" class="flex-center"><text>加载中...</text></view><view wx:if="{{c}}" class="flex-center"><text class="text-danger">{{d}}</text></view></view>

View File

@@ -1,10 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

View File

@@ -1,52 +0,0 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const api_statistics = require("../../api/statistics.js");
const _sfc_main = /* @__PURE__ */ common_vendor.defineComponent({
__name: "statistics",
setup(__props) {
const statistics = common_vendor.ref(null);
const loading = common_vendor.ref(false);
const error = common_vendor.ref("");
const getStatistics = async () => {
try {
loading.value = true;
const [purchase, transport, financial] = await Promise.all([
api_statistics.getPurchaseStats(),
api_statistics.getTransportStats(),
api_statistics.getFinancialStats()
]);
statistics.value = {
...purchase,
...transport,
...financial
};
} catch (err) {
error.value = "获取统计数据失败";
common_vendor.index.__f__("error", "at pages/statistics/statistics.vue:25", "获取统计数据失败:", err);
} finally {
loading.value = false;
}
};
common_vendor.onMounted(() => {
getStatistics();
});
return (_ctx, _cache) => {
return common_vendor.e({
a: statistics.value
}, statistics.value ? {
b: common_vendor.t(statistics.value.totalPurchase),
c: common_vendor.t(statistics.value.totalAmount),
d: common_vendor.t(statistics.value.averagePrice),
e: common_vendor.t(statistics.value.averageWeight)
} : {}, {
f: loading.value
}, loading.value ? {} : {}, {
g: error.value
}, error.value ? {
h: common_vendor.t(error.value)
} : {});
};
}
});
wx.createPage(_sfc_main);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/statistics/statistics.js.map

View File

@@ -1,4 +0,0 @@
{
"navigationBarTitleText": "数据统计",
"usingComponents": {}
}

View File

@@ -1 +0,0 @@
<view class="container"><view wx:if="{{a}}" class="card"><text class="text-bold">采购统计</text><view class="divider"></view><view class="flex-between margin-top-sm"><text>总采购量: {{b}}头</text><text>总金额: ¥{{c}}</text></view><view class="flex-between margin-top-sm"><text>平均价格: ¥{{d}}/头</text><text>平均重量: {{e}}kg</text></view></view><view class="card margin-top"><text class="text-bold">采购趋势</text><view class="divider"></view><view class="chart-placeholder"><text>采购趋势图表</text></view></view><view wx:if="{{f}}" class="flex-center"><text>加载中...</text></view><view wx:if="{{g}}" class="flex-center"><text class="text-danger">{{h}}</text></view></view>

View File

@@ -1,19 +0,0 @@
.container {
padding: 20rpx;
}
.card {
background-color: #fff;
border-radius: 8rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
.chart-placeholder {
height: 300rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
}

Some files were not shown because too many files have changed in this diff Show More