订单列表,飞行任务接口对接

This commit is contained in:
Double-_-Z 2025-07-30 18:00:25 +08:00
parent 45e22fdddc
commit ba75524ecd
6 changed files with 372 additions and 93 deletions

View File

@ -1,7 +1,9 @@
<template>
<view class="mobile-index">
<scroll-view :scroll-top="scrollTop" :scrollY="true" class="u-page upage"
scroll-with-animation @scroll="scroll" @refresherrefresh="refresh">
scroll-with-animation @scroll="scroll" @refresherrefresh="refresh"
:refresher-enabled="(isPilot&&current!==3)||(!isPilot&&current!==1)"
:refresher-triggered="triggered" @refresherpulling="onPulling" lower-threshold="60">
<!-- #ifdef MP-WEIXIN -->
<Order ref="pageRef" :topLevel="topLevel" v-if="current===0" />
<Equipment ref="pageRef" :topLevel="topLevel" v-if="isPilot&&current===1" />
@ -90,9 +92,13 @@ export default {
//
isLogin: this.$store.state.vuex_token,
isPilot: this.$store.state.user_type == 1,
//
triggered: false,
_freshing: false
}
},
mounted(){
this._freshing = false;
let index = uni.getStorageSync('current');
// B线
this.current = (!index||(!this.isPilot&&(index===2||index===3)))?0:index;
@ -141,9 +147,20 @@ export default {
this.oldScrollTop = e.detail.scrollTop;
},
//
refresh(){
this.changeCurrent(this.current);
async refresh(){
if (this._freshing) return;
this._freshing = true;
await this.changeCurrent(this.current);
this.triggered = false;
this._freshing = false;
},
//
onPulling(e) {
if (e.detail.deltaY < 0) {
return;
}
this.triggered = true;
}
}
}
</script>

View File

@ -8,18 +8,19 @@
<script>
import configService from '@/common/config.service.js';
import Topnav from '@/components/topnav/index.vue';
export default {
// #ifdef MP
options: {
styleIsolation: 'shared'
},
// #endif
components: { Topnav },
data() {
return {
// #ifdef MP
//
StatusBar: this.StatusBar || 0,
CustomBarHeight: this.Custom.height+(this.Custom.top-this.StatusBar)*2 || 0,
CustomBar: this.CustomBar || 0,
// #endif
loading: true, //
}

View File

@ -1,14 +1,20 @@
<template>
<view class="order-add">
<Topnav :topLevel="1" title="新增订单" defaultBackColor="#333333"
<Topnav :topLevel="1" :title="`${form.orderId?'编辑':'新增'}订单`" defaultBackColor="#333333"
defaultNavTextColor="#333333" showBack :fixed="false" />
<view class="order-form">
<view class="order-field">
<u-form ref="uForm" :model="form" label-position="top"
:label-style="{fontFamily: 'PingFang SC, PingFang SC',
fontWeight: 'bold',fontSize: '32rpx',color: '#000000'}">
<u-form-item v-if="form.orderId" label="订单号:" :border-bottom="false">
<u-input disabled class="field-ninput" placeholder="订单号" v-model="form.orderNo" />
</u-form-item>
<u-form-item label="订单类型:" :border-bottom="false">
<u-input class="field-input" placeholder="请选择订单类型" v-model="form.orderTypeName" type="select" disabled/>
<u-input style="opacity: 0.8;" class="field-input" placeholder="请选择订单类型" v-model="form.orderTypeName" type="select" disabled/>
</u-form-item>
<u-form-item v-if="form.orderId" label="订单发起人:" :border-bottom="false">
<u-input disabled class="field-ninput" placeholder="订单发起人" v-model="form.orderInitiator" />
</u-form-item>
<u-form-item prop="customerName" required label="客户名称:" :border-bottom="false">
<u-input class="field-input" placeholder="请选择客户" v-model="form.customerName"
@ -26,7 +32,7 @@
<!-- <u-input class="field-input" placeholder="请选择路线" v-model="form.routeIds"
type="select"/> -->
<w-select class="field-w-select" v-model="form.routeIds" multiple
:list="routes" valueName="content" keyName="id" @change="changeRoute"
:list="routes" valueName="value" keyName="key" @change="changeRoute"
placeholder="请选择路线" width="100%" bgColor="#f8f9fb">
</w-select>
</u-form-item>
@ -38,6 +44,25 @@
<u-input type="number" class="field-ninput" placeholder="请输入附加费(最多保留两位小数)" v-model.number="form.surchargeAmount" />
<view slot="right" class="field-input-right"></view>
</u-form-item>
<u-form-item prop="operatorIds" label="操作员:" required :border-bottom="false">
<w-select class="field-w-select" v-model="form.operatorIds" multiple
:list="operators" valueName="content" keyName="id"
placeholder="请选择操作员" width="100%" bgColor="#f8f9fb">
</w-select>
</u-form-item>
<u-form-item v-if="form.orderId" label="下单时间:" :border-bottom="false">
<u-input disabled class="field-ninput" placeholder="下单时间" v-model="form.orderCreateTime" />
</u-form-item>
<u-form-item v-if="form.orderId" label="订单确认人:" :border-bottom="false">
<u-input disabled class="field-ninput" placeholder="订单确认人" v-model="form.orderCreateTime" />
</u-form-item>
<view class="field-btns">
<u-button type="warning" :custom-style="customStyle" style="width: 100%;"
:hair-line="false" @click="saveOrder">保存</u-button>
<u-button style="margin-left: 30rpx;width: 100%;" type="warning" v-if="form.orderId"
:custom-style="customStyle"
:hair-line="false" @click="finishOrder">完成订单</u-button>
</view>
</u-form>
</view>
</view>
@ -67,6 +92,7 @@ export default {
// #endif
//
form:{
orderId: '',
orderType: 1,
orderTypeName: '载物订单',
customerName: '',
@ -76,7 +102,7 @@ export default {
attractionId: '',
surchargeAmount:'',
cargoWeight: '',
operatorIds: '',
operatorIds: [],
routeIds: []
},
//
@ -126,27 +152,61 @@ export default {
// blurchange
trigger: ['change','blur'],
}],
routeIds: [{
require: true,
message: '请至少选择一条路线',
trigger: ['change','blur']
},
{
//
validator: (rule, value, callback) => {
return value&&value.length>0;
},
message: '请至少选择一条路线',
// blurchange
trigger: ['change','blur'],
}],
operatorIds: [{
require: true,
message: '请至少选择一位操作员',
trigger: ['change','blur']
},
{
//
validator: (rule, value, callback) => {
return value&&value.length>0;
},
message: '请至少选择一位操作员',
// blurchange
trigger: ['change','blur'],
}],
},
//
customStyle: {
backgroundColor: '#FEE547',
color: '#333333',
fontSize: '30rpx',
fontWeight: 'bold',
fontFamily: 'Source Han Sans SC',
padding: '20rpx 0',
borderRadius: '12rpx',
border: 'none'
},
//
scenics: [],
//
customers: [],
//
operators: [],
// 线
routes: [{
id: 1,
content: "张三",
},
{
id: 2,
content: "李四",
},],
routes: [],
//
userMessage: this.$store.state.vuex_token === ''?{}:JSON.parse(this.$store.state.user_message),
isPilot: this.$store.state.user_type == 1,
// /
showScenOrCus: false,
// /
scenOrCusType: ''
scenOrCusType: '',
}
},
onReady() {
@ -161,6 +221,9 @@ export default {
return index?[arr.findIndex(item=>item.id === index)]:[0];
}
},
onLoad(e) {
this.form.orderId = e.id || '';
},
created() {
this.$nextTick(()=>{
this.init();
@ -169,25 +232,25 @@ export default {
methods: {
//
async init(){
let res = await this.$api.allCustomers();
let resp = await this.$api.aSelfDetail(this.userMessage.id);
if(!res){
let cusRes = await this.$api.allCustomers();
// let opeRes = await this.$api.all
let selfRes = await this.$api.aSelfDetail(this.userMessage.id);
if(!cusRes){
this.$refs.uToast.show({type: 'error',title: "客户获取失败!"});
}else{
this.customers = res || [];
this.customers = cusRes || [];
}
if(!resp){
if(!selfRes){
this.$refs.uToast.show({type: 'error',title: "个人信息获取失败!"});
}else{
if(resp.areaId){
let resx = await this.$api.allScenicsByAreaId({areaId: resp.areaId});
this.scenics = resx || [];
if(selfRes.areaId){
let scenRes = await this.$api.allScenicsByAreaId({areaId: selfRes.areaId});
this.scenics = scenRes || [];
}
}
},
// 线
changeRoute(e){
console.log(this.form.routeIds);
},
// /
handleSelectScenOrCus(type){
@ -195,18 +258,49 @@ export default {
this.showScenOrCus = true;
},
//
handleConfirmScenOrCus(index){
async handleConfirmScenOrCus(index){
if(this.scenOrCusType === '景区'){
const val = this.scenics[index[0]];
this.form.attractionName = val.name;
this.form.attractionId = val.id;
this.form.routeIds = [];
let res = await this.$api.allRoutesByScenicId(val.id);
if(res){
this.routes = res || [];
}else{
this.$refs.uToast.show({type: 'error',title: "景区路线获取失败!"});
}
}else{
const val = this.customers[index[0]];
this.form.customerId = val.id;
this.form.customerName = val.name;
this.form.phone = val.phone;
}
},
//
saveOrder(){
this.$refs.uForm.validate(valid => {
if (valid) {
console.log('验证通过');
}
});
},
//
async finishOrder(){
let that = this;
uni.showModal({
title: '订单完成',
content: '是否确认完成该订单?',
confirmColor: '#f7c04d',
success: async(res) => {
if (res.confirm) {
let res = await that.$api.completeOrder(that.form.orderId);
that.$refs.uToast.show({type: res?'success':'error',
title: `订单完成操作${res?'成功':'失败'}!`});
}
}
})
},
}
}
</script>
@ -275,6 +369,14 @@ export default {
margin-left: -80rpx;
z-index: 1;
}
.field-btns{
width: 100%;
margin-top: auto;
margin-bottom: 30rpx;
padding-top: 30rpx;
display: flex;
align-items: center;
}
}
}
}

View File

@ -6,8 +6,8 @@
<view class="order-top">
<u-image width="100%" :src="myFileUrl+topBg" mode="widthFix" />
<view class="top-abs" :style="{top: CustomBar+'px'}">
<view class="order-status">待接单</view>
<view class="order-tips">请尽快执行任务</view>
<view class="order-status">{{ orderDetail.mainOrderStatus }}</view>
<view class="order-tips">{{ orderDetail.mainOrderStatus === '已完成' ? '已完成飞行任务' : '请尽快执行任务'}}</view>
</view>
</view>
<view class="order-content">
@ -20,23 +20,23 @@
<view class="message-content">
<view class="mc-lam">
<text class="lam-title">订单类型</text>
<text class="lam-value">载人</text>
<text class="lam-value">{{ orderDetail.orderType.slice(0, 2) }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">景区</text>
<text class="lam-value">白云山</text>
<text class="lam-value">{{ orderDetail.scenicName }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">路线</text>
<text class="lam-value">南门山顶广场</text>
<text class="lam-value">{{ orderDetail.routeName }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">货物重量</text>
<text class="lam-value">56 KG</text>
<text class="lam-value">{{ orderDetail.cargoWeight }} KG</text>
</view>
<view class="mc-lam">
<text class="lam-title">附加费</text>
<text class="lam-value"><text>100</text></text>
<text class="lam-value"><text>{{ orderDetail.surchargeAmount }}</text></text>
</view>
</view>
</view>
@ -49,23 +49,23 @@
<view class="message-content">
<view class="mc-lam">
<text class="lam-title">发起人</text>
<text class="lam-value">李晓霞</text>
<text class="lam-value">{{ orderDetail.orderInitiator }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">客户名称</text>
<text class="lam-value">李晓霞</text>
<text class="lam-value">{{ orderDetail.customerName }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">手机号</text>
<text class="lam-value">13624566325</text>
<text class="lam-value">{{ orderDetail.phone }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">操作员</text>
<text class="lam-value">陈新生</text>
<text class="lam-value">{{ orderDetail.operatorName }}</text>
</view>
<view class="mc-lam">
<text class="lam-title">下单时间</text>
<text class="lam-value">2025-07-06 14:02:08</text>
<text class="lam-value">{{ orderDetail.orderCreateTime }}</text>
</view>
</view>
</view>
@ -75,7 +75,29 @@
<u-image class="text-bg" width="148" height="28"
:src="fileUrl+textBg" />
</view>
<view class="message-empty">
<view class="fly-message-content" v-if="orderDetail.orderTaskDetailList&&orderDetail.orderTaskDetailList.length>0"
:style="{backgroundImage: `url(${fileUrl+mask})`}" v-for="(item, index) in orderDetail.orderTaskDetailList"
:key="index">
<view class="action-detail">
<u-image border-radius="20" width="140" height="140" :src="orderDetail.attachmentMaterialList[0].fileFullPath||(fileUrl+defaultIcon)" class="action-detail-photo" />
<view class="action-detail-content">
<view class="action-device">{{ item.deviceName }}</view>
<view>重量: {{ item.cargoWeight }}KG</view>
<view class="action-operator">操作员: {{ item.operatorName }}</view>
</view>
<view class="action-detail-status" :style="{color: item.orderItemStatus==='未进行'?'#F8B500':'#666666'}">
{{ item.orderItemStatus }}
</view>
</view>
<view class="action-btns" v-if="orderDetail.mainOrderStatus!=='已完成'">
<u-button :custom-style="deleteCustomStyle" style="margin-left: auto;"
:hair-line="false" @click="handleDeleteAction(item)">删除</u-button>
<u-button type="warning" :custom-style="customStyle" style="margin-left: 20rpx;margin-right: 30rpx;"
:hair-line="false" @click="handleChangeAction(item)">更改状态</u-button>
</view>
<view class="action-btns" v-else />
</view>
<view class="message-empty" v-else>
<u-image width="200rpx" height="130rpx" :src="fileUrl+empty" />
<view class="empty-text">
~暂无任务~
@ -83,7 +105,7 @@
</view>
</view>
</view>
<view class="order-bottom">
<view class="order-bottom" v-if="orderDetail.mainOrderStatus !== '已完成'">
<view class="add-action" @click="showAddAction=true">
新增任务
</view>
@ -174,6 +196,7 @@
:iconStyle="{ color: '#fff' }" :customStyle="{background: 'linear-gradient(180deg, #f8b500 0%, #fceabb 100%)',
boxShadow: '0rpx 0rpx 12rpx rgba(202,202,182,0.5)',
filter: 'opacity(0.96)'}"></u-back-top>
<u-toast ref="uToast"></u-toast>
</view>
</template>
@ -206,6 +229,29 @@ export default {
uploadFileHeader: {
'Authorization':this.$store.state.vuex_token,
},
//
customStyle: {
backgroundColor: '#FEE547',
color: '#333333',
fontSize: '30rpx',
fontWeight: 'bold',
fontFamily: 'Source Han Sans SC',
width: '160rpx',
height: '72rpx',
borderRadius: '12rpx',
border: 'none'
},
deleteCustomStyle:{
backgroundColor: '#FFFFFF',
color: '#333333',
fontSize: '30rpx',
fontWeight: 'bold',
fontFamily: 'Source Han Sans SC',
width: '160rpx',
height: '70rpx',
borderRadius: '10rpx',
border: '2rpx solid #999999'
},
//
fileList: [],
//
@ -224,6 +270,10 @@ export default {
closeIcon: 'close.png',
//
uploadIcon: 'upload.png',
//
mask: 'mask.png',
//
defaultIcon: 'default.png',
//
topLevel: 0,
//
@ -241,8 +291,10 @@ export default {
weight: '',
photo: ''
},
//
orderDetail: {},
//
current: 0
current: 0,
}
},
onPageScroll(e) {
@ -251,7 +303,17 @@ export default {
else this.topLevel = 1;
this.scrollTop = e.scrollTop;
},
onLoad(e) {
this.init(e.id);
},
methods:{
//
async init(id){
if(!id) return;
let res = await this.$api.orderDetail(id);
if(res) this.orderDetail = res;
else this.$refs.uToast.show({type: 'error',title: "订单详情获取失败!"});
},
//
handleClickPick(){
this.showEquipment = true;
@ -277,6 +339,14 @@ export default {
this.current = 0;
}
this.current += 1;
},
//
handleDeleteAction(item){
},
//
handleChangeAction(item){
}
}
}
@ -339,6 +409,54 @@ export default {
margin-top: 24rpx;
}
}
&-content{
background-size: contain;
margin-top: 16rpx;
background-repeat: no-repeat;
// background: linear-gradient(0deg, #FFF6BD, #FFFDF1);
background-color: #FFFFFF;
box-shadow: 0rpx 6rpx 10rpx 0rpx rgba(200,199,193,0.3);
border-radius: 16rpx;
margin-bottom: 26rpx;
.action-detail{
margin: 40rpx 20rpx 0;
display: flex;
&-photo{
margin-right: 20rpx;
}
&-content{
flex: 1;
display: flex;
flex-direction: column;
font-family: Source Han Sans SC;
font-weight: 400;
font-size: 28rpx;
color: #666666;
.action-device{
font-weight: bold;
font-size: 32rpx;
color: #333333;
margin-bottom: 16rpx;
}
.action-operator{
margin-top: 12rpx;
}
}
&-status{
font-family: Source Han Sans SC;
font-weight: 500;
font-size: 28rpx;
color: #F8B500;
margin-right: 10rpx;
}
}
.action-btns{
margin-top: 18rpx;
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
}
.message-empty{
margin-top: 16rpx;
padding: 90rpx 30rpx;

View File

@ -3,14 +3,14 @@
<Topnav :topLevel="topLevel" title="爱尚云" />
<u-image width="100%" :src="fileUrl+banner" mode="widthFix" />
<view class="order-list">
<view class="order-item" v-for="(item,index) in orders" :key="index">
<view class="order-item" v-for="(item,index) in orders" :key="index" @click="showDetail(item)">
<view class="item-first">
<view class="item-status">{{ item.mainOrderStatus }}</view>
<view class="item-type">订单类型<text>{{ item.orderType }}</text></view>
<view class="item-status">{{ orderStatus[item.mainOrderStatus] }}</view>
<view class="item-type">订单类型<text>{{ orderTypes[item.orderType] }}</text></view>
</view>
<view class="item-second">
<view class="item-spot">
<view class="item-dot"/>景区{{ item.attractionId }}
<view class="item-dot"/>景区{{ scenics[item.attractionId] }}
</view>
<view class="item-route">
<view class="item-dot"/>路线{{ item.routeName }}
@ -19,19 +19,20 @@
<view class="item-third">
<view class="item-identity">
<u-image class="item-avatar" width="80rpx" height="80rpx"
:src="fileUrl+(item.gender === 0 ? boyIcon : girlIcon)" />
:src="fileUrl+(customers[item.customerId].gender === '男' ? boyIcon : girlIcon)" />
<view class="item-self">
<text class="item-name">{{ item.customerName }}</text>
<text class="item-name">{{ customers[item.customerId].name }}</text>
<text class="item-phone">{{ item.customerPhone }}</text>
</view>
</view>
<view class="item-active">
<u-button type="warning" :custom-style="customStyle"
:hair-line="false" @click="handleDoAction(item)">执行任务</u-button>
:hair-line="false" @click.stop="handleDoAction(item)">执行任务</u-button>
</view>
</view>
</view>
<view class="order-empty" v-if="orders.length===0">
<u-loadmore v-if="orders.length>0" @loadmore="getMore" :status="form.isFinish" color="#333333" marginTop="30" marginBottom="20" />
<view class="order-empty" v-else>
<u-empty text="订单为空" mode="list"
src="/static/empty.png" icon-size="300" font-size="40"
margin-top="250"></u-empty>
@ -70,44 +71,20 @@ export default {
girlIcon: 'girl.png',
//
boyIcon: 'boy.png',
//
orderStatus: {
0:'未进行',
1:'进行中',
2:'已完成',
3:'已取消'
},
//
orderTypes: {
1: '载物',
2: '载人'
},
//
orders: [{
id: 1,
mainOrderStatus: '待接单',
orderType: '载物',
attractionId: '白云山',
customerPhone: '13624566325',
routeName: '南门→山顶广场',
gender: 1,
customerName: '李晓霞'
},{
id: 2,
mainOrderStatus: '待接单',
orderType: '载人',
attractionId: '白云山',
customerPhone: '13624566325',
routeName: '南门→山顶广场',
gender: 0,
customerName: '李道明'
},{
id: 3,
mainOrderStatus: '待接单',
orderType: '载物',
attractionId: '白云山',
customerPhone: '13624566325',
routeName: '南门→山顶广场',
gender: 1,
customerName: '李晓霞'
},{
id: 4,
mainOrderStatus: '待接单',
orderType: '载物',
attractionId: '白云山',
customerPhone: '13624566325',
routeName: '南门→山顶广场',
gender: 1,
customerName: '李晓霞'
}],
orders: [],
//
customStyle: {
backgroundColor: '#FEE547',
@ -119,20 +96,76 @@ export default {
height: '72rpx',
borderRadius: '12rpx',
border: 'none'
},
//
userMessage: this.$store.state.vuex_token === ''?{}:JSON.parse(this.$store.state.user_message),
//
form:{
current: 1,
size: 10,
// loadmoreloadingnomore
isFinish: 'nomore',
},
//
customers: {},
//
scenics: {}
}
}
},
onLoad() {
this.$nextTick(()=>{
this.init();
})
},
methods:{
//
async init(){
this.form = {size: 10,current: 1,isFinish: 'nomore'};
//
await this.getOrderList();
//
let cusRes = await this.$api.allCustomers();
if(!cusRes){
this.$refs.uToast.show({type: 'error',title: "客户获取失败!"});
}else this.customers = await cusRes.reduce((obj, item) => ({...obj,[item.id]: item}), {})||{};
//
let scenRes = await this.$api.allScenic();
if(!scenRes)
this.$refs.uToast.show({type: 'error',title: "景区列表获取失败!"});
else this.scenics = await scenRes.reduce((obj, item) => ({...obj,[item.id]: item.name}), {})||{};
},
//
async getOrderList(){
this.form.isFinish = 'loading';
let ordRes = await this.$api.getOrders(this.form);
if(ordRes){
const { records, size, total, current } = ordRes;
if(current === 1) this.orders = records || [];
else this.orders.push(...records);
this.form.isFinish = size*current >= total ? 'nomore' : 'loadmore';
}else{
this.$refs.uToast.show({type:'error',title: "订单列表获取失败!"});
this.form.isFinish = 'loadmore';
}
},
//
getMore(){
if(this.form.isFinish === 'nomore') return;
this.form.current++;
this.getOrderList();
},
//
handleDoAction(item){
uni.navigateTo({
url: `/aircraft/server/order/detail?id=${item.id}`
})
}
},
//
showDetail(item){
uni.navigateTo({
url: `/aircraft/server/order/add?id=${item.id}`
})
},
}
}
</script>

View File

@ -11,9 +11,17 @@ const install = (Vue, vm) => {
vm.$api.aUpdatePass = async (params = {}) => await vm.$u.post(`/api/emEmployees/updatePass`,params);// 修改飞行员密码
vm.$api.bUpdatePass = async (params = {}) => await vm.$u.post(`/cnCustomer/updatePass`,params);// 修改客户密码
// 区域管理
// 区域/景区管理
vm.$api.allAreas = async () => await vm.$u.get('/emArea/all');// 获取全部区域
vm.$api.allScenicsByAreaId = async (params = {}) => await vm.$u.get('/emScenic/all',params);// 获取区域下全部景区
vm.$api.allRoutesByScenicId = async (scenicId) => await vm.$u.get(`/api/dataDropdown/obtainRouteListByScenicId/${scenicId}`);// 根据景区获取对应的线路
vm.$api.allScenic = async () => await vm.$u.get('/emScenic/all');// 获取全部景区
vm.$api.singleScenic = async (id) => await vm.$u.get(`/emScenic/${id}`);// 查询单个景区
// 订单管理
vm.$api.completeOrder = async (orderId) => await vm.$u.get(`/api/order/completeOrder/${orderId}`);// 完成订单
vm.$api.getOrders = async (params = {}) => await vm.$u.get('/api/order/allOrder',params);// 获取订单列表
vm.$api.orderDetail = async (id) => await vm.$u.get(`/api/order/queryOrderDetail/${id}`);// 查询单个订单
// 客户管理
vm.$api.allCustomers = async () => await vm.$u.get('/cnCustomer/all');// 获取全部客户