移除无用文件
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
import { request } from './request';
|
||||
|
||||
|
||||
|
||||
// 获取配置
|
||||
export function fetchGetConfig() {
|
||||
return request({
|
||||
url: '/config/get', // id : number
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置配置
|
||||
export function fetchSetConfig(data : {}) {
|
||||
return request({
|
||||
url: '/config/set',
|
||||
data: data,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
// 设置价格规则
|
||||
export function fetchSetPriceRules(data : {}) {
|
||||
return request({
|
||||
url: '/config/setPriceRules',
|
||||
data: data,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取价格规则
|
||||
export function fetchGetPriceRules() {
|
||||
return request({
|
||||
url: '/config/getPriceRules', // id : number
|
||||
});
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
import { request } from "./request";
|
||||
// import { EditGoodsParams } from "../types/contorl";
|
||||
|
||||
|
||||
// 根据串号搜索列表
|
||||
export function fetchGoodsListByGoodsNo(goods_no: string) {
|
||||
return request({
|
||||
url: '/store.control/goodsListByGoodsNo',
|
||||
data: {
|
||||
goods_no: goods_no,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑商品
|
||||
export function fetchControlEditGoods(form:{}) {
|
||||
return request({
|
||||
url: '/store.control/editGoods',
|
||||
data: form,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 工作台商品详情
|
||||
export function fetchControlGoodsDetail(id:number) {
|
||||
return request({
|
||||
url: '/store.control/goodsDetail',
|
||||
data: {id:id}
|
||||
})
|
||||
}
|
||||
|
||||
// // 获取配件详情
|
||||
// export function fetchControlPartsGoodsDetail(id:number) {
|
||||
// return request({
|
||||
// url: '/parts.goods/detail',
|
||||
// data: {id:id}
|
||||
// })
|
||||
// }
|
||||
// // 获取配件所属机型-机型选项
|
||||
// export function fetchControlPartsProducts() {
|
||||
// return request({
|
||||
// url: '/parts.goods/products',
|
||||
// // data: {id:id}
|
||||
// })
|
||||
// }
|
||||
// // 获取配件所属分类-分类选项
|
||||
// export function fetchControlPartsTypes() {
|
||||
// return request({
|
||||
// url: '/parts.goods/types',
|
||||
// // data: {id:id}
|
||||
// })
|
||||
// }
|
||||
// // 获取配件所属分类的子类
|
||||
// export function fetchControlPartsDegree(id:number) {
|
||||
// return request({
|
||||
// url: '/parts.goods/filterDegree',
|
||||
// data: {type_id:id}
|
||||
// })
|
||||
// }
|
||||
|
||||
// // 根据 分类 子类 机型 筛选配件
|
||||
// export function fetchControlPartsFilterGoods(params: {type_id: number;product_id?: number;degree_id?: number;}) {
|
||||
// // 验证必填参数
|
||||
// if (params.type_id === undefined || params.type_id === null) {
|
||||
// return Promise.reject(new Error('type_id 是必填参数'));
|
||||
// }
|
||||
// // 构建请求数据,只包含有值的字段
|
||||
// const requestData: Record<string, any> = {
|
||||
// type_id: params.type_id
|
||||
// };
|
||||
// if (params.product_id !== undefined && params.product_id !== null) {
|
||||
// requestData.product_id = params.product_id;
|
||||
// }
|
||||
// if (params.degree_id !== undefined && params.degree_id !== null) {
|
||||
// requestData.degree_id = params.degree_id;
|
||||
// }
|
||||
// return request({
|
||||
// url: '/parts.goods/filterGoods',
|
||||
// data: requestData
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// // 配件工作台-修改配件
|
||||
// export function editGoods(params:EditGoodsParams) {
|
||||
// return request({
|
||||
// url: '/parts.goods/editGoods',
|
||||
// data: params,
|
||||
// method: 'POST'
|
||||
// })
|
||||
// }
|
||||
60
api/goods.ts
60
api/goods.ts
@@ -1,60 +0,0 @@
|
||||
import { request } from './request';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 编辑商品
|
||||
export function fetchGoodsEdit(form:{}) {
|
||||
return request({
|
||||
url: '/goods/edit',
|
||||
data: form,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 商品详情
|
||||
export function fetchGoodsDetail(id:number) {
|
||||
return request({
|
||||
url: '/goods/detail',
|
||||
data: {goods_id:id}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 新增商品
|
||||
export function fetchGoodsAdd(form:{}) {
|
||||
return request({
|
||||
url: '/goods/add',
|
||||
data: form,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 筛选
|
||||
export function fetchFilterParmas(is_origin : number = 0) {
|
||||
return request({
|
||||
url: '/goods/filterParams',
|
||||
data: {
|
||||
is_origin: is_origin
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 首页机器列表
|
||||
export function fetchGoodsList(data : {}) {
|
||||
return request({
|
||||
url: '/goods/lists',
|
||||
data: data,
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
import { request } from './request';
|
||||
import { houseRequest } from './house_request';
|
||||
|
||||
// 仓库筛选
|
||||
export function houseFetchFilterParmas(is_origin : number = 0) {
|
||||
return houseRequest({
|
||||
url: '/store.goods/filterParams',
|
||||
data: {
|
||||
is_origin: is_origin
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export interface goodsListParams {
|
||||
page ?: string;
|
||||
pageSize ?: string;
|
||||
price_sort ?: string;
|
||||
degree_ids ?: string[]; // 新增的 ID 数组字段(假设是字符串数组)
|
||||
product_ids ?: string[];
|
||||
search ?: string;
|
||||
type_id ?: number;
|
||||
brand_id ?: number;
|
||||
[property : string] : any;
|
||||
}
|
||||
|
||||
|
||||
// 仓库机器列表
|
||||
export function houseFetchGoodsList(filter : goodsListParams) {
|
||||
return houseRequest({
|
||||
url: '/store.goods/lists',
|
||||
data: filter,
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 仓库商品详情
|
||||
export function houseFetchGoodsDetail(id : number) {
|
||||
return houseRequest({
|
||||
url: '/store.goods/detail',
|
||||
data: { id: id },
|
||||
});
|
||||
}
|
||||
|
||||
// 获取购物车商品列表
|
||||
export function houseFetchCartGoodsIds() {
|
||||
return houseRequest({
|
||||
url: '/store.goods/cartGoodsIds',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 检测报告树
|
||||
export function fetchGoodsReportTags () {
|
||||
return houseRequest({
|
||||
url:'/store.goods/reportTags',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 添加购物车
|
||||
export function fetchAddCart(goods_id : number) {
|
||||
return request({
|
||||
url: '/store.goods/addCart',
|
||||
data: { goods_id: goods_id },
|
||||
});
|
||||
}
|
||||
|
||||
// 删除购物车
|
||||
export function fetchDelCart(goods_id : number) {
|
||||
return request({
|
||||
url: '/store.goods/delCart',
|
||||
data: { goods_id: goods_id },
|
||||
});
|
||||
}
|
||||
|
||||
// 获取购物车商品
|
||||
export function fetchCartList() {
|
||||
return request({
|
||||
url: '/store.goods/cartList',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// export interface PartsListParams {
|
||||
// /**
|
||||
// * 子类id
|
||||
// */
|
||||
// degree_id ?: string;
|
||||
// page ?: string;
|
||||
// pageSize ?: string;
|
||||
// /**
|
||||
// * 配件机型id
|
||||
// */
|
||||
// product_id ?: string;
|
||||
// /**
|
||||
// * 配件id
|
||||
// */
|
||||
// type_id ?: string;
|
||||
// [property : string] : any;
|
||||
// }
|
||||
// export function fetcPartsList(filter : PartsListParams) {
|
||||
// return request({
|
||||
// url: '/parts.goods/filtergoodslist',
|
||||
// data: filter,
|
||||
// method: 'POST',
|
||||
// });
|
||||
// }
|
||||
|
||||
// export function fetchPartsDetail(id: number) {
|
||||
// return request({
|
||||
// url: '/goods/detail',
|
||||
// data: { id: id },
|
||||
// });
|
||||
// }
|
||||
|
||||
// export function addPartsCart(goods_id : number) {
|
||||
// return request({
|
||||
// url: '/parts.cart/addCart',
|
||||
// data: { goods_id },
|
||||
// });
|
||||
// }
|
||||
// export function incPartsCartNum(goods_id : number) {
|
||||
// return request({
|
||||
// url: '/parts.cart/incNum',
|
||||
// data: { goods_id },
|
||||
// });
|
||||
// }
|
||||
// export function decPartsCartNum(goods_id : number) {
|
||||
// return request({
|
||||
// url: '/parts.cart/decNum',
|
||||
// data: { goods_id },
|
||||
// });
|
||||
// }
|
||||
// export function setPartsCartNum(goods_id : number, quantity : number) {
|
||||
// return request({
|
||||
// url: '/parts.cart/setNum',
|
||||
// data: { goods_id, quantity },
|
||||
// });
|
||||
// }
|
||||
|
||||
// export function delPartsCart(goods_id : number) {
|
||||
// return request({
|
||||
// url: '/parts.cart/delCart',
|
||||
// data: { goods_id },
|
||||
// });
|
||||
// }
|
||||
// export function fetchPartsCartList() {
|
||||
// return request({
|
||||
// url: '/parts.cart/cartList',
|
||||
// });
|
||||
// }
|
||||
@@ -1,183 +0,0 @@
|
||||
import config from '@/config';
|
||||
|
||||
import { houseRequest } from "./house_request";
|
||||
|
||||
// 保存远程收货地址
|
||||
export function houseFetchUpdateAddress(form : {}) {
|
||||
// 设置默认参数
|
||||
const defaultParams = {
|
||||
agent_id: config.wxapp_id,
|
||||
address: {},
|
||||
};
|
||||
console.log(defaultParams);
|
||||
console.log(form);
|
||||
const requestParams = {
|
||||
...defaultParams,
|
||||
...form
|
||||
};
|
||||
return houseRequest({
|
||||
url: '/store.api/updateAddress',
|
||||
data: requestParams,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 仓库商品状态校验
|
||||
export function houseFetchCheckGoods(form : {}) {
|
||||
// 设置默认参数
|
||||
const defaultParams = {
|
||||
agent_id: config.wxapp_id,
|
||||
goods_id: 0,
|
||||
};
|
||||
console.log(defaultParams);
|
||||
console.log(form);
|
||||
const requestParams = {
|
||||
...defaultParams,
|
||||
...form
|
||||
};
|
||||
return houseRequest({
|
||||
url: '/store.api/checkGoods',
|
||||
data: requestParams,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 仓库订单预览
|
||||
export function houseFetchGoodsPreview(form : {}) {
|
||||
// 设置默认参数
|
||||
const defaultParams = {
|
||||
agent_id: config.wxapp_id,
|
||||
goods_id: 0,
|
||||
};
|
||||
console.log(defaultParams);
|
||||
console.log(form);
|
||||
const requestParams = {
|
||||
...defaultParams,
|
||||
...form
|
||||
};
|
||||
return houseRequest({
|
||||
url: '/store.api/preview',
|
||||
data: requestParams,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 订单下单
|
||||
export function fetchOrderbuyNow(data : {}) {
|
||||
return houseRequest({
|
||||
url: '/order/buyNow',
|
||||
data: data,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // 订单详情
|
||||
// export function fetchOrderDetail(id : Number) {
|
||||
// return request({
|
||||
// url: '/order/detail',
|
||||
// data: { id: id },
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // 订单统计
|
||||
// export function fetchOrderTotalCount() {
|
||||
// return request({
|
||||
// url: '/order/totalCount'
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // 获取订单列表
|
||||
// interface orderListParams {
|
||||
// page ?: number;
|
||||
// pageSize ?: number;
|
||||
// status ?: 'all' | 'payment' | 'delivery' | 'received' | 'finish';
|
||||
// goods_no ?: string;
|
||||
// [key : string] : any; // 允许其他扩展参数
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 获取订单列表
|
||||
// * @param params 请求参数对象
|
||||
// * @returns Promise
|
||||
// */
|
||||
// export function fetchOrderList(params : orderListParams = {}) {
|
||||
// // 设置默认参数
|
||||
// const defaultParams = {
|
||||
// page: 1,
|
||||
// pageSize: 10,
|
||||
// status: 'all',
|
||||
// goods_no: '',
|
||||
// };
|
||||
|
||||
// const requestParams = {
|
||||
// ...defaultParams,
|
||||
// ...params
|
||||
// };
|
||||
// return request({
|
||||
// url: '/order/getList',
|
||||
// method: 'GET', // 或 'POST' 根据实际需求
|
||||
// data: requestParams
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // 取消订单
|
||||
// export function fetchCancelOrder(id : Number) {
|
||||
// return request({
|
||||
// url: '/order/cancel',
|
||||
// data: { id: id },
|
||||
// })
|
||||
// }
|
||||
|
||||
// // 标记付款
|
||||
// export function fetchPayOrder(id : Number) {
|
||||
// return request({
|
||||
// url: '/order/paid',
|
||||
// data: { id: id },
|
||||
// })
|
||||
// }
|
||||
|
||||
// // 标记发货
|
||||
// export function fetchDeliveryOrder(form : {}) {
|
||||
// return request({
|
||||
// url: '/order/delivery',
|
||||
// data: form,
|
||||
// method: 'POST'
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// // 确认收货
|
||||
// export function fetchReceiptOrder(id : Number) {
|
||||
// return request({
|
||||
// url: '/order/receipt',
|
||||
// data: { id: id },
|
||||
// })
|
||||
// }
|
||||
@@ -1,100 +0,0 @@
|
||||
// 针对仓库的Api接口
|
||||
|
||||
|
||||
|
||||
import config from '@/config';
|
||||
import { goToLoginPage } from '@/utils/helper';
|
||||
|
||||
// 定义请求参数接口
|
||||
interface Options {
|
||||
url : string; // 请求路径(不包含基础URL)
|
||||
method ?: 'GET' | 'POST'; // 请求方法,默认为GET
|
||||
data ?: any; // POST请求体数据
|
||||
params ?: any; // GET请求参数(与data二选一)
|
||||
dataType ?: string; // 返回数据格式,默认json
|
||||
responseType ?: string; // 响应数据类型,默认text
|
||||
}
|
||||
|
||||
// 定义响应数据结构接口
|
||||
interface Response {
|
||||
code : number;
|
||||
msg ?: string;
|
||||
data : any;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 获取图片上传的完整URL
|
||||
// * @returns {string} 完整的图片上传URL,包含基础URL、wxapp_id和token参数
|
||||
// */
|
||||
// export const getUploadImageUrl = () => {
|
||||
// return config.api_base_url + '/store.upload/image' + '&wxapp_id=10001&token=' + uni.getStorageSync('token');
|
||||
// };
|
||||
|
||||
/**
|
||||
* 封装uni.request的通用请求方法
|
||||
* @param {Options} options 请求配置项
|
||||
* @returns {Promise} 返回Promise对象
|
||||
*
|
||||
* 功能说明:
|
||||
* 1. 自动拼接基础URL和认证参数
|
||||
* 2. 统一处理登录状态(code=-1跳转登录页)
|
||||
* 3. 统一处理错误提示(code=0显示Toast)
|
||||
* 4. 成功时返回data字段(code=1)
|
||||
*/
|
||||
export const houseRequest = (options : Options) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
// 拼接完整请求URL(基础URL + 路径 + 固定参数)
|
||||
url: config.house_api_base_url + options.url + '&wxapp_id=10001&token=' + uni.getStorageSync('token'),
|
||||
|
||||
method: options.method || 'GET', // 默认GET方法
|
||||
data: options.data || options.params || {}, // 兼容data/params传参
|
||||
dataType: options.dataType || 'json', // 默认json格式
|
||||
responseType: options.responseType || 'text', // 默认text类型
|
||||
|
||||
// 请求成功回调
|
||||
success(res) {
|
||||
const ret : Response = res.data;
|
||||
// console.log(ret);
|
||||
|
||||
// 状态码处理
|
||||
switch (ret.code) {
|
||||
case -1: // 未登录状态
|
||||
goToLoginPage();
|
||||
break;
|
||||
case 1: // 成功状态
|
||||
// console.log(options.url);
|
||||
// if (options.url === '/parts.order/preview') {
|
||||
// console.log('ressss', ret);
|
||||
// resolve(ret);
|
||||
// break;
|
||||
// }
|
||||
resolve(ret.data); // 返回data字段
|
||||
break;
|
||||
case 0: // 失败状态
|
||||
// console.log(options.url);
|
||||
// if (options.url === '/parts.order/preview') {
|
||||
// console.log('ressss', ret);
|
||||
// resolve(ret);
|
||||
// break;
|
||||
// }
|
||||
uni.showToast({
|
||||
title: ret.msg || '操作失败', // 显示错误信息
|
||||
icon: 'none', // 不显示图标
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// 请求失败回调
|
||||
fail(err) {
|
||||
uni.$emit('z-paging-error-emit');
|
||||
reject(err); // 返回错误对象
|
||||
uni.showToast({
|
||||
title: '网络请求失败',
|
||||
icon: 'none',
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
129
api/order.ts
129
api/order.ts
@@ -1,129 +0,0 @@
|
||||
import { request } from "./request";
|
||||
|
||||
|
||||
|
||||
// 订单预览
|
||||
export function fetchOrderPreview(form : {}) {
|
||||
return request({
|
||||
url: '/order/preview',
|
||||
data: form,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 订单下单
|
||||
export function fetchOrderbuyNow(data : {}) {
|
||||
return request({
|
||||
url: '/order/buyNow',
|
||||
data: data,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 订单详情
|
||||
export function fetchOrderDetail(id : Number) {
|
||||
return request({
|
||||
url: '/order/detail',
|
||||
data: { id: id },
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 订单统计
|
||||
export function fetchOrderTotalCount() {
|
||||
return request({
|
||||
url: '/order/totalCount'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取订单列表
|
||||
interface orderListParams {
|
||||
page ?: number;
|
||||
pageSize ?: number;
|
||||
status ?: 'all' | 'payment' | 'delivery' | 'received' | 'finish';
|
||||
goods_no ?: string;
|
||||
[key : string] : any; // 允许其他扩展参数
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @param params 请求参数对象
|
||||
* @returns Promise
|
||||
*/
|
||||
export function fetchOrderList(params : orderListParams = {}) {
|
||||
// 设置默认参数
|
||||
const defaultParams = {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
status: 'all',
|
||||
goods_no: '',
|
||||
};
|
||||
|
||||
const requestParams = {
|
||||
...defaultParams,
|
||||
...params
|
||||
};
|
||||
return request({
|
||||
url: '/order/getList',
|
||||
method: 'GET', // 或 'POST' 根据实际需求
|
||||
data: requestParams
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 取消订单
|
||||
export function fetchCancelOrder(id : Number) {
|
||||
return request({
|
||||
url: '/order/cancel',
|
||||
data: { id: id },
|
||||
})
|
||||
}
|
||||
|
||||
// 标记付款
|
||||
export function fetchPayOrder(id : Number) {
|
||||
return request({
|
||||
url: '/order/paid',
|
||||
data: { id: id },
|
||||
})
|
||||
}
|
||||
|
||||
// 标记发货
|
||||
export function fetchDeliveryOrder(form : {}) {
|
||||
return request({
|
||||
url: '/order/delivery',
|
||||
data: form,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 确认收货
|
||||
export function fetchReceiptOrder(id : Number) {
|
||||
return request({
|
||||
url: '/order/receipt',
|
||||
data: { id: id },
|
||||
})
|
||||
}
|
||||
@@ -67,13 +67,13 @@ interface Response {
|
||||
data : any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片上传的完整URL
|
||||
* @returns {string} 完整的图片上传URL,包含基础URL、wxapp_id和token参数
|
||||
*/
|
||||
export const getUploadImageUrl = () => {
|
||||
return config.api_base_url + '/upload/image' + '&wxapp_id=' + config.wxapp_id + '&token=' + uni.getStorageSync('token');
|
||||
};
|
||||
// /**
|
||||
// * 获取图片上传的完整URL
|
||||
// * @returns {string} 完整的图片上传URL,包含基础URL、wxapp_id和token参数
|
||||
// */
|
||||
// export const getUploadImageUrl = () => {
|
||||
// return config.api_base_url + '/upload/image' + '&wxapp_id=' + config.wxapp_id + '&token=' + uni.getStorageSync('token');
|
||||
// };
|
||||
|
||||
/**
|
||||
* 封装uni.request的通用请求方法
|
||||
|
||||
31
api/user.ts
31
api/user.ts
@@ -1,31 +0,0 @@
|
||||
import { request } from "./request";
|
||||
|
||||
// 用户登录
|
||||
|
||||
export function login(code : number, user_info : {}) {
|
||||
return request({
|
||||
url: '/user/login',
|
||||
data: {
|
||||
code: code,
|
||||
user_info: user_info
|
||||
},
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export function fetchUserInfo() {
|
||||
return request({
|
||||
url: '/user/info'
|
||||
})
|
||||
}
|
||||
|
||||
// 绑定手机号
|
||||
export function fetchUserPhone(code:string) {
|
||||
return request({
|
||||
url: '/store.user/bindPhone',
|
||||
data: {
|
||||
code: code,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
# 1.4.2
|
||||
|
||||
新增
|
||||
|
||||
1. 新增`filterValue`属性,支持通过此关键词来搜索并筛选树结构的内容
|
||||
|
||||
# 1.4.1
|
||||
|
||||
修复
|
||||
|
||||
1. 修复单选 onlyRadioLeaf 时末级节点无法选中的 bug
|
||||
|
||||
# 1.4.0
|
||||
|
||||
版本调整
|
||||
|
||||
建议更新,但需要注意,异步数据的时候,后台需返回 leaf 字段来判断是否末项数据
|
||||
|
||||
1. **调整数据项格式,新增 `leaf` 字段,来判断是否为末节点**
|
||||
2. **调整数据项格式,新增 `sort` 字段,来排序节点位置**
|
||||
3. **注意:异步加载数据,当为末项的时候,需要服务端数据返回 `leaf` 字段**
|
||||
4. 新增 `alwaysFirstLoad` ,即异步数据总会在第一次展开节点时,拉取一次后台数据,来比对是否一致
|
||||
5. 拆分 `field` 属性,**注意: 1.5.0 版本后将移除 `field` 属性**
|
||||
6. 新增 `labelField` 同 `field.label`,指定节点对象中某个属性为**标签**字段,默认`label`
|
||||
7. 新增 `valueField` 同 `field.key`,指定节点对象中某个属性为**值**字段,默认`value`
|
||||
8. 新增 `childrenField` 同 `field.children`,指定节点对象中某个属性为**子树节点**字段,默认`children`
|
||||
9. 新增 `disabledField` 同 `field.disabled`,指定节点对象中某个属性为**禁用**字段,默认`disabled`
|
||||
10. 新增 `appendField` 同 `field.append`,指定节点对象中某个属性为**副标签**字段,默认`append`
|
||||
11. 新增 `leafField` 同 `field.label`,指定节点对象中某个属性为**末级节点**字段,默认`leaf`
|
||||
12. 新增 `sortField` 同 `field.label`,指定节点对象中某个属性为**排序**字段,默认`sort`
|
||||
13. 新增 `isLeafFn` ,用来自定义控制数据项的末项
|
||||
14. 更多的项目示例
|
||||
15. 支持单选取消选中
|
||||
16. 修复节点展开时可能存在的 bug
|
||||
17. 修复节点选择可能存在的 bug
|
||||
18. 调整为子节点默认继承父节点禁用属性
|
||||
19. `setExpandedKeys` 添加参数一为 `all` 即可支持一键展开/收起全部节点
|
||||
20. 其它更多优化
|
||||
|
||||
# 1.3.4
|
||||
|
||||
优化
|
||||
|
||||
1. 优化图标字体命名
|
||||
|
||||
# 1.3.3
|
||||
|
||||
优化
|
||||
|
||||
1. 新增方法调用
|
||||
> - 新增`getUncheckedKeys`,返回未选的 key
|
||||
> - 新增`getUncheckedNodes`,返回未选的节点
|
||||
> - 新增`getUnexpandedKeys`,返回未展开的 key
|
||||
> - 新增`getUnexpandedNodes`,返回未展开的节点
|
||||
2. 优化示例项目
|
||||
|
||||
# 1.3.2
|
||||
|
||||
修复
|
||||
|
||||
1. 修复在 APP 真机环境中的报错
|
||||
|
||||
# 1.3.1
|
||||
|
||||
修复
|
||||
|
||||
1. 修复方法`setExpandedKeys`没联动展开上级父子节点
|
||||
|
||||
# 1.3.0
|
||||
|
||||
优化
|
||||
|
||||
1. `field`新增字段 `append` 用于在标签后面显示小提示
|
||||
2. 新增支持点击标签也能选中节点
|
||||
3. 方法`setExpandedKeys`支持加载动态数据
|
||||
4. 修复父节点禁用,则不能展开及图标展开显示
|
||||
5. 修复动态加载数据时,末级节点的 `children` 为 `null` 时仍显示展开图标
|
||||
|
||||
# 1.2.6
|
||||
|
||||
新增
|
||||
|
||||
1. 新增支持主题换色
|
||||
2. 支持单选的`onlyRadioLeaf`为`true`时可点父节点展开/收起
|
||||
3. 优化`expandChecked`调整为不展开无子节点的节点
|
||||
|
||||
# 1.2.5
|
||||
|
||||
新增
|
||||
|
||||
1. 新增 `expandChecked`,控制选择时是否展开当前已选的所有下级节点
|
||||
|
||||
# 1.2.4
|
||||
|
||||
修复
|
||||
|
||||
1. 修复动态数据展开状态异常问题
|
||||
|
||||
# 1.2.3
|
||||
|
||||
新增
|
||||
|
||||
1. 新增 `checkedDisabled`,是否渲染禁用值
|
||||
2. 新增 `packDisabledkey`,是否返回已禁用并选中的 key
|
||||
3. 修复选择父级时,子级已禁用但仍被选中的问题
|
||||
|
||||
# 1.2.2
|
||||
|
||||
优化
|
||||
|
||||
1. 调整动态数据载入处理方式
|
||||
2. 修复节点数据因动态数据引起的状态异常
|
||||
3. 修复初始节点数据默认选中
|
||||
|
||||
# 1.2.1
|
||||
|
||||
修复
|
||||
|
||||
1. 修复切换`选中状态`被重复选中问题
|
||||
2. 修复动态数据引起的重复选择问题
|
||||
|
||||
# 1.2.0
|
||||
|
||||
新增
|
||||
|
||||
1. 新增方法调用
|
||||
> - 新增`setCheckedKeys`,方法设置指定 key 的节点选中状态
|
||||
> - 新增`setExpandedKeys`,方法设置指定 key 的节点展开状态
|
||||
2. 修复小程序重复插槽一直刷报错问题
|
||||
3. 优化展开时,会展开子级所以下级节点
|
||||
|
||||
# 1.1.1
|
||||
|
||||
新增
|
||||
|
||||
1. 新增`data`的`disabled`,支持节点禁用状态
|
||||
2. 新增`field`的`disabled`,可自定`disabled`字段值
|
||||
|
||||
# 1.1.0
|
||||
|
||||
新增
|
||||
|
||||
1. 新增`loadMode`、`loadApi`,支持展开时加载异步数据
|
||||
2. 新增方法调用
|
||||
> - 新增`getCheckedKeys`,方法返回已选的 key
|
||||
> - 新增`getHalfCheckedKeys`,方法返回半选的 key
|
||||
> - 新增`getExpandedKeys`,方法返回已展开的 key
|
||||
> - 新增`getCheckedNodes`,方法返回已选的节点
|
||||
> - 新增`getHalfCheckedNodes`,方法返回半选的节点
|
||||
> - 新增`getExpandedNodes`,方法返回已展开的节点
|
||||
3. 对代码进行重构,更易于后期拓展
|
||||
4. 此次更新后,页面多个的 DaTee 组件间的数据不再关联
|
||||
|
||||
# 1.0.6
|
||||
|
||||
新增
|
||||
|
||||
1. 新增`checkStrictly`,多选模式下选中时是否父子不关联
|
||||
|
||||
# 1.0.5
|
||||
|
||||
修复
|
||||
|
||||
1. 修复多选时已选数据重复问题
|
||||
|
||||
# 1.0.4
|
||||
|
||||
修复
|
||||
|
||||
1. 修复 `change` 事件回调数据的问题
|
||||
|
||||
# 1.0.3
|
||||
|
||||
优化
|
||||
|
||||
1. 优化文档及示例说明
|
||||
|
||||
# 1.0.2
|
||||
|
||||
新增
|
||||
|
||||
1. 新增 `onlyRadioLeaf` ,单选时只允许选中末级
|
||||
2. 优化默认展开及默认选择的展开问题
|
||||
|
||||
# 1.0.1
|
||||
|
||||
新增
|
||||
|
||||
1. 支持展开/收起回调事件`@expand`
|
||||
|
||||
# 1.0.0
|
||||
|
||||
初始版本 1.0.0,基于 Vue3 进行开发,支持单选、多选,兼容各大平台
|
||||
|
||||
1. 支持单选
|
||||
2. 支持多选
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,197 +0,0 @@
|
||||
export default {
|
||||
/**
|
||||
* 树的数据
|
||||
*/
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
/**
|
||||
* 主题色
|
||||
*/
|
||||
themeColor: {
|
||||
type: String,
|
||||
default: '#007aff',
|
||||
},
|
||||
/**
|
||||
* 是否开启多选,默认单选
|
||||
*/
|
||||
showCheckbox: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 默认选中的节点,注意单选时为单个key,多选时为key的数组
|
||||
*/
|
||||
defaultCheckedKeys: {
|
||||
type: [Array, String, Number],
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 是否默认展开全部
|
||||
*/
|
||||
defaultExpandAll: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 默认展开的节点
|
||||
*/
|
||||
defaultExpandedKeys: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 筛选关键词
|
||||
*/
|
||||
filterValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/**
|
||||
* 是否自动展开到选中的节点,默认不展开
|
||||
*/
|
||||
expandChecked: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
/**
|
||||
* (旧)字段对应内容,默认为 {label: 'label',key: 'key', children: 'children', disabled: 'disabled', append: 'append'}
|
||||
* 注意:1.5.0版本后不再兼容
|
||||
*/
|
||||
field: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 标签字段(新,拆分了)
|
||||
*/
|
||||
labelField: {
|
||||
type: String,
|
||||
default: 'label',
|
||||
},
|
||||
/**
|
||||
* 值字段(新,拆分了)
|
||||
*/
|
||||
valueField: {
|
||||
type: String,
|
||||
default: 'value',
|
||||
},
|
||||
/**
|
||||
* 下级字段(新,拆分了)
|
||||
*/
|
||||
childrenField: {
|
||||
type: String,
|
||||
default: 'children',
|
||||
},
|
||||
/**
|
||||
* 禁用字段(新,拆分了)
|
||||
*/
|
||||
disabledField: {
|
||||
type: String,
|
||||
default: 'disabled',
|
||||
},
|
||||
/**
|
||||
* 末级节点字段(新,拆分了)
|
||||
*/
|
||||
leafField: {
|
||||
type: String,
|
||||
default: 'leaf',
|
||||
},
|
||||
/**
|
||||
* 副标签字段(新,拆分了)
|
||||
*/
|
||||
appendField: {
|
||||
type: String,
|
||||
default: 'append',
|
||||
},
|
||||
/**
|
||||
* 排序字段(新,拆分了)
|
||||
*/
|
||||
sortField: {
|
||||
type: String,
|
||||
default: 'sort',
|
||||
},
|
||||
/**
|
||||
* Api数据返回后的结果路径,支持嵌套如`data.list`
|
||||
*/
|
||||
resultField: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
isLeafFn: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 是否显示单选图标,默认显示
|
||||
*/
|
||||
showRadioIcon: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* 单选时只允许选中末级,默认可随意选中
|
||||
*/
|
||||
onlyRadioLeaf: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 多选时,是否执行父子不关联的任意勾选,默认父子关联
|
||||
*/
|
||||
checkStrictly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 为 true 时,空的 children 数组会显示展开图标
|
||||
*/
|
||||
loadMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 异步加载接口
|
||||
*/
|
||||
loadApi: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* 是否总在首次的时候加载一下内容,来比对是否一致
|
||||
*/
|
||||
alwaysFirstLoad: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 是否渲染(操作)禁用值
|
||||
*/
|
||||
checkedDisabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 是否返回已禁用的但已选中的key
|
||||
*/
|
||||
packDisabledkey: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* 选择框的位置,可选 left/right
|
||||
*/
|
||||
checkboxPlacement: {
|
||||
type: String,
|
||||
default: 'left',
|
||||
},
|
||||
/**
|
||||
* 子项缩进距离,默认40,单位rpx
|
||||
*/
|
||||
indent: {
|
||||
type: Number,
|
||||
default: 40,
|
||||
},
|
||||
}
|
||||
@@ -1,310 +0,0 @@
|
||||
# da-tree
|
||||
|
||||
一个基于 Vue3 的 tree(树)组件,同时支持主题换色,可能是最适合你的 tree(树)组件
|
||||
|
||||
组件一直在更新,遇到问题可在下方讨论。
|
||||
|
||||
`同时更新 Vue2 版本,在此查看 ===>` **[Vue2 版](https://ext.dcloud.net.cn/plugin?id=12692)**
|
||||
|
||||
### 关于使用
|
||||
|
||||
可在右侧的`使用 HBuilderX 导入插件`或`下载示例项目ZIP`,方便快速上手。
|
||||
|
||||
可通过下方的示例及文档说明,进一步了解使用组件相关细节参数。
|
||||
|
||||
插件地址:https://ext.dcloud.net.cn/plugin?id=12384
|
||||
|
||||
### 组件示例
|
||||
|
||||
```jsx
|
||||
<template>
|
||||
<view>多选</view>
|
||||
<view><button @click="doCheckedTree(['2'],true)">全选</button></view>
|
||||
<view><button @click="doCheckedTree(['2'],false)">取消全选</button></view>
|
||||
<view><button @click="doCheckedTree(['211','222'],true)">选中指定节点</button></view>
|
||||
<view><button @click="doCheckedTree(['211','222'],false)">取消选中指定节点</button></view>
|
||||
<view><button @click="doExpandTree('all',true)">展开全部节点</button></view>
|
||||
<view><button @click="doExpandTree('all',false)">收起全部节点</button></view>
|
||||
<view><button @click="doExpandTree(['22','23'],true)">展开节点</button></view>
|
||||
<view><button @click="doExpandTree(['22','23'],false)">收起节点</button></view>
|
||||
<DaTree
|
||||
ref="DaTreeRef"
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
defaultExpandAll
|
||||
showCheckbox
|
||||
:defaultCheckedKeys="defaultCheckedKeysValue"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange"></DaTree>
|
||||
<view>单选</view>
|
||||
<DaTree
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
defaultExpandAll
|
||||
:defaultCheckedKeys="defaultCheckedKeysValue2"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange"></DaTree>
|
||||
<view>默认展开指定节点</view>
|
||||
<DaTree
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
showCheckbox
|
||||
:defaultExpandedKeys="defaultExpandKeysValue3"
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange"></DaTree>
|
||||
<view>异步加载数据</view>
|
||||
<DaTree
|
||||
:data="roomTreeData"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
showCheckbox
|
||||
loadMode
|
||||
:loadApi="GetApiData"
|
||||
defaultExpandAll
|
||||
@change="handleTreeChange"
|
||||
@expand="handleExpandChange"></DaTree>
|
||||
</template>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
/**
|
||||
* 模拟创建一个接口数据
|
||||
*/
|
||||
function GetApiData(currentNode) {
|
||||
const { key } = currentNode
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
// 模拟返回空数据
|
||||
if (key.indexOf('-') > -1) {
|
||||
return resolve(null)
|
||||
// return resolve([])
|
||||
}
|
||||
|
||||
return resolve([
|
||||
{
|
||||
id: `${key}-1`,
|
||||
name: `行政部X${key}-1`,
|
||||
},
|
||||
{
|
||||
id: `${key}-2`,
|
||||
name: `财务部X${key}-2`,
|
||||
append: '定义了末项数据',
|
||||
leaf: true,
|
||||
},
|
||||
{
|
||||
id: `${key}-3`,
|
||||
name: `资源部X${key}-3`,
|
||||
},
|
||||
{
|
||||
id: `${key}-4`,
|
||||
name: `资源部X${key}-3`,
|
||||
append: '被禁用,无展开图标',
|
||||
disabled: true,
|
||||
},
|
||||
])
|
||||
}, 2000)
|
||||
})
|
||||
}
|
||||
|
||||
import DaTree from '@/components/da-tree/index.vue'
|
||||
export default defineComponent({
|
||||
components: { DaTree },
|
||||
setup() {
|
||||
const DaTreeRef = ref()
|
||||
// key的类型必须对应树数据key的类型
|
||||
const defaultCheckedKeysValue = ref(['211', '222'])
|
||||
const defaultCheckedKeysValue2 = ref('222')
|
||||
const defaultExpandKeysValue3 = ref(['212', '231'])
|
||||
const roomTreeData = ref([
|
||||
{
|
||||
id: '2',
|
||||
name: '行政中心',
|
||||
children: [
|
||||
{
|
||||
id: '21',
|
||||
name: '行政部',
|
||||
children: [
|
||||
{
|
||||
id: '211',
|
||||
name: '行政一部',
|
||||
children: null,
|
||||
},
|
||||
{
|
||||
id: '212',
|
||||
name: '行政二部',
|
||||
children: [],
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '22',
|
||||
name: '财务部',
|
||||
children: [
|
||||
{
|
||||
id: '221',
|
||||
name: '财务一部',
|
||||
children: [],
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
id: '222',
|
||||
name: '财务二部',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '23',
|
||||
name: '人力资源部',
|
||||
children: [
|
||||
{
|
||||
id: '231',
|
||||
name: '人力一部',
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
id: '232',
|
||||
name: '人力二部',
|
||||
append: '更多示例,请下载示例项目查看',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
function doExpandTree(keys, expand) {
|
||||
DaTreeRef.value?.setExpandedKeys(keys, expand)
|
||||
|
||||
const gek = DaTreeRef.value?.getExpandedKeys()
|
||||
console.log('当前已展开的KEY ==>', gek)
|
||||
}
|
||||
function doCheckedTree(keys, checked) {
|
||||
DaTreeRef.value?.setCheckedKeys(keys, checked)
|
||||
|
||||
const gek = DaTreeRef.value?.getCheckedKeys()
|
||||
console.log('当前已选中的KEY ==>', gek)
|
||||
}
|
||||
function handleTreeChange(allSelectedKeys, currentItem) {
|
||||
console.log('handleTreeChange ==>', allSelectedKeys, currentItem)
|
||||
}
|
||||
function handleExpandChange(expand, currentItem) {
|
||||
console.log('handleExpandChange ==>', expand, currentItem)
|
||||
}
|
||||
return {
|
||||
DaTreeRef,
|
||||
roomTreeData,
|
||||
defaultCheckedKeysValue,
|
||||
defaultCheckedKeysValue2,
|
||||
defaultExpandKeysValue3,
|
||||
handleTreeChange,
|
||||
handleExpandChange,
|
||||
GetApiData,
|
||||
doExpandTree,
|
||||
doCheckedTree,
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
** 更多示例请下载/导入示例项目 ZIP 查看 **
|
||||
|
||||
### 组件参数
|
||||
|
||||
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||
| :------------------ | :------------------------------ | :--------- | :--- | :--------------------------------------------------------------------------- |
|
||||
| data | `Array` | - | 是 | 树的数据 |
|
||||
| themeColor | `String` | `#007aff` | 否 | 主题色,十六进制 |
|
||||
| defaultCheckedKeys | `Array` \| `Number` \| `String` | - | 否 | 默认选中的节点,单选为单个 key,多选为 key 的数组 |
|
||||
| showCheckbox | `Boolean` | `false` | 否 | 是否开启多选,默认单选 |
|
||||
| checkStrictly | `Boolean` | `false` | 否 | 多选时,是否执行父子不关联的任意勾选,默认父子关联 |
|
||||
| showRadioIcon | `Boolean` | `true` | 否 | 是否显示单选图标,默认显示 |
|
||||
| onlyRadioLeaf | `Boolean` | `true` | 否 | 单选时只允许选中末级,默认可随意选中 |
|
||||
| defaultExpandAll | `Boolean` | `false` | 否 | 是否默认展开全部 |
|
||||
| defaultExpandedKeys | `Array` | - | 否 | 默认展开的节点 |
|
||||
| indent | `Number` | `40` | 否 | 子项缩进距离,单位 rpx |
|
||||
| checkboxPlacement | `String` | `left` | 否 | 选择框的位置,可选 left/right |
|
||||
| loadMode | `Boolean` | `false` | 否 | 为 true 时,空的 children 数组会显示展开图标 |
|
||||
| loadApi | `Function` | - | 否 | 选择框的位置,可选 left/right |
|
||||
| checkedDisabled | `Boolean` | `false` | 否 | 是否渲染禁用值,默认不渲染 |
|
||||
| packDisabledkey | `Boolean` | `true` | 否 | 是否返回已禁用的但已选中的 key,默认返回禁用已选值 |
|
||||
| expandChecked | `Boolean` | `false` | 否 | 是否自动展开到选中的节点,默认不展开 |
|
||||
| alwaysFirstLoad | `Boolean` | `false` | 否 | 是否总在首次的时候加载一下内容,默认不加载,否则只有展开末级节点才会加载数据 |
|
||||
| isLeafFn | `Function` | - | 否 | 自定义函数返回来控制数据项的末项 |
|
||||
| field | `Object` | - | 否 | 字段对应内容,格式参考下方(1.5.0 后移除,请用单独的字段匹配) |
|
||||
| labelField | `String` | `label` | 否 | 指定节点对象中某个属性为标签字段,默认`label` |
|
||||
| valueField | `String` | `value` | 否 | 指定节点对象中某个属性为值字段,默认`value` |
|
||||
| childrenField | `String` | `children` | 否 | 指定节点对象中某个属性为子树节点字段,默认`children` |
|
||||
| disabledField | `String` | `disabled` | 否 | 指定节点对象中某个属性为禁用字段,默认`disabled` |
|
||||
| appendField | `String` | `append` | 否 | 指定节点对象中某个属性为副标签字段,默认`append` |
|
||||
| leafField | `String` | `leaf` | 否 | 指定节点对象中某个属性为末级节点字段,默认`leaf` |
|
||||
| sortField | `String` | `sort` | 否 | 指定节点对象中某个属性为排序字段,默认`sort` |
|
||||
| filterValue | `String` | - | 否 | 搜索筛选的关键词,通过输入关键词筛选内容 |
|
||||
|
||||
**field 格式(1.5.0 后移除,请用单独的字段匹配)**
|
||||
|
||||
```js
|
||||
{
|
||||
label: 'label',
|
||||
key: 'key',
|
||||
children: 'children',
|
||||
disabled: 'disabled',
|
||||
append: 'append'
|
||||
}
|
||||
```
|
||||
|
||||
### 组件事件
|
||||
|
||||
| 事件名称 | 回调参数 | 说明 |
|
||||
| :------- | :-------------------------------------- | :-------------- |
|
||||
| change | `(allCheckedKeys, currentItem) => void` | 选中时回调 |
|
||||
| expand | `(expandState, currentItem) => void` | 展开/收起时回调 |
|
||||
|
||||
### 组件方法
|
||||
|
||||
| 方法名称 | 参数 | 说明 |
|
||||
| :------------------ | :--------------- | :------------------------------------------------------------------------------------------------ |
|
||||
| setCheckedKeys | `(keys,checked)` | 设置指定 key 的节点选中/取消选中的状态。注: keys 单选时为 key,多选时为 key 的数组 |
|
||||
| setExpandedKeys | `(keys,expand)` | 设置指定 key 的节点展开/收起的状态,当 keys 为 all 时即代表展开/收起全部。注:keys 为数组或 `all` |
|
||||
| getCheckedKeys | - | 返回已选的 key |
|
||||
| getHalfCheckedKeys | - | 返回半选的 key |
|
||||
| getUncheckedKeys | - | 返回未选的 key |
|
||||
| getCheckedNodes | - | 返回已选的节点 |
|
||||
| getUncheckedNodes | - | 返回未选的节点 |
|
||||
| getHalfCheckedNodes | - | 返回半选的节点 |
|
||||
| getExpandedKeys | - | 返回已展开的 key |
|
||||
| getUnexpandedKeys | - | 返回未展开的 key |
|
||||
| getExpandedNodes | - | 返回已展开的节点 |
|
||||
| getUnexpandedNodes | - | 返回未展开的节点 |
|
||||
|
||||
### 组件版本
|
||||
|
||||
v1.4.2
|
||||
|
||||
### 差异化
|
||||
|
||||
已通过测试
|
||||
|
||||
> - H5 页面
|
||||
> - 微信小程序
|
||||
> - 支付宝、钉钉小程序
|
||||
> - 字节跳动、抖音、今日头条小程序
|
||||
> - 百度小程序
|
||||
> - 飞书小程序
|
||||
> - QQ 小程序
|
||||
> - 京东小程序
|
||||
|
||||
未测试
|
||||
|
||||
> - 快手小程序由于非企业用户暂无演示
|
||||
> - 快应用、360 小程序因 Vue3 支持的原因暂无演示
|
||||
|
||||
### 开发组
|
||||
|
||||
[@CRLANG](https://crlang.com)
|
||||
@@ -1,150 +0,0 @@
|
||||
/** 未选 */
|
||||
export const unCheckedStatus = 0
|
||||
/** 半选 */
|
||||
export const halfCheckedStatus = 1
|
||||
/** 选中 */
|
||||
export const isCheckedStatus = 2
|
||||
|
||||
/**
|
||||
* 深拷贝内容
|
||||
* @param originData 拷贝对象
|
||||
* @author crlang(https://crlang.com)
|
||||
*/
|
||||
export function deepClone(originData) {
|
||||
const type = Object.prototype.toString.call(originData)
|
||||
let data
|
||||
if (type === '[object Array]') {
|
||||
data = []
|
||||
for (let i = 0; i < originData.length; i++) {
|
||||
data.push(deepClone(originData[i]))
|
||||
}
|
||||
} else if (type === '[object Object]') {
|
||||
data = {}
|
||||
for (const prop in originData) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (originData.hasOwnProperty(prop)) { // 非继承属性
|
||||
data[prop] = deepClone(originData[prop])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data = originData
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有指定的节点
|
||||
* @param type
|
||||
* @param value
|
||||
* @author crlang(https://crlang.com)
|
||||
*/
|
||||
export function getAllNodes(list, type, value, packDisabledkey = true) {
|
||||
if (!list || list.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const res = []
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const item = list[i]
|
||||
if (item[type] === value) {
|
||||
if ((packDisabledkey && item.disabled) || !item.disabled) {
|
||||
res.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有指定的key值
|
||||
* @param type
|
||||
* @param value
|
||||
* @author crlang(https://crlang.com)
|
||||
*/
|
||||
export function getAllNodeKeys(list, type, value, packDisabledkey = true) {
|
||||
if (!list || list.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const res = []
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const item = list[i]
|
||||
if (item[type] === value) {
|
||||
if ((packDisabledkey && item.disabled) || !item.disabled) {
|
||||
res.push(item.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res.length ? res : null
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误输出
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
export function logError(msg, ...args) {
|
||||
console.error(`DaTree: ${msg}`, ...args)
|
||||
}
|
||||
|
||||
const toString = Object.prototype.toString
|
||||
|
||||
export function is(val, type) {
|
||||
return toString.call(val) === `[object ${type}]`
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否对象(Object)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isObject(val) {
|
||||
return val !== null && is(val, 'Object')
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否数字(Number)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isNumber(val) {
|
||||
return is(val, 'Number')
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否字符串(String)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isString(val) {
|
||||
return is(val, 'String')
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否函数方法(Function)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isFunction(val) {
|
||||
return typeof val === 'function'
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否布尔(Boolean)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isBoolean(val) {
|
||||
return is(val, 'Boolean')
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否数组(Array)
|
||||
* @param val
|
||||
|
||||
*/
|
||||
export function isArray(val) {
|
||||
return val && Array.isArray(val)
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
<template>
|
||||
<view class="navbar">
|
||||
<view class="navbar-fixed">
|
||||
<!-- 状态栏占位 -->
|
||||
<view :style="{height: props.statusBarHeight+'px'}"></view>
|
||||
<!-- 导航栏内容 -->
|
||||
<view class="navbar-content" :style="{height:props.navbarHeight+'px',width:props.windowWidth+'px'}">
|
||||
<view class="header">
|
||||
<view class="company-name">{{title}}</view>
|
||||
<nut-animate type="flicker" :loop="true">
|
||||
<view class="description">{{desc}}</view>
|
||||
</nut-animate>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <nut-searchbar clearable v-model="search_val" background="transparent" input-background="#fff"
|
||||
@search="onSearch" @clear="onClear">
|
||||
<template #rightout>
|
||||
<nut-icon @click="onScan" name="scan2" custom-color="#ffffff" />
|
||||
</template>
|
||||
</nut-searchbar> -->
|
||||
</view>
|
||||
<!-- 占位状态栏+导航栏的高度,使下面的内容不会被遮挡 -->
|
||||
<view :style="{height:(statusBarHeight + navbarHeight+ navbarSearchBoxHeight)+'px'}"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
defineProps
|
||||
} from 'vue';
|
||||
// import {
|
||||
// fetchGoodsList
|
||||
// } from '../../api/goods';
|
||||
import {
|
||||
navigateTo
|
||||
} from '@/utils/helper';
|
||||
|
||||
// const navbarSearchBoxHeight = 50
|
||||
const navbarSearchBoxHeight = 0
|
||||
const props = defineProps({
|
||||
statusBarHeight: Number,
|
||||
windowWidth: Number,
|
||||
navbarHeight: Number,
|
||||
title:String,
|
||||
desc:String,
|
||||
// onIndexPageSearch:Function,
|
||||
// onIndexPageClear:Function
|
||||
})
|
||||
|
||||
|
||||
|
||||
// const search_val = ref('')
|
||||
// const onSearch = () => {
|
||||
// if(props.onIndexPageSearch) {
|
||||
// props.onIndexPageSearch(search_val.value)
|
||||
// }
|
||||
// }
|
||||
// const onClear = () => {
|
||||
// if(props.onIndexPageClear) {
|
||||
// props.onIndexPageClear()
|
||||
// }
|
||||
|
||||
// }
|
||||
// const onScan =() => {
|
||||
// uni.scanCode({
|
||||
// onlyFromCamera:true,
|
||||
// success: (res) => {
|
||||
// fetchGoodsList({
|
||||
// search_params: {goods_no:res.result}
|
||||
// }).then(res => {
|
||||
// if (res.list.total >= 1) {
|
||||
// navigateTo("/pages/mall/item/index?id=" + res.list?.data[0]?.goods_id)
|
||||
// } else {
|
||||
// uni.showToast({
|
||||
// icon:'none',
|
||||
// title:'暂无该商品'
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// fail: () => {
|
||||
// uni.showToast({
|
||||
// icon:'none',
|
||||
// title:'扫码失败'
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.navbar {}
|
||||
|
||||
.navbar-fixed {
|
||||
/* // 固定定位 */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
/* background: linear-gradient(90deg, #b79dff, #f2a4ff); */
|
||||
/* 渐变背景 */
|
||||
background-image: -webkit-linear-gradient(60deg, rgba(233, 100, 67, 1), rgba(198, 77, 255, 1));
|
||||
background-image: linear-gradient(30deg, rgba(233, 100, 67, 1), rgba(198, 77, 255, 1));
|
||||
background-position: 0 0;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% auto;
|
||||
opacity: 1;
|
||||
/* 确保背景不透明 */
|
||||
}
|
||||
|
||||
.navbar-content {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
/* // 水平居中 */
|
||||
justify-content: center;
|
||||
/* // 垂直居中 */
|
||||
/* // align-items: center; */
|
||||
padding: 0 30rpx;
|
||||
/* // 盒内显示 (父元素和子元素宽度都是100%,但是父元素加了左右内填充,会导致子元素不在父元素内) */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.company-name {
|
||||
font-family: Akrobat ExtraBold !important;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.description {
|
||||
font-family: Akrobat ExtraBold !important;
|
||||
color: #fff;
|
||||
font-size: 16rpx
|
||||
}
|
||||
</style>
|
||||
@@ -1,132 +0,0 @@
|
||||
<template>
|
||||
<view class="navbar">
|
||||
<view class="navbar-fixed">
|
||||
<!-- 状态栏占位 -->
|
||||
<view :style="{height: props.statusBarHeight+'px'}"></view>
|
||||
<!-- 导航栏内容 -->
|
||||
<view class="navbar-content" :style="{height:props.navbarHeight+'px',width:props.windowWidth+'px'}">
|
||||
<view class="header">
|
||||
<view class="company-name">济南远阳数码</view>
|
||||
<view class="description">专注于电子组件研发20年,提供优质产品与服务!</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <nut-searchbar clearable v-model="search_val" background="transparent" input-background="#fff"
|
||||
@search="onSearch" @clear="onClear">
|
||||
<template #rightout>
|
||||
<nut-icon @click="onScan" name="scan2" custom-color="#ffffff" />
|
||||
</template>
|
||||
</nut-searchbar> -->
|
||||
</view>
|
||||
<!-- 占位状态栏+导航栏的高度,使下面的内容不会被遮挡 -->
|
||||
<view :style="{height:(statusBarHeight + navbarHeight+ navbarSearchBoxHeight)+'px'}"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
defineProps
|
||||
} from 'vue';
|
||||
import {
|
||||
fetchGoodsList
|
||||
} from '../../api/goods';
|
||||
import {
|
||||
navigateTo
|
||||
} from '../../utils/helper';
|
||||
|
||||
// const navbarSearchBoxHeight = 50
|
||||
const navbarSearchBoxHeight = 0
|
||||
const props = defineProps({
|
||||
statusBarHeight: Number,
|
||||
windowWidth: Number,
|
||||
navbarHeight: Number,
|
||||
// onIndexPageSearch:Function,
|
||||
// onIndexPageClear:Function
|
||||
})
|
||||
// const search_val = ref('')
|
||||
// const onSearch = () => {
|
||||
// if(props.onIndexPageSearch) {
|
||||
// props.onIndexPageSearch(search_val.value)
|
||||
// }
|
||||
// }
|
||||
// const onClear = () => {
|
||||
// if(props.onIndexPageClear) {
|
||||
// props.onIndexPageClear()
|
||||
// }
|
||||
|
||||
// }
|
||||
// const onScan =() => {
|
||||
// uni.scanCode({
|
||||
// onlyFromCamera:true,
|
||||
// success: (res) => {
|
||||
// fetchGoodsList({
|
||||
// search_params: {goods_no:res.result}
|
||||
// }).then(res => {
|
||||
// if (res.list.total >= 1) {
|
||||
// navigateTo("/pages/mall/item/index?id=" + res.list?.data[0]?.goods_id)
|
||||
// } else {
|
||||
// uni.showToast({
|
||||
// icon:'none',
|
||||
// title:'暂无该商品'
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// fail: () => {
|
||||
// uni.showToast({
|
||||
// icon:'none',
|
||||
// title:'扫码失败'
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.navbar {}
|
||||
|
||||
.navbar-fixed {
|
||||
/* // 固定定位 */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
/* background: linear-gradient(90deg, #b79dff, #f2a4ff); */
|
||||
/* 渐变背景 */
|
||||
background-image: -webkit-linear-gradient(60deg, rgba(233, 100, 67, 1), rgba(198, 77, 255, 1));
|
||||
background-image: linear-gradient(30deg, rgba(233, 100, 67, 1), rgba(198, 77, 255, 1));
|
||||
background-position: 0 0;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% auto;
|
||||
opacity: 1;
|
||||
/* 确保背景不透明 */
|
||||
}
|
||||
|
||||
.navbar-content {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
/* // 水平居中 */
|
||||
justify-content: center;
|
||||
/* // 垂直居中 */
|
||||
/* // align-items: center; */
|
||||
padding: 0 30rpx;
|
||||
/* // 盒内显示 (父元素和子元素宽度都是100%,但是父元素加了左右内填充,会导致子元素不在父元素内) */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.company-name {
|
||||
font-family: Akrobat ExtraBold !important;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.description {
|
||||
font-family: Akrobat ExtraBold !important;
|
||||
color: #fff;
|
||||
font-size: 16rpx
|
||||
}
|
||||
</style>
|
||||
@@ -1,341 +0,0 @@
|
||||
<template>
|
||||
<view
|
||||
class="inline-select"
|
||||
:class="{ 'is-disabled': disabled, 'is-error': hasError }"
|
||||
:tabindex="disabled ? -1 : 0"
|
||||
@keydown.enter="handleTriggerClick"
|
||||
@keydown.space.prevent="handleTriggerClick"
|
||||
@keydown.esc="onCancel"
|
||||
>
|
||||
<view class="inline-select__trigger" :style="customStyle" @click="handleTriggerClick">
|
||||
<view class="inline-select__content">
|
||||
<view class="inline-select__value" :class="{ 'is-placeholder': !hasValue }">{{ displayValue }}</view>
|
||||
<slot name="suffix">
|
||||
<view class="inline-select__indicator">
|
||||
<text v-if="loading" class="inline-select__loading"></text>
|
||||
<text v-else class="inline-select__arrow" :class="{ 'is-active': show_popup }"></text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<nut-popup v-model:visible="show_popup" position="bottom" safe-area-inset-bottom :close-on-click-overlay="closeOnClickOverlay">
|
||||
<nut-picker
|
||||
:columns="columns"
|
||||
:field-names="fieldNames"
|
||||
v-bind="$attrs"
|
||||
v-model="currentPickerValue"
|
||||
@confirm="onConfirm"
|
||||
@change="onChange"
|
||||
@cancel="onCancel"
|
||||
>
|
||||
|
||||
<view v-if="columns.length === 0" class="inline-select__empty">{{ emptyText }}</view>
|
||||
<template v-else-if="$slots.option" #default="{ option }">
|
||||
<slot name="option" :option="option"></slot>
|
||||
</template>
|
||||
</nut-picker>
|
||||
</nut-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
/**
|
||||
* @component InlineSelect
|
||||
* @description 行内选择组件 - 基于 NutUI Picker 的移动端下拉选择器,提供了丰富的自定义选项和事件处理能力。
|
||||
* 该组件适用于在表单中进行单项选择的场景,支持自定义样式、异步加载、键盘操作等特性。
|
||||
*
|
||||
* @property {String|Number} modelValue - 选择器的当前值,支持v-model双向绑定
|
||||
* @property {String} [title='请选择'] - 选择器标题,显示在弹出层顶部
|
||||
* @property {String} [placeholder='请选择'] - 选择框占位文本,未选择时显示
|
||||
* @property {Object} [fieldNames={ text: 'name', value: 'value' }] - 自定义字段名映射,用于适配不同数据结构
|
||||
* @property {String} [fieldNames.text='name'] - 选项显示文本的字段名
|
||||
* @property {String} [fieldNames.value='value'] - 选项值的字段名
|
||||
* @property {Array<{[key: string]: any}>} columns - 选项数据列表(必填),每个选项对象必须包含text和value字段,支持自定义字段名
|
||||
* @property {String|Number} [defaultValue=''] - 默认选中值,当modelValue未设置时生效
|
||||
* @property {Boolean} [disabled=false] - 是否禁用选择器,禁用时无法打开选择弹窗
|
||||
* @property {Boolean} [closeOnClickOverlay=true] - 是否在点击遮罩层时关闭弹窗
|
||||
* @property {Object} [customStyle={}] - 自定义样式对象,用于定制选择器外观
|
||||
* @property {Boolean} [loading=false] - 是否显示加载状态,加载时显示loading图标
|
||||
* @property {String} [emptyText='暂无可选项'] - 无选项时显示的文本
|
||||
* @property {String} [theme='default'] - 主题样式,可选值:'default'|'primary'|'success'|'warning'|'danger'
|
||||
*
|
||||
* @event {Function} update:modelValue - 值更新时触发,参数: (value: string|number)
|
||||
* @event {Function} change - 选项改变时触发,参数: { columnIndex: number, selectedValue: Array, selectedOptions: Array }
|
||||
* @event {Function} confirm - 点击确定按钮时触发,参数: { value: string|number, option: Object }
|
||||
* @event {Function} cancel - 点击取消按钮时触发
|
||||
* @event {Function} error - 选中值无效时触发,参数: { value: string|number, message: string }
|
||||
*
|
||||
* @slot suffix - 选择框后置内容,默认显示箭头图标
|
||||
* @slot option - 自定义选项渲染,参数: { option: Object }
|
||||
*
|
||||
* @see 更多信息请参考 NutUI Picker 组件文档
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, shallowRef, onMounted } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '未选择',
|
||||
},
|
||||
fieldNames: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
text: 'name',
|
||||
value: 'value',
|
||||
};
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
defaultValue: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
customStyle: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
emptyText: {
|
||||
type: String,
|
||||
default: '暂无可选项',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change', 'confirm', 'cancel', 'error']);
|
||||
|
||||
// 状态管理
|
||||
const show_popup = ref(false);
|
||||
const currentValue = shallowRef('');
|
||||
const hasError = ref(false);
|
||||
const optionsCache = new Map();
|
||||
|
||||
// 初始化currentValue
|
||||
const initCurrentValue = () => {
|
||||
if (props.modelValue !== undefined && props.modelValue !== null) {
|
||||
currentValue.value = props.modelValue;
|
||||
} else if (props.defaultValue !== undefined && props.defaultValue !== null) {
|
||||
currentValue.value = props.defaultValue;
|
||||
emit('update:modelValue', props.defaultValue);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(initCurrentValue);
|
||||
|
||||
// 监听columns变化,重新初始化currentValue
|
||||
watch(
|
||||
() => props.columns,
|
||||
() => {
|
||||
initCurrentValue();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const currentPickerValue = ref([]);
|
||||
// 监听columns变化,重新初始化currentValue
|
||||
watch(
|
||||
() => currentValue.value,
|
||||
() => {
|
||||
currentPickerValue.value = [currentValue.value];
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 计算属性
|
||||
const hasValue = computed(() => currentValue.value !== '' && currentValue.value !== undefined && currentValue.value !== null);
|
||||
|
||||
const displayValue = computed(() => {
|
||||
if (!hasValue.value || !props.columns.length) return props.placeholder;
|
||||
|
||||
const cachedOption = optionsCache.get(currentValue.value);
|
||||
if (cachedOption) {
|
||||
hasError.value = false;
|
||||
return cachedOption[props.fieldNames.text];
|
||||
}
|
||||
|
||||
const selectedItem = props.columns.find(item => item[props.fieldNames.value] === currentValue.value);
|
||||
if (selectedItem) {
|
||||
optionsCache.set(currentValue.value, selectedItem);
|
||||
hasError.value = false;
|
||||
return selectedItem[props.fieldNames.text];
|
||||
}
|
||||
|
||||
hasError.value = true;
|
||||
emit('error', { value: currentValue.value, message: '选项不存在' });
|
||||
return props.placeholder;
|
||||
});
|
||||
|
||||
// 事件处理
|
||||
const handleTriggerClick = () => {
|
||||
if (props.disabled) return;
|
||||
show_popup.value = true;
|
||||
};
|
||||
|
||||
const onChange = ({ columnIndex, selectedValue, selectedOptions }) => {
|
||||
emit('change', { columnIndex, selectedValue, selectedOptions });
|
||||
};
|
||||
|
||||
const onConfirm = ({ selectedValue, selectedOptions }) => {
|
||||
if (!Array.isArray(selectedValue) || !Array.isArray(selectedOptions) || !selectedValue.length || !selectedOptions.length) return;
|
||||
|
||||
const value = selectedValue[0];
|
||||
const option = selectedOptions[0];
|
||||
|
||||
if (value === undefined || option === undefined) return;
|
||||
|
||||
currentValue.value = value;
|
||||
emit('update:modelValue', value);
|
||||
emit('confirm', { value, option });
|
||||
show_popup.value = false;
|
||||
};
|
||||
const onCancel = () => {
|
||||
show_popup.value = false;
|
||||
emit('cancel');
|
||||
};
|
||||
|
||||
// 监听modelValue的变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
newValue => {
|
||||
if (newValue !== undefined && newValue !== null && newValue !== currentValue.value) {
|
||||
currentValue.value = newValue;
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.inline-select {
|
||||
width: 100%;
|
||||
outline: none;
|
||||
|
||||
&:focus:not(.is-disabled) .inline-select__trigger {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
|
||||
.inline-select__trigger {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-error .inline-select__trigger {
|
||||
border-color: var(--theme-error-color, #f56c6c);
|
||||
}
|
||||
|
||||
&__trigger {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: var(--theme-bg-color, #fff);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
&:active:not(.is-disabled) {
|
||||
background-color: var(--theme-hover-bg-color, #f5f5f5);
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
&__value {
|
||||
flex: 1;
|
||||
line-height: 1.5;
|
||||
color: var(--theme-text-color, #333);
|
||||
|
||||
&.is-placeholder {
|
||||
color: var(--theme-placeholder-color, #999);
|
||||
}
|
||||
}
|
||||
|
||||
&__indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
&__arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 12rpx solid transparent;
|
||||
border-top-color: var(--theme-arrow-color, #999);
|
||||
transform: translateY(25%) rotate(0deg);
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
&.is-active {
|
||||
transform: translateY(25%) rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
&__loading {
|
||||
display: inline-block;
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border: 3rpx solid var(--theme-loading-color, #2d8cf0);
|
||||
border-radius: 50%;
|
||||
border-top-color: transparent;
|
||||
animation: inline-select-loading 0.8s infinite linear;
|
||||
}
|
||||
|
||||
&__empty {
|
||||
padding: 64rpx;
|
||||
text-align: center;
|
||||
color: var(--theme-empty-color, #999);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes inline-select-loading {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--theme-color-rgb: 45, 140, 240;
|
||||
--theme-bg-color: #fff;
|
||||
--theme-text-color: #333;
|
||||
--theme-border-color: #dcdfe6;
|
||||
--theme-placeholder-color: #999;
|
||||
--theme-hover-bg-color: #f5f5f5;
|
||||
--theme-arrow-color: #999;
|
||||
--theme-loading-color: #2d8cf0;
|
||||
--theme-empty-color: #999;
|
||||
--theme-error-color: #f56c6c;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +0,0 @@
|
||||
## 1.1.1(2025-03-06)
|
||||
1.1.1
|
||||
## 1.1.0(2025-03-06)
|
||||
1.1.0
|
||||
## 1.0.0(2025-03-05)
|
||||
1.0.0
|
||||
1.0.0
|
||||
@@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<view class="op-cascader" :style="{maxHeight: maxHeight}">
|
||||
<template v-for="(opt, optInx) in newOption" :key="optInx">
|
||||
<view class="cascader-content">
|
||||
<scroll-view :scroll-y="true" style="height: 100%;">
|
||||
<template v-for="(item, index) in opt" :key="index">
|
||||
<view v-if="item._parentId==0 || (optInx >0 && modelValue[optInx-1] == item._parentId)"
|
||||
class="cascader-item" :class="{active:
|
||||
isActive(item,optInx,valueKey)
|
||||
}" @click="select(item[valueKey], optInx, index, item._level)">
|
||||
<view class="cascader-item-label">{{ item[labelKey] }}</view>
|
||||
<template v-if="iconShow">
|
||||
<image v-if="isActive(item,optInx,valueKey)" class="icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAOHSURBVHgB7ZldbtpAEMdnFgeBaCV6gnKDkhMUpCbKW9oTRDlB04cS5SnwUFWiL+EEbW+QxzSJFHqCcIOSGyD1I4Hgne44obWNbXb9BQ/8HhJsL+Y/u7O7szMAa9YkAiEFGm2qliq/6rZdeI1CPAegOiFVkbDKz9XnEZIYEqn/IL8LIftn75/2IQUSGbDz6WeDRUMB9mZidWGj1J9TALt30XoygJjEMsARDtYxEjQgBYigX5Cwf3ZUHoIhRgawqxQr42P1iweQBUgnk9/lTr+NI+2v6Dbc+XhbkwW4Uh9rkC1DYUNTdzSETqOtrpqgFl1D9uIZp6O2upO6TuOFI8DiAcWV6SRNDo4IRPOiVYyc4JEG5Og2IeBI2LQZ5U6hLsQTdrnimQcNrCWsRagBzmqzVPH/qBUrt8dhDwNd6NF1fsAKIXHavAzYvQNHwLbgM6wYKK3AUZgbga0Pkzpu2NewggSNwtwIkHWfzS4bAocRum2R4y4fcwagwF3IC5Kdi8NyEwg6Os1VpLvnX5E8BqjJ28htw1Lizw8rbf54flhuE+qMBFUtFba773gMkEI2IA9c4pnt7lg7svW7kccAEuIlZE2AeNV1bd2vo29v8s4BomzdJ6F4B4EvPJeeh2i285qsIKmId8DwSWw0gU1WkNTEOy8LN0D7Farn3StIpBGpip/HO4n5oK0BIjS2u/8DrFAjMhHvPW76XUj7LKpoRxqRWc/LofvKuw8QmqY3go3I0G3I18mW+wJR3sTItLARcN4qO73vGOEibZ/nxJj72jsHbE40xcIzEjPSFs+oaKHvvvYYMC3dDXQncgAeI7IQzxPYH07Pnwe6f04Q8C3Ep/3QL2mLd8R++dYq77vvWf5G7EZYgIQGSMgCCYWe/97cRnZ5VO7rhbb5wptnUI4ocCemqd4BI084+Rt0P9AAZxSAerAikKReWHIrNBa63xjzpjSEZaM03N959xY3oQb03z0bCQnNBMtqcpR41hCVbo+MRp1hI7kUI5QLjwjtN4vS7AvDaaf8o4zI051YvFo0mzqlJ7MCh1DJXsNTmzGPbpNqgYPhF06Kd5tZrk682kxuS5smtbJ4RT41Gpw/TbPIRxI6vHyDIYnKrFy9UYegA0LcRTAss7KfS/iq4vvTOMJnpFLoZl6prJ4qYDec3NJDeqY2M4rFonMUxAFJecOip+PSwKQauWZNRvwFjird3f4t0GAAAAAASUVORK5CYII="
|
||||
mode="aspectFit"></image>
|
||||
<image v-else class="icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQdSURBVHgB7VlbTiJBFC3QGOOHz1/RxOjPGP8HF+C4AMUFDC5AWYfMAtQFyMwC0AXIAgwmRuMP86uJfBhjVOYcUtW5XV0N3dA0TMJJSFc/qLqn7q2q+1BqjDH6QkYlgPv7+1lcNrPZ7I+vr68VXL/hOpfJZPhctVqtJp418IzXa1xrGxsbNZUA+iIAwfNa6AMjbFSQFC5V/M5Apq56RE8EKDguJQidVwkAZGpvb29HW1tbDRUTsQhoU6HgxUBHmUwD2qh+fHzcol1bWFh4WVpa4iyrp6en2efn5xyay5OTk3lobBdC51SQyBkuJ9BIU0VEZAI3Nze5mZmZ3/bAELYCgSpxbRqTwTVTRH8Fq7/G6+vrflRtRCJQr9c3p6am/kg7R/sagx+vr6/HVrvEw8NDDn0dSyIkgUn5GWVtdCVgC8/FNzExcbK2tnamEsTj42Px8/OzZMbBtQkSe91IdCRgm02cmekFWhtyvCbMaaeTOYUS4IKFjV5J4dHe79dkusFBgpO2E7awsx36KplOaDZpCE9wDGpZnxNKy1AK+95JgKYjt0rafBrCG9BEOaa5pyz67AnASWB6evqX+HMl6QUbBRyTB5x45NRCgAD3Z3nCopOyGhIgx5Fo511acGmgKP5USdN0bHBsymDu6XfZ37gI7JoGjv3UTccGT3lxe6DdGQ8+AlSROEgaq6urA9nv44AuCmVhG+bcdtvlex8BqEjaWFWNDjxZbDPyEYC6tkU7kYAjCUCWW9Feke/sNeDZF/yfv2pEQPfctBntyXc2Ac9Vfn9/H9ruYwO2/yJu5+Q7HwHpLscJKgYNKYteyB6y6j+Hj4BxoAh7vx0mpCx0seU7ext9ER/OqdGBtzaxC/nWpm1C3sEFMt/V6GDZNOQkt++tDz12MKdNNSKwDljf+WQfZJfidleNDjxZ7AM2YEIyEgoLItIE3XsZI9vpGx8B7rdQ14V4VFDDh0yiBfyzwDkgzQiMCwwv1ZCgQ1tvEl3ufYAAVSRDORlepg2MfWzaTKS53Puwk1gG1HmkOg5Vyri7uzuUs88soOs7JwEdRJyae6b+uJhUSqDpYC3K2T8NC21DfSGshbKMhNDheRrrwWQDZWQ4Pz8fmlgIJcAdicksua2y40GSYB7WTmVSBpOmd6GjN6rVtmeRuBrEmqDNM4kss4HM0HXLikRKr+tc/rmsDaBdQVWl3EtVRYIa5U5n5aI4YXuJpNcN7KSrGIxpj9h1Ln3KF+RO0xYoZhI5domJuwMGCJiQXvBVvK+hzMR4umEiKf6P7jn+l9cxrbPExN2GC7aTzfdFwEBrowwhtlUC4CHFXa+X0mu/ZdZ2nYtFu17KrHANLqCty35qxokUugldM6ZdswrJaC5nFboZiNRZ8KbQi4uL9TimMsYYA8I/5WtETy5O2jYAAAAASUVORK5CYII="
|
||||
mode="aspectFit"></image>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
defineModel,
|
||||
defineProps,
|
||||
defineEmits,
|
||||
watch
|
||||
} from 'vue';
|
||||
const modelValue = defineModel({
|
||||
type: Array,
|
||||
default: []
|
||||
});
|
||||
const DefProps = defineProps({
|
||||
option: { // tree数据
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
props: { // 属性值
|
||||
type: Object,
|
||||
default: {
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
disabled: 'disabled',
|
||||
}
|
||||
},
|
||||
maxHeight: { //最大下拉高度
|
||||
type: String,
|
||||
default: "400rpx"
|
||||
},
|
||||
iconShow: { // 是由否显示左侧按钮
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(['change'])
|
||||
const newOption = ref([]); // 选项tree
|
||||
const labelKey = ref('label'); // 默认属性key
|
||||
const valueKey = ref('value');
|
||||
const childrenKey = ref('children');
|
||||
const disabled = ref('disabledKey');
|
||||
|
||||
// 配置属性key
|
||||
watch(() => DefProps.props, (newVal, oldVal) => {
|
||||
labelKey.value = newVal.label ?? 'label'
|
||||
valueKey.value = newVal.value ?? 'value'
|
||||
childrenKey.value = newVal.children ?? 'children'
|
||||
disabled.value = newVal.disabledKey ?? 'disabledKey'
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
})
|
||||
|
||||
// 整理tree数据根据层级分类数组
|
||||
watch(() => DefProps.option, (newVal, oldVal) => {
|
||||
if (newVal) {
|
||||
let tree = treeConfig(newVal);
|
||||
newOption.value = setData(tree);
|
||||
}
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true
|
||||
});
|
||||
|
||||
const isActive = (item, optInx, valueKey) => {
|
||||
if (item._level !== newOption.value.length) {
|
||||
return modelValue.value[optInx] == item[valueKey]
|
||||
} else {
|
||||
if (modelValue.value[item._level - 1] === undefined) {
|
||||
return false
|
||||
} else {
|
||||
return modelValue.value[item._level - 1].includes(item[valueKey])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认tree列表配置,设置父子级关系和层级
|
||||
function treeConfig(arr, parentId = 0, level = 0) {
|
||||
let list = JSON.parse(JSON.stringify(arr))
|
||||
list.forEach(item => {
|
||||
item._parentId = parentId;
|
||||
item._level = level + 1;
|
||||
if (item[childrenKey.value] && item[childrenKey.value].length > 0) {
|
||||
item[childrenKey.value] = treeConfig(item[childrenKey.value], item[valueKey.value], item._level);
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 将tree数据根据层级分类
|
||||
function setData(tree, list = []) {
|
||||
tree.forEach(item => {
|
||||
let obj = {}
|
||||
for (let k in item) {
|
||||
if (k != childrenKey.value) {
|
||||
obj[k] = item[k];
|
||||
}
|
||||
}
|
||||
if (!list[obj._level - 1]) {
|
||||
list[obj._level - 1] = [];
|
||||
}
|
||||
list[obj._level - 1].push(obj);
|
||||
|
||||
if (item[childrenKey.value] && item[childrenKey.value].length > 0) {
|
||||
list = setData(item[childrenKey.value], list)
|
||||
}
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
// 选择
|
||||
function select(value, parentIndex, index, _level) {
|
||||
let arr = JSON.parse(JSON.stringify(modelValue.value))
|
||||
arr[parentIndex] = value;
|
||||
let list = []
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (i <= parentIndex) {
|
||||
list.push(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
let origin_list = modelValue.value
|
||||
let current_list = list
|
||||
|
||||
if (JSON.stringify(origin_list.slice(0, newOption.value.length - 1)) === JSON.stringify(current_list.slice(0,
|
||||
newOption.value.length - 1))) {
|
||||
// 将最后一个层级设置为多选
|
||||
if (_level === newOption.value.length) {
|
||||
if (modelValue.value[_level - 1] === undefined) {
|
||||
modelValue.value[_level - 1] = []
|
||||
}
|
||||
|
||||
|
||||
if (modelValue.value[_level - 1].includes(value)) {
|
||||
modelValue.value[_level - 1] = modelValue.value[_level - 1].filter(e => e != value)
|
||||
} else {
|
||||
modelValue.value[_level - 1].push(value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
modelValue.value = list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Emits('change', modelValue.value, value)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
page,
|
||||
view,
|
||||
text,
|
||||
swiper,
|
||||
swiper-item,
|
||||
image,
|
||||
navigator,
|
||||
icon,
|
||||
form,
|
||||
input,
|
||||
button {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.op-cascader {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
|
||||
.cascader-content {
|
||||
flex: 1;
|
||||
// overflow: hidden;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.cascader-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 8rpx;
|
||||
|
||||
&.active {
|
||||
.cascader-item-label {
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
|
||||
.cascader-item-label {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
color: #364462;
|
||||
font-size: 25rpx;
|
||||
line-height: 92rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
&.active {
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
|
||||
>.icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cascader-content:first-of-type {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,300 +0,0 @@
|
||||
<template>
|
||||
<view class="op-dateTime-picker">
|
||||
<view class="dateTime">
|
||||
<!-- 日期时间 -->
|
||||
<view class="dateTime-input" v-if="type.indexOf('range') == -1">
|
||||
<view class="dateTime-label">{{ label }}:</view>
|
||||
<input v-model="timeVal" type="date" :placeholder="placeholder" disabled @click.stop="openTimeSelect()"></input>
|
||||
</view>
|
||||
<!-- 日期时间范围 -->
|
||||
<template v-if="type.indexOf('range') > -1">
|
||||
<view class="dateTime-input">
|
||||
<view class="dateTime-label">开始{{ label }}:</view>
|
||||
<input v-model="timeVals[0]" type="date" :placeholder="startPlaceholder" disabled @click.stop="openTimeSelect(0)"></input>
|
||||
</view>
|
||||
<view class="dateTime-input">
|
||||
<view class="dateTime-label">结束{{ label }}:</view>
|
||||
<input v-model="timeVals[1]" type="date" :placeholder="endPlaceholder" disabled @click.stop="openTimeSelect(1)"></input>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 下拉选择 -->
|
||||
<view v-if="dateTimeVisible">
|
||||
<picker-view :value="defaultVal" class="pickerView" indicator-class="pickerViewColumn" @change="pickerChange">
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1 || type.indexOf('year') > -1}">
|
||||
<view class="item" v-for="(item,index) in years" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1 || type.indexOf('month') > -1}">
|
||||
<view class="item" v-for="(item,index) in months" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('date') > -1}">
|
||||
<view class="item" v-for="(item,index) in days" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('time') > -1}">
|
||||
<view class="item" v-for="(item,index) in hours" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column :class="{show: type.indexOf('time') > -1}">
|
||||
<view class="item" v-for="(item,index) in minutes" :key="index">{{item}}</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, defineModel, defineProps, defineEmits, watch } from 'vue';
|
||||
const modelVal= defineModel();
|
||||
const Props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'datetime', // 'date、datetime、time、yearmonth、year、daterange、datetimerange、timerange、yearmonthrange、yearrange'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
startPlaceholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
endPlaceholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(["change", "update:modelVal"]);
|
||||
const label = ref("");
|
||||
const timeVal = ref(""); // 日期时间
|
||||
const timeVals = ref([]); // 日期时间范围
|
||||
const dateTimeVisible = ref(false); // 日期时间选择显示隐藏
|
||||
let rangeInx = 0; // 范围值的索引
|
||||
watch(() => modelVal.value, (newVal, oldVal) => {
|
||||
if( Props.type.indexOf("range") > -1 ) {
|
||||
timeVals.value = newVal??[];
|
||||
} else {
|
||||
timeVal.value = newVal
|
||||
}
|
||||
}, { immediate: true, deep: true})
|
||||
|
||||
watch(() => Props.type, (newVal, oldVal) => {
|
||||
switch(newVal) {
|
||||
case 'date':
|
||||
label.value = '日期';
|
||||
break
|
||||
case 'daterange':
|
||||
label.value = '日期';
|
||||
break
|
||||
case 'datetimerange':
|
||||
label.value = '日期时间';
|
||||
break
|
||||
case 'datetime':
|
||||
label.value = '日期时间';
|
||||
break
|
||||
case 'time':
|
||||
label.value = '时间';
|
||||
break
|
||||
case 'timerange':
|
||||
label.value = '时间';
|
||||
break
|
||||
case 'year':
|
||||
label.value = '年份';
|
||||
break
|
||||
case 'yearrange':
|
||||
label.value = '年份';
|
||||
break
|
||||
case 'yearmonth':
|
||||
label.value = '年月';
|
||||
break
|
||||
case 'yearmonthrange':
|
||||
label.value = '年月';
|
||||
break
|
||||
}
|
||||
}, { immediate: true})
|
||||
|
||||
const defaultVal = ref([]); // 下拉时间默认值
|
||||
const years = ref([]); //年
|
||||
const nowYear = new Date().getFullYear();
|
||||
// 设置年份数组
|
||||
for (let i = nowYear - 100; i <= nowYear+100; i++) {
|
||||
if(i < 1970) continue;
|
||||
years.value.push(i.toString());
|
||||
}
|
||||
const months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']; //月
|
||||
const days = ref([]); // 日
|
||||
const hours = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
|
||||
const minutes = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59']
|
||||
|
||||
|
||||
/** 打开日期时间选择
|
||||
* @param { String } key form属性键
|
||||
* @param { String } datetype 时间类型
|
||||
* @param { Number } inx 值在时间范围的索引
|
||||
*/
|
||||
function openTimeSelect(inx=0) {
|
||||
// 设置下拉默认值
|
||||
const data = (Props.type.indexOf("range") > -1)? timeVals.value[inx] :timeVal.value;
|
||||
let now;
|
||||
// 获取当前时间
|
||||
if (Props.type == 'time' || Props.type == 'timerange') {
|
||||
now = data?new Date('2025-01-01 '+data):new Date();
|
||||
} else {
|
||||
now = data?new Date(data):new Date();
|
||||
}
|
||||
// 获取当前年份
|
||||
const currentYear = now.getFullYear();
|
||||
const currentMonth = now.getMonth()+1;
|
||||
const currentDay = now.getDate();
|
||||
const currentHour = now.getHours();
|
||||
const currentMinute = now.getMinutes();
|
||||
// 设置天数数组
|
||||
const dayCount = new Date(currentYear, currentMonth, 0).getDate(); //此月天数
|
||||
days.value = []
|
||||
for (let i = 1; i <= dayCount; i++) {
|
||||
days.value.push(i>9?i.toString():'0'+i);
|
||||
}
|
||||
|
||||
// 设置默认年月日时分
|
||||
setIndex(currentYear, 0, years.value);
|
||||
setIndex(currentMonth, 1, months);
|
||||
setIndex(currentDay, 2, days.value);
|
||||
setIndex(currentHour, 3, hours);
|
||||
setIndex(currentMinute, 4, minutes);
|
||||
|
||||
// 下拉选择显示
|
||||
if(dateTimeVisible.value && rangeInx == inx){
|
||||
dateTimeVisible.value = false;
|
||||
rangeInx = 0;
|
||||
} else {
|
||||
dateTimeVisible.value = false;
|
||||
rangeInx = inx;
|
||||
setTimeout(() => {
|
||||
dateTimeVisible.value = true;
|
||||
}, 60)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据值设置各列索引
|
||||
function setIndex(val, inx, list) {
|
||||
defaultVal.value[inx] = list.findIndex(item => item == val)
|
||||
}
|
||||
|
||||
// 日期时间改变
|
||||
function pickerChange(val) {
|
||||
const Y = years.value[ val.detail.value[0] ];
|
||||
const M = months[ val.detail.value[1] ];
|
||||
const D = days.value[ val.detail.value[2] ];
|
||||
const h = hours[ val.detail.value[3] ];
|
||||
const m = minutes[ val.detail.value[4] ];
|
||||
// 更新天数
|
||||
const dayCount = new Date(Y, M, 0).getDate(); //此月天数
|
||||
if(days.value.length != dayCount){
|
||||
days.value = [];
|
||||
for (let i = 1; i <= dayCount; i++) {
|
||||
days.value.push(i>9?i.toString():'0'+i);
|
||||
}
|
||||
}
|
||||
switch(Props.type) {
|
||||
case 'datetime':
|
||||
timeVal.value = `${Y}-${M}-${D} ${h}:${m}:00`
|
||||
break;
|
||||
case 'datetimerange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}-${D} ${h}:${m}:00`
|
||||
break;
|
||||
case 'date':
|
||||
timeVal.value = `${Y}-${M}-${D}`
|
||||
break;
|
||||
case 'daterange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}-${D}`
|
||||
break;
|
||||
case 'time':
|
||||
timeVal.value = `${h}:${m}:00`
|
||||
break;
|
||||
case 'timerange':
|
||||
timeVals.value[rangeInx] = `${h}:${m}:00`
|
||||
break;
|
||||
case 'yearmonth':
|
||||
timeVal.value = `${Y}-${M}`
|
||||
break;
|
||||
case 'yearmonthrange':
|
||||
timeVals.value[rangeInx] = `${Y}-${M}`
|
||||
break;
|
||||
case 'year':
|
||||
timeVal.value = `${Y}`
|
||||
break;
|
||||
case 'yearrange':
|
||||
timeVals.value[rangeInx] = `${Y}`
|
||||
break;
|
||||
}
|
||||
if(Props.type.indexOf('range') > -1){
|
||||
// 根据大小重新排序
|
||||
Emits('change', timeVals.value);
|
||||
Emits("update:modelVal", timeVals.value)
|
||||
} else {
|
||||
Emits('change', timeVal.value);
|
||||
modelVal.value = timeVal.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
page, view, text, swiper, swiper-item, image, navigator, icon, form, input, button{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.op-dateTime-picker{
|
||||
.dateTime{
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
.dateTime-input{
|
||||
padding: 20rpx 32rpx;
|
||||
display: flex;
|
||||
.dateTime-label{
|
||||
font-size: 28rpx;
|
||||
line-height: 72rpx;
|
||||
margin-right: 10rpx;
|
||||
color: #364462;
|
||||
}
|
||||
input{
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background-color: rgb(249, 249, 249);
|
||||
border-radius: 8rpx;
|
||||
padding: 0 10px;
|
||||
color: rgb(96, 98, 102);
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pickerView{
|
||||
width: 100%;
|
||||
height: 350rpx;
|
||||
background-color: #f2f2f2;
|
||||
:deep(.pickerViewColumn){
|
||||
height: 70rpx;
|
||||
}
|
||||
picker-view-column{
|
||||
flex: 0;
|
||||
.item{
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.show{
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,304 +0,0 @@
|
||||
<template>
|
||||
<view class="drop-down-container">
|
||||
<view class="drop-down-select">
|
||||
<!-- 下拉按钮 -->
|
||||
<view class="select-up">
|
||||
<template v-for="(item, index) in newOption" :key="index">
|
||||
<view class="select-button" @click="openMenu(index)">
|
||||
<text :class="{active: item.menuVisible}">{{item.newTitle??item.title}}</text>
|
||||
<image v-if="item.menuVisible" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAC3SURBVHgBpc9NDoIwEAXgmWI07jhCPYzGJZ5Aj4Iro5fgKHokFv5EQlooIW3aYVoS3gbSTifvA0hk/3hfDvdPkZrD2OXx9pMqg2c/ljffze5VYs3NitiiVqiy/0gAna+3/yo2yy4yJIHibA9QFzHiJM2RTBtvvOaIk40cKQxPJIsIKQxD9Gg8iTwjRK8RTwpDiXZRkkRK+cSBNp9Etlni0Gg+KYwjoiEhZBUsiVan1fhzhQVBQNkBj+1WDGeu7GQAAAAASUVORK5CYII=" ></image>
|
||||
<image v-else src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACtSURBVHgBpZNNDsIgEEaBGNYugVN5A+0NPIKeRD1BeyNnB8ueAJxprMEE6LR9yYTh7wtvgbTWXqWUR7GDGOP7gCNg9WIfF+W9H7AZxHaeIYSXok5r3eEwipWklAC17tRPQQAw4mInVoJ3bvga+AURGxQnpXmi8h2uYq5UDOIq5krFIIKh+KdUDSJqiiWlZlBNsaTEwjnXY6VvPVpnVWtzVmwpscFPfTLGnJfOfQDwZHGVR0KC2QAAAABJRU5ErkJggg==" ></image>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 下拉选项 -->
|
||||
<view class="select-down">
|
||||
<template v-for="(item, index) in newOption" :key="index">
|
||||
<view v-if="item.menuVisible" class="select-menu">
|
||||
<!-- 联级 -->
|
||||
<Op-Cascader v-if="item.type=='cascader'" v-model="form[newOption[index].key]" :option="item.option" :props="item.props" :iconShow="true" maxHeight="600rpx"></Op-Cascader>
|
||||
<!-- 下拉选择 -->
|
||||
<view class="select" v-if="item.type == 'select'">
|
||||
<view class="label"
|
||||
v-for="(itm, inx) in item.option" :key="inx"
|
||||
:class="{ active: itm.value == form[item.key]}"
|
||||
@click="select(itm.value, itm, inx, index)"
|
||||
>
|
||||
{{itm.label}}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 日期时间选择 -->
|
||||
<Op-DateTime-Picker v-if="['date','time','yearmonth','year','datetime','daterange','timerange','yearmonthrange','yearrange','datetimerange'].includes(item.type)" v-model="form[newOption[index].key]" :type="item.type" :placeholder="item.placeholder" :startPlaceholder="item.startPlaceholder" :endPlaceholder="item.endPlaceholder"></Op-DateTime-Picker>
|
||||
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<slot v-if="item.type == 'custom'" :name="newOption[index].key"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<slot v-if="item.type == 'custom'" name="custom-{{index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- 底部确认按钮 -->
|
||||
<view class="drop-down-button">
|
||||
<view @click="reset(index)">重置</view>
|
||||
<view @click="submit(index)">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="drop-down-modal" v-if="modalShow" @click="closeModal"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, defineProps, watch, defineEmits } from 'vue';
|
||||
import OpCascader from '@/components/op-drop-down/components/op-cascader/op-cascader.vue';
|
||||
import OpDateTimePicker from '@/components/op-drop-down/components/op-dateTime-picker/op-dateTime-picker.vue';
|
||||
const form = reactive({});
|
||||
const Props = defineProps({
|
||||
defaultValue: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
option: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
closeOnClickModal:{ // 是否点击模态窗关闭
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const Emits = defineEmits(['update:modelValue', "submit", "reset", "change" ]);
|
||||
const newOption = ref([]); // 所有选项
|
||||
const modalShow = ref(false); // 模态框
|
||||
watch(() => Props.defaultValue, (newVal, oldVal) => {
|
||||
if(newVal){
|
||||
for(let k in newVal){
|
||||
form[k] = newVal[k];
|
||||
}
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
watch(() => Props.option, (newVal, oldVal) => {
|
||||
if(newVal){
|
||||
newOption.value = JSON.parse(JSON.stringify(newVal));
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
|
||||
/** 展开菜单 */
|
||||
function openMenu(inx) {
|
||||
if(newOption.value[inx].menuVisible){
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
} else {
|
||||
newOption.value.forEach((item, index) => {
|
||||
item.menuVisible = index == inx
|
||||
})
|
||||
modalShow.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** select菜单选择
|
||||
* @param { String | Number } val 选中值
|
||||
* @param { Object } row 选中行
|
||||
* @param { Number } inx 选中行索引
|
||||
* @param { Number } parentInx 选中行父级索引
|
||||
*/
|
||||
function select(val, row, inx, parentInx) {
|
||||
form[newOption.value[parentInx].key] = val;
|
||||
}
|
||||
|
||||
|
||||
// 重置
|
||||
function reset(inx) {
|
||||
// 初始话默认值,联级选择需要设置为[],防止双向数据绑定失效
|
||||
if(newOption.value[inx].type == 'cascader' || newOption.value[inx].type.indexOf('range') > -1){
|
||||
form[newOption.value[inx].key] = [];
|
||||
} else {
|
||||
form[newOption.value[inx].key] = undefined;
|
||||
}
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
const data = JSON.parse(JSON.stringify(form));
|
||||
Emits("reset", data);
|
||||
Emits("change", data);
|
||||
}
|
||||
|
||||
// 确认提交
|
||||
function submit(inx) {
|
||||
newOption.value[inx].menuVisible = false;
|
||||
modalShow.value = false;
|
||||
let data = JSON.parse(JSON.stringify(form));
|
||||
if(newOption.value[inx].type.indexOf('range') > -1 ){
|
||||
const key = newOption.value[inx].key;
|
||||
if(data[key] && data[key][0] && data[key][1] ){
|
||||
data[key] = againSort(data[key], newOption.value[inx].type)
|
||||
}
|
||||
}
|
||||
Emits("submit", data);
|
||||
if(JSON.stringify(Props.value) != JSON.stringify(form)){
|
||||
Emits("change", data);
|
||||
}
|
||||
}
|
||||
// 重新排序
|
||||
function againSort(arr, type) {
|
||||
if(!arr[0] || !arr[1]) return arr;
|
||||
let start = 0;
|
||||
let end = 0;
|
||||
if(type.indexOf('date') > -1 && type.indexOf('year') > -1){
|
||||
start = new Date(arr[0]).getTime();
|
||||
end = new Date(arr[1]).getTime();
|
||||
} else if (type == 'timerange') {
|
||||
start = arr[0].split(":").join("");
|
||||
end = arr[1].split(":").join("");
|
||||
}
|
||||
return end > start? arr: [ arr[1], arr[0] ]
|
||||
}
|
||||
|
||||
// 关闭模态窗
|
||||
function closeModal() {
|
||||
if(!Props.closeOnClickModal) return
|
||||
newOption.value.forEach(item => {
|
||||
item.menuVisible = false;
|
||||
})
|
||||
modalShow.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page, view, text, swiper, swiper-item, image, navigator, icon, form, input, button{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.drop-down-container{
|
||||
flex-shrink: 0;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
.drop-down-select{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
.select-up{
|
||||
width: 100%;
|
||||
height: 92rpx;
|
||||
display: flex;
|
||||
.select-button{
|
||||
flex: 1;
|
||||
padding: 24rpx 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
text{
|
||||
font-size: 30rpx;
|
||||
line-height: 44rpx;
|
||||
color: #1A1A1A;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
&.active{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
image{
|
||||
flex-shrink: 0;
|
||||
width: 18rpx;
|
||||
height: 14rpx;
|
||||
margin-left: 22rpx;
|
||||
}
|
||||
&.active{
|
||||
text{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-down{
|
||||
width: 100%;
|
||||
border-top: 1rpx solid rgba(0,0,0,0.1);
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 92rpx;
|
||||
.select{
|
||||
width: 100%;
|
||||
.label{
|
||||
text-align: center;
|
||||
color: #364462;
|
||||
font-size: 32rpx;
|
||||
line-height: 92rpx;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding: 0 10rpx;
|
||||
&.active{
|
||||
color: #468AF7;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dateTime{
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
.dateTime-input{
|
||||
padding: 20rpx 32rpx;
|
||||
display: flex;
|
||||
.dateTime-label{
|
||||
font-size: 28rpx;
|
||||
line-height: 72rpx;
|
||||
margin-right: 10rpx;
|
||||
color: #364462;
|
||||
}
|
||||
input{
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background-color: rgb(249, 249, 249);
|
||||
border-radius: 8rpx;
|
||||
padding: 0 10px;
|
||||
color: rgb(96, 98, 102);
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.drop-down-button{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
view{
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
font-size: rgba(0,0,0,0.9);
|
||||
&:nth-of-type(1){
|
||||
border-top: 1rpx solid rgba(0,0,0,0.1);
|
||||
}
|
||||
&:nth-of-type(2){
|
||||
background-color: #468AF7;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.drop-down-modal{
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,88 +0,0 @@
|
||||
{
|
||||
"id": "op-drop-down",
|
||||
"displayName": "op-drop-down",
|
||||
"version": "1.1.1",
|
||||
"description": "多功能下拉筛选,支持tree联机筛选、时间范围筛选、数组筛选、自定义筛选菜单",
|
||||
"keywords": [
|
||||
"drop-down",
|
||||
"datetimerange",
|
||||
"cascader",
|
||||
"自定义",
|
||||
"下拉筛选"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "u",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u",
|
||||
"app-uvue": "u",
|
||||
"app-harmony": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "y",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
# op-drop-down
|
||||
# 前端UI下拉选择组件,
|
||||
|
||||
### 使用方式
|
||||
|
||||
```html
|
||||
<Op-Drop-Down :defaultValue="form" :option="paramOptions" :closeOnClickModal="true" @change="onChange" @reset="reset">
|
||||
<template #customKey>
|
||||
<button>按钮1</button>
|
||||
<button>按钮2</button>
|
||||
<button>按钮3</button>
|
||||
<button>按钮4</button>
|
||||
</template>
|
||||
</Op-Drop-Down>
|
||||
```
|
||||
```javascript
|
||||
import OpDropDown from '@/uni_modules/op-drop-down/components/op-drop-down/op-drop-down.vue';
|
||||
|
||||
export default {
|
||||
components: { OpDropDown },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
type: [],
|
||||
status: '',
|
||||
time: '',
|
||||
dateTimeRange: [],
|
||||
customKey: ''
|
||||
},
|
||||
paramOptions: [
|
||||
{
|
||||
title: '分类',
|
||||
key: 'type',
|
||||
type: 'cascader',
|
||||
props: { label: 'label', value: 'value', children: 'children', disabled: 'disabled'},
|
||||
option: [
|
||||
{
|
||||
label: '标题1',
|
||||
value: '1',
|
||||
children: [
|
||||
{
|
||||
label: '标题1-1',
|
||||
value: '1-1',
|
||||
children: [
|
||||
{ label: '标题1-1-1', value: '1-1-1' },
|
||||
{ label: '标题1-1-2', value: '1-1-2' },
|
||||
{ label: '标题1-1-3', value: '1-1-3', disabled: true },
|
||||
{ label: '标题1-1-4', value: '1-1-4', disabled: true },
|
||||
{ label: '标题1-1-5', value: '1-1-5' },
|
||||
{ label: '标题1-1-6', value: '1-1-6' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题1-2',
|
||||
value: '1-2',
|
||||
children: [
|
||||
{ label: '标题1-2-1', value: '1-2-1' },
|
||||
{ label: '标题1-2-2', value: '1-2-2' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题2',
|
||||
value: '2',
|
||||
children: [
|
||||
{
|
||||
label: '标题2-1',
|
||||
value: '2-1',
|
||||
children: [
|
||||
{ label: '标题2-1-1', value: '2-1-1' },
|
||||
{ label: '标题2-1-2', value: '2-1-2' }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题2-2',
|
||||
value: '2-2',
|
||||
children: [
|
||||
{ label: '标题2-2-1', value: '2-2-1' },
|
||||
{ label: '标题2-2-2', value: '2-2-2' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '标题3',
|
||||
value: '3',
|
||||
},
|
||||
{
|
||||
label: '标题4',
|
||||
value: '4',
|
||||
},
|
||||
{
|
||||
label: '标题5',
|
||||
value: '5',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
type: 'select',
|
||||
option: [
|
||||
{ label: '在线', value: 'online'},
|
||||
{ label: '离线', value: 'offline'},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
key: 'time',
|
||||
type: 'time',
|
||||
placeholder: '请选择',
|
||||
},
|
||||
{
|
||||
title: '日期范围',
|
||||
key: 'dateTimeRange',
|
||||
type: 'datetimerange',
|
||||
startPlaceholder: '请选择',
|
||||
endPlaceholder: '请选择',
|
||||
},
|
||||
{
|
||||
title: '自定义',
|
||||
key: 'customKey',
|
||||
type: 'custom',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
onChange(val) {
|
||||
this.form = val
|
||||
console.log(val)
|
||||
},
|
||||
reset(val) {
|
||||
this.form = val
|
||||
console.log(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
###组件的属性说明如下:
|
||||
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||
| ---------------- | ------- | ------- | ---- | ------------------------------ |
|
||||
| defaultValue | Object | {} | 是 | 设置整个下拉的默认键值对 |
|
||||
| option | Array | [] | 是 | 下拉菜单配置的数据 |
|
||||
| closeOnClickModal | Boolean | true | 否 | 点击模态窗是否关闭下拉 |
|
||||
|
||||
####option参数说明:
|
||||
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|
||||
| ---------------- | ------- | ------- | ---- | ------------------------------ |
|
||||
| title | String | | 是 | 属性名,显示在页面上 |
|
||||
| key | String | | 是 | 与defaultValue对应的键 |
|
||||
| type | String | 可选cascader、select、date、time、yearmonth、year、datetime、daterange、timerange、yearmonthrange、yearrange、datetimerange、custom | 是 | 下拉类型 |
|
||||
| props | Object | { label: label, value: value, children: children } | 否 | 只针对联级下拉选择项cascader,自定义节点 label、value、options 的字段 |
|
||||
| placeholder | String | | 否 | 时间选择占位文本 |
|
||||
| startPlaceholder | String | | 否 | 时间范围选择占位文本 |
|
||||
| endPlaceholder | String | | 否 | 时间范围选择占位文本 |
|
||||
|
||||
###事件
|
||||
| 事件名称 | 回调参数 | 说明 |
|
||||
| --------- | -------------------- | ------------------------------------------------------------ |
|
||||
| change | (data) => void | 改变事件,data为当前操作后的数据 |
|
||||
| reset | (data) => void | 重置其中一个选中数据,data为当前操作后的数据 |
|
||||
14
pages.json
14
pages.json
@@ -96,13 +96,13 @@
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "订单详情",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
}
|
||||
// {
|
||||
// "path": "pages/order/detail",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "订单详情",
|
||||
// "enablePullDownRefresh": false
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "path": "pages/mall/detail",
|
||||
// "style": {
|
||||
|
||||
@@ -1,342 +0,0 @@
|
||||
<template>
|
||||
<nut-noticebar v-if="!audit" :text="cart_txt" :background="`rgba(251, 248, 220, 1)`"
|
||||
:custom-color="`#D9500B`"></nut-noticebar>
|
||||
<nut-noticebar v-else text="各位员工选定商品后统一给仓库管理员处理" :background="`rgba(251, 248, 220, 1)`"
|
||||
:custom-color="`#D9500B`"></nut-noticebar>
|
||||
|
||||
|
||||
<view class="content">
|
||||
<view class="cart-goods-list">
|
||||
<nut-empty v-if="goods_list.length === 0" description="你还没有添加商品哦">
|
||||
<template #image>
|
||||
<image src="@/static/empty.png" />
|
||||
</template>
|
||||
</nut-empty>
|
||||
|
||||
<nut-checkbox-group v-model="selectedGoodsIds">
|
||||
<view class="cart-goods" v-for="(item, idx) in goods_list" :name="String(item.goods_id)" :key="idx">
|
||||
<nut-checkbox :label="item.goods_id" />
|
||||
<image class="goods-img" :src="item.goods_house.image[0]?.file_path" mode="scaleToFill"
|
||||
@click="navigateTo('/pages/mall/item/index?id=' + item.goods_id)" />
|
||||
<view class="middle" @click="navigateTo('/pages/mall/item/index?id=' + item.goods_id)">
|
||||
<view class="middle-header">
|
||||
<nut-tag custom-color="#1a1a1a">{{ item.goods_house?.degree?.degree_name }}</nut-tag>
|
||||
<text class="title">{{ item.goods_house?.goods_name }}</text>
|
||||
</view>
|
||||
<nut-price :price="item.goods_house?.goods_price" :need-symbol="true" />
|
||||
<view class="middle-footer" @click.stop>
|
||||
<view class="countdown">
|
||||
<nut-countdown :end-time="item.deadline_time * 1000"></nut-countdown>
|
||||
<text class="t">自动移除购物车</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-del-btn" @click="confirmDel(item.goods_id)">
|
||||
<nut-icon name="del2" size="24"></nut-icon>
|
||||
</view>
|
||||
</view>
|
||||
</nut-checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="fixed_footer" v-if="!audit">
|
||||
<view>
|
||||
<nut-checkbox v-model="toggle_all_val" @change="toggleAll()">全选</nut-checkbox>
|
||||
</view>
|
||||
<view style="display: flex; flex-direction: row; gap: 10px">
|
||||
<view class="price">
|
||||
<text v-if="selectedGoodsIds.length > 0">{{ selectedGoodsIds.length }}件 </text>
|
||||
<text>合计:</text>
|
||||
<nut-price :price="total_price" size="large" :need-symbol="true" />
|
||||
</view>
|
||||
<nut-button type="primary" @click="submitOrder()">立即下单</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="fixed_footer" v-else>
|
||||
<view>
|
||||
<nut-checkbox v-model="toggle_all_val" @change="toggleAll()">全选</nut-checkbox>
|
||||
</view>
|
||||
<view style="display: flex; flex-direction: row; gap: 10px">
|
||||
<view class="price">
|
||||
<text v-if="selectedGoodsIds.length > 0">{{ selectedGoodsIds.length }}件 </text>
|
||||
<text>合计:</text>
|
||||
<nut-price :price="total_price" size="large" :need-symbol="true" />
|
||||
</view>
|
||||
<nut-button type="primary" @click="submitOrderGL()">立即下单</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
computed,
|
||||
onMounted,
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
onHide
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
fetchDelCart,
|
||||
fetchCartList
|
||||
} from '@/api/goods';
|
||||
import {
|
||||
fetchConfig
|
||||
} from '@/api/index';
|
||||
import {
|
||||
navigateTo
|
||||
} from '@/utils/helper';
|
||||
|
||||
|
||||
const audit = ref(true);
|
||||
const selectedGoodsIds = ref([]);
|
||||
const goods_cart_ids = ref([]);
|
||||
const cart_txt = ref('')
|
||||
const goods_list = reactive([]);
|
||||
const toggle_all_val = ref(false);
|
||||
const confirmDel = id => {
|
||||
uni.showModal({
|
||||
content: '确定要删除吗?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
delGoodsCart(id);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
const delGoodsCart = id => {
|
||||
fetchDelCart(id).then(res => {
|
||||
let tmp_goods_list = goods_list.filter(item => item.goods_id !== id);
|
||||
goods_list.length = 0;
|
||||
Object.assign(goods_list, tmp_goods_list);
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: goods_list.length.toString()
|
||||
})
|
||||
});
|
||||
};
|
||||
const toggleAll = () => {
|
||||
let goods_ids = goods_list.reduce((acc, item) => {
|
||||
if ('goods_id' in item) {
|
||||
acc.push(item.goods_id);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
if (toggle_all_val.value === true) {
|
||||
selectedGoodsIds.value = goods_ids;
|
||||
} else {
|
||||
selectedGoodsIds.value.length = 0;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
const submitOrderGL = () =>{
|
||||
uni.showToast({
|
||||
title: '仓管已收到清单',
|
||||
icon: 'none',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const submitOrder = () => {
|
||||
if (selectedGoodsIds.value.length === 0) {
|
||||
uni.showToast({
|
||||
title: '请选择商品',
|
||||
icon: 'none',
|
||||
});
|
||||
return;
|
||||
}
|
||||
navigateTo('/pages/order/preview/index?ids=' + selectedGoodsIds.value + '&from=cart');
|
||||
};
|
||||
|
||||
|
||||
|
||||
const init = () => {
|
||||
console.log("手机购物车初始化");
|
||||
|
||||
// 加载配置
|
||||
fetchConfig().then(res => {
|
||||
audit.value = (res.audit === "true");
|
||||
console.log('audit', audit.value);
|
||||
console.log(res.cart_txt);
|
||||
cart_txt.value = res.cart_txt
|
||||
})
|
||||
|
||||
// 进来购物车就清空已经选择的
|
||||
selectedGoodsIds.value = [];
|
||||
toggle_all_val.value = false;
|
||||
console.log("手机购物车选中商品ids", selectedGoodsIds.value);
|
||||
goods_list.length = 0;
|
||||
fetchCartList().then(res => {
|
||||
Object.assign(goods_list, res.list);
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: goods_list.length.toString()
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// 进入购物车就清空已经选择的
|
||||
// selectedGoodsIds.value = [];
|
||||
// toggle_all_val.value = false;
|
||||
|
||||
// console.log('1111', selectedGoodsIds.value);
|
||||
init();
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
console.log("onshow");
|
||||
init();
|
||||
});
|
||||
|
||||
// 计算总价格
|
||||
const total_price = computed(() => {
|
||||
let total_price = 0;
|
||||
console.log('goods_list', goods_list);
|
||||
goods_list.forEach((item, idx) => {
|
||||
if (selectedGoodsIds.value.includes(item.goods_id)) {
|
||||
total_price = parseFloat(total_price) + parseFloat(item.goods_house.goods_price);
|
||||
}
|
||||
});
|
||||
return total_price;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* align-items: center; */
|
||||
// justify-content: center;
|
||||
background-color: #f2f3f5;
|
||||
padding: 20rpx;
|
||||
// height: calc(100% - 140rpx);
|
||||
}
|
||||
|
||||
.fixed_footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 100rpx;
|
||||
background: #fff;
|
||||
width: calc(100% - 40rpx);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-goods-list {
|
||||
background: #fff;
|
||||
display: flex;
|
||||
height: calc(100vh - 230rpx);
|
||||
gap: 30rpx;
|
||||
flex-direction: column;
|
||||
border-radius: 10rpx;
|
||||
--nut-checkbox-label-margin-left: 0rpx;
|
||||
--nut-checkbox-margin-right: 0rpx;
|
||||
overflow-y: auto;
|
||||
// padding-bottom: 20rpx;
|
||||
|
||||
.cart-goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 30rpx;
|
||||
width: calc(100% - 40rpx);
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.goods-img {
|
||||
flex-shrink: 0;
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.middle {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 5rpx;
|
||||
width: 100%;
|
||||
|
||||
.middle-header {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.middle-footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
|
||||
.countdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
--nut-countdown-color: #000;
|
||||
--nut-countdown-font-size: 26rpx;
|
||||
|
||||
.t {
|
||||
color: #000;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除按钮
|
||||
.goods-del-btn {
|
||||
// width: 140rpx;
|
||||
height: 100%;
|
||||
color: #fa2c19;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.touch-dom {
|
||||
width: 100rpx;
|
||||
// height: 100rpx;
|
||||
background: #f52222;
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,429 +0,0 @@
|
||||
<template>
|
||||
|
||||
<view class="page-content">
|
||||
|
||||
|
||||
<nut-searchbar shape="square" placeholder="请输入商品串号" clearable v-model="search_val" input-background="#eee" @search="onSearch"
|
||||
@clear="onClear">
|
||||
<template #rightout>
|
||||
<nut-icon @click="onScan" name="scan2" size="30" custom-color="#000000" />
|
||||
</template>
|
||||
</nut-searchbar>
|
||||
|
||||
<view v-if="goods_ids_with_goods_no_list.length > 0" class="list">
|
||||
<view @click="getGoodsDetail(item.goods_id)" class="list-item" :key="idx"
|
||||
v-for="(item,idx) in goods_ids_with_goods_no_list">
|
||||
{{ item.goods_no }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view v-if="is_show_detail" style=" padding: 20rpx;">
|
||||
<nut-form>
|
||||
<nut-form-item label="名称">
|
||||
<nut-input v-model="form.goods_name" class="nut-input-text" placeholder="请输入名称" type="text" />
|
||||
</nut-form-item>
|
||||
<nut-form-item label="价格">
|
||||
<nut-input v-model="form.goods_price" class="nut-input-text" placeholder="请输入价格" type="nubmer" />
|
||||
</nut-form-item>
|
||||
<nut-form-item label="串号">
|
||||
<nut-input v-model="form.goods_no" class="nut-input-text" placeholder="请输入串号" type="text" readonly disabled/>
|
||||
</nut-form-item>
|
||||
|
||||
|
||||
<nut-form-item label="介绍">
|
||||
<nut-textarea v-model="form.content" autosize placeholder="请输入介绍" type="text" />
|
||||
</nut-form-item>
|
||||
<!-- <nut-form-item label="上架人">
|
||||
<nut-input v-model="form.add_person" class="nut-input-text" placeholder="请输入上架人" type="text" />
|
||||
</nut-form-item> -->
|
||||
<!-- <nut-form-item label="排序">
|
||||
<nut-input v-model="form.goods_sort" class="nut-input-text" placeholder="请输入排序" type="number" />
|
||||
</nut-form-item> -->
|
||||
|
||||
|
||||
|
||||
<!-- <nut-form-item label="状态">
|
||||
<nut-radio-group direction="horizontal" v-model="form.goods_status">
|
||||
<nut-radio label="10">上架</nut-radio>
|
||||
<nut-radio label="20">下架</nut-radio>
|
||||
</nut-radio-group>
|
||||
</nut-form-item> -->
|
||||
|
||||
<nut-form-item>
|
||||
<template v-slot:label>成色</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="show_degree_popup = true">
|
||||
<text>{{form.degree_name}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<nut-form-item>
|
||||
<template v-slot:label>机型</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="show_product_cascader = true">
|
||||
<text>{{form.type_name}},{{form.brand_name}},{{form.product_name}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<nut-form-item>
|
||||
<template v-slot:label>商品图片</template>
|
||||
<template v-slot:default>
|
||||
<shmily-drag-image v-model="form.images" :number=9 :add-image="addGoodsImg"
|
||||
keyName="file_path"></shmily-drag-image></template>
|
||||
</nut-form-item>
|
||||
<nut-form-item>
|
||||
<template v-slot:label>验机报告</template>
|
||||
<template v-slot:default>
|
||||
<view @click="show_report_tags_popup = true">
|
||||
<text>点击勾选</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<view style="align-items: center;text-align: center; padding: 20rpx 0rpx;">
|
||||
<nut-button type="primary" @click="onSubmit">
|
||||
保存修改
|
||||
</nut-button>
|
||||
</view>
|
||||
</nut-form>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
<nut-popup :custom-style="{ height: '50%' }" v-model:visible="show_report_tags_popup" position="bottom"
|
||||
safe-area-inset-bottom>
|
||||
<view style="margin-left: 200rpx; margin-top: 30rpx;">
|
||||
<!-- <DaTree ref="DaTreeRef" :data="report_tags" childrenField="value_list" labelField="name" valueField="id"
|
||||
defaultExpandAll showCheckbox @change="handleTreeChange">
|
||||
</DaTree> -->
|
||||
<DaTree ref="DaTreeRef" :data="report_tags" childrenField="value_list" labelField="name" valueField="id"
|
||||
:defaultExpandedKeys="defaultExpandKeys" showCheckbox @change="handleTreeChange">
|
||||
</DaTree>
|
||||
</view>
|
||||
</nut-popup>
|
||||
|
||||
|
||||
<nut-popup v-model:visible="show_degree_popup" position="bottom" safe-area-inset-bottom>
|
||||
<nut-picker v-model="popup_degree_val" :columns="filter_params.degree_list"
|
||||
:field-names="{text:'degree_name',value:'degree_id'}" title="选择成色" @confirm="onConfirmDegree"
|
||||
@cancel="show_degree_popup = false">
|
||||
</nut-picker>
|
||||
</nut-popup>
|
||||
|
||||
<nut-cascader title="机型选择" v-model:visible="show_product_cascader" v-model="cascader_product_val"
|
||||
@change="onProductChange" @pathChange="onProcutPathChange" text-key="label" value-key="value"
|
||||
:title-ellipsis="false" children-key="children" :options="filter_params.drop_down_options"></nut-cascader>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
onMounted,
|
||||
reactive,
|
||||
ref,
|
||||
toValue
|
||||
} from 'vue';
|
||||
import {
|
||||
fetchGoodsDetail,
|
||||
fetchGoodsList,
|
||||
|
||||
fetchFilterParmas,
|
||||
fetchGoodsReportTags,
|
||||
} from '../../../api/goods';
|
||||
import {
|
||||
getUploadImageUrl
|
||||
} from '../../../api/request';
|
||||
|
||||
import {
|
||||
DaTree
|
||||
} from '@/components/da-tree/index.vue'
|
||||
import {
|
||||
fetchControlEditGoods,
|
||||
fetchControlGoodsDetail,
|
||||
fetchGoodsListByGoodsNo,
|
||||
} from '../../../api/control';
|
||||
import {
|
||||
clearReactiveData
|
||||
} from '../../../utils/helper';
|
||||
|
||||
// 是否显示结果页
|
||||
const is_show_detail = ref(false);
|
||||
// 搜索内容
|
||||
const search_val = ref('')
|
||||
// 商品详情
|
||||
const detail = reactive({})
|
||||
|
||||
const filter_params = reactive({})
|
||||
|
||||
const report_tags = reactive([])
|
||||
|
||||
const all_report_tag_ids = ref([])
|
||||
|
||||
// 默认展开
|
||||
const defaultExpandKeys = ref([0])
|
||||
|
||||
// 显示机型选择
|
||||
const show_product_cascader = ref(false)
|
||||
// 显示成色
|
||||
const show_degree_popup = ref(false)
|
||||
// 显示验机报告
|
||||
const show_report_tags_popup = ref(false)
|
||||
|
||||
|
||||
const popup_degree_val = ref([])
|
||||
|
||||
const cascader_product_val = ref([])
|
||||
const DaTreeRef = ref()
|
||||
|
||||
// 搜索串号列表
|
||||
const goods_ids_with_goods_no_list = ref([])
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
goods_ids_with_goods_no_list.value = [];
|
||||
is_show_detail.value = false;
|
||||
fetchGoodsListByGoodsNo(search_val.value).then(res => {
|
||||
goods_ids_with_goods_no_list.value = res || []
|
||||
})
|
||||
}
|
||||
// 清空搜索内容
|
||||
const onClear = () => {
|
||||
search_val.value = ''
|
||||
is_show_detail.value = false;
|
||||
goods_ids_with_goods_no_list.value = []
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
goods_name: '',
|
||||
goods_id: 0,
|
||||
content: '',
|
||||
goods_price: '',
|
||||
goods_no: '',
|
||||
images: [],
|
||||
// add_person: '',
|
||||
// goods_status: '10',
|
||||
// goods_sort: 0,
|
||||
degree_id: 0,
|
||||
degree_name: '未选择',
|
||||
type_id: 0,
|
||||
type_name: '未选择',
|
||||
brand_id: 0,
|
||||
brand_name: '未选择',
|
||||
product_id: 0,
|
||||
product_name: '未选择',
|
||||
report_tag_ids: []
|
||||
})
|
||||
|
||||
// 获取商品详情
|
||||
const getGoodsDetail = (id) => {
|
||||
fetchControlGoodsDetail(id).then(res => {
|
||||
// 显示商品详情
|
||||
is_show_detail.value = true;
|
||||
Object.assign(detail, res)
|
||||
goods_ids_with_goods_no_list.value = []
|
||||
form.goods_name = res.goods_name
|
||||
form.goods_id = res.goods_id
|
||||
form.content = res.content
|
||||
form.goods_price = res.goods_price
|
||||
form.goods_no = res.goods_no
|
||||
// form.add_person = res.add_person
|
||||
// form.goods_status = res.goods_status.value.toString()
|
||||
// form.goods_sort = res.goods_sort
|
||||
form.degree_id = res.degree?.degree_id ?? 0
|
||||
form.degree_name = res.degree?.degree_name ?? '未选择'
|
||||
form.type_id = res.type?.type_id ?? 0
|
||||
form.type_name = res.type?.name ?? '未选择'
|
||||
form.brand_id = res.brand?.brand_id ?? 0
|
||||
form.brand_name = res.brand?.name ?? '未选择'
|
||||
form.product_id = res.product?.product_id ?? 0
|
||||
form.product_name = res.product?.name ?? '未选择'
|
||||
form.images = []
|
||||
DaTreeRef.value?.setCheckedKeys(all_report_tag_ids.value, false)
|
||||
let tag_ids = (res.report_tag_ids?.split(',') || []).map(Number)
|
||||
form.report_tag_ids = tag_ids
|
||||
DaTreeRef.value?.setCheckedKeys(tag_ids, true)
|
||||
popup_degree_val.value = [res.degree?.degree_id ?? 0]
|
||||
cascader_product_val.value = [res.type?.type_id ?? 0, res.brand?.brand_id ?? 0, res.product?.product_id??0]
|
||||
res.image?.forEach(item => {
|
||||
form.images.push({
|
||||
id: item.image_id,
|
||||
file_path: item.file_path,
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const onProductChange = (...args) => {
|
||||
// console.log(0,...args)
|
||||
// console.log(cascader_product_val)
|
||||
}
|
||||
const handleTreeChange = (allSelectedKeys, currentItem) => {
|
||||
form.report_tag_ids = allSelectedKeys
|
||||
// console.log('handleTreeChange ==>', allSelectedKeys, currentItem)
|
||||
}
|
||||
|
||||
|
||||
|
||||
const onSubmit = () => {
|
||||
fetchControlEditGoods(form).then(res => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '成功'
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: '/pages/control/goods/index',
|
||||
success: res => {},
|
||||
fail: () => {},
|
||||
complete: () => {}
|
||||
});
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
const onProcutPathChange = (args) => {
|
||||
console.log(args);
|
||||
form.type_id = 0
|
||||
form.type_name = ''
|
||||
form.brand_id = 0
|
||||
form.brand_name = ''
|
||||
form.product_id = 0
|
||||
form.product_name = ''
|
||||
if (args.length >= 1 && args[0] !== null) {
|
||||
form.type_id = args[0].value
|
||||
form.type_name = args[0].text
|
||||
}
|
||||
if (args.length >= 2 && args[1] !== null) {
|
||||
form.brand_id = args[1].value
|
||||
form.brand_name = args[1].text
|
||||
}
|
||||
if (args.length >= 3 && args[2] !== null) {
|
||||
form.product_id = args[2].value
|
||||
form.product_name = args[2].text
|
||||
}
|
||||
}
|
||||
const onConfirmDegree = () => {
|
||||
form.degree_id = popup_degree_val.value[0]
|
||||
filter_params.degree_list.forEach(item => {
|
||||
if (item.degree_id === form.degree_id) {
|
||||
form.degree_name = item.degree_name
|
||||
}
|
||||
})
|
||||
show_degree_popup.value = false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 扫码
|
||||
const onScan = () => {
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
success: (res) => {
|
||||
form.goods_no = res.result
|
||||
search_val.value = res.result
|
||||
fetchGoodsListByGoodsNo(res.result).then(res => {
|
||||
if (res.length >= 1) {
|
||||
getGoodsDetail(res[0]?.goods_id)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '扫码失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
fetchFilterParmas(1).then(res => {
|
||||
Object.assign(filter_params, res)
|
||||
filter_params.degree_list.unshift({
|
||||
degree_id: 0,
|
||||
degree_name: '未选择'
|
||||
})
|
||||
console.log(filter_params)
|
||||
})
|
||||
fetchGoodsReportTags().then(res => {
|
||||
Object.assign(report_tags, res)
|
||||
console.log('report_tags',report_tags);
|
||||
all_report_tag_ids.value = []
|
||||
report_tags.forEach((report_tag, i) => {
|
||||
all_report_tag_ids.value.push(report_tag.id)
|
||||
console.log(report_tag.value_list)
|
||||
report_tag.value_list.forEach((val, ii) => {
|
||||
all_report_tag_ids.value.push(val.id)
|
||||
val.value_list.forEach((vv, iii) => {
|
||||
all_report_tag_ids.value.push(vv.id)
|
||||
})
|
||||
})
|
||||
})
|
||||
console.log(all_report_tag_ids)
|
||||
})
|
||||
})
|
||||
|
||||
// 上传商品图片
|
||||
const addGoodsImg = () => {
|
||||
uni.chooseImage({
|
||||
count: 9 - (detail.image?.length || 0),
|
||||
sourceType: ['album', 'camera'],
|
||||
success: res => {
|
||||
res.tempFiles.forEach(file => {
|
||||
uni.uploadFile({
|
||||
url: getUploadImageUrl(),
|
||||
filePath: file.path,
|
||||
name: 'iFile',
|
||||
formData: {
|
||||
group_id: 1,
|
||||
},
|
||||
success: (res) => {
|
||||
let data = JSON.parse(res.data).data
|
||||
form.images.push({
|
||||
id: parseInt(data.file_id),
|
||||
file_path: data.file_path,
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-content {
|
||||
min-height: 100vh;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
background: #ffffff;
|
||||
align-items: center;
|
||||
max-height: 300rpx;
|
||||
overflow-y: scroll;
|
||||
padding: 10px;
|
||||
|
||||
.list-item {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 20rpx 10rpx;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,283 +0,0 @@
|
||||
<template>
|
||||
<page-meta :page-style="'overflow:'+(is_lock_scroll?'hidden':'visible')"></page-meta>
|
||||
|
||||
<IndexCustomNavigationbar :statusBarHeight="statusBarHeight" :windowWidth="windowWidth"
|
||||
:navbarHeight="navbarHeight" :onIndexPageSearch="onIndexPageSearch" :onIndexPageClear="onIndexPageClear"/>
|
||||
<view class="content">
|
||||
<view class="index-content-inner"></view>
|
||||
<view class="index-class-card-box">
|
||||
<view class="index-class-card-body">
|
||||
<view class="navbar-list-content">
|
||||
<view v-for="(item,idx) in nav_list" :key="idx" class="navbar-item-content"
|
||||
@click="navigateTo('/pages/mall/index/index?brand_id='+item.brand_id + '&type_id=' + item.type_id)">
|
||||
<image class="navbar-item-content-img" :src='item.image?.file_path'></image>
|
||||
<view class="navbar-item-content-name">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="index-kefu-card-box">
|
||||
<view class="index-kefu-card-header">
|
||||
<text class="index-kefu-card-header-title">远阳数码售后</text>
|
||||
<text class="index-kefu-card-header-text">7天内有质量问题可退可换</text>
|
||||
<text class="index-kefu-card-header-text">30天内有质量问题只换不修</text>
|
||||
</view>
|
||||
<view class="index-kefu-card-body">
|
||||
<view class="index-kefu-item">
|
||||
<view class="index-kefu-item-profile">
|
||||
<image class="index-kefu-item-profile-avatar" @click="showWechatImg()" src="/static/wechat.jpg"
|
||||
alt="陈汉彬" />
|
||||
<view class="index-kefu-item-profile-info">
|
||||
<view class="index-kefu-item-profile-info-name-phone">
|
||||
<text class="index-kefu-item-profile-info-name-phone-name">陈一鸣</text>
|
||||
<text class="index-kefu-item-profile-info-name-phone-phone">13156107870</text>
|
||||
</view>
|
||||
<view class="index-kefu-item-profile-info-address">山东省济南市天桥区凤凰广场B座803室</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="index-kefu-item">
|
||||
<view class="index-kefu-item-profile">
|
||||
<image class="index-kefu-item-profile-avatar" @click="showWechatImg()" src="/static/wechat.jpg"
|
||||
alt="陈汉阳" />
|
||||
<view class="index-kefu-item-profile-info">
|
||||
<view class="index-kefu-item-profile-info-name-phone">
|
||||
<text class="index-kefu-item-profile-info-name-phone-name">陈一鸣</text>
|
||||
<text class="index-kefu-item-profile-info-name-phone-phone">13156107870</text>
|
||||
</view>
|
||||
<view class="index-kefu-item-profile-info-address">山东省济南市天桥区凤凰广场B座803室</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
<MallFilter :offset-top="topHeight" :is-lock-scroll="isLockScroll" ref="mall_filter" :offset="mall_offset" />
|
||||
|
||||
<!-- <TabBar v-model="currentTab" /> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// import TabBar from '@/components/TabBar/TabBar.vue';
|
||||
|
||||
import {
|
||||
nextTick,
|
||||
onMounted,
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue'
|
||||
import IndexCustomNavigationbar from '@/components/index-custom-navigationbar/index.vue'
|
||||
import MallFilter from '@/components/mall-filter/index.vue'
|
||||
import {
|
||||
fetchFilterParmas,
|
||||
fetchNavList
|
||||
} from '../../api'
|
||||
import {
|
||||
navigateTo,
|
||||
showWechatImg
|
||||
} from '@/utils/helper.ts'
|
||||
import {
|
||||
onPullDownRefresh,
|
||||
onShareAppMessage
|
||||
} from '@dcloudio/uni-app'
|
||||
const statusBarHeight = uni.getWindowInfo().statusBarHeight
|
||||
const windowWidth = uni.getWindowInfo().windowWidth
|
||||
const menu_top = ref(0)
|
||||
const menu_bottom = ref(0)
|
||||
// #ifdef MP
|
||||
const menu_button_info = uni.getMenuButtonBoundingClientRect()
|
||||
menu_top.value = menu_button_info.top
|
||||
menu_bottom.value = menu_button_info.bottom
|
||||
// #endif
|
||||
const navbarHeight = (menu_bottom.value - statusBarHeight) + (menu_top.value - statusBarHeight)
|
||||
const topHeight = navbarHeight + statusBarHeight + 50
|
||||
// const topHeight = navbarHeight + statusBarHeight
|
||||
const nav_list = reactive([])
|
||||
const mall_filter = ref(null)
|
||||
const mall_offset = ref(0)
|
||||
|
||||
// 默认选中第一个tab
|
||||
const currentTab = ref(0);
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
mall_offset.value = topHeight + 48
|
||||
fetchNavList().then(res => {
|
||||
Object.assign(nav_list, res.list)
|
||||
})
|
||||
})
|
||||
onPullDownRefresh(async () => {
|
||||
await mall_filter.value?.refresh()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
|
||||
const onIndexPageSearch = (val) => {
|
||||
mall_filter.value?.filterGoodsName(val)
|
||||
}
|
||||
|
||||
const onIndexPageClear = () => {
|
||||
mall_filter.value?.filterGoodsName('')
|
||||
}
|
||||
|
||||
const is_lock_scroll = ref(false)
|
||||
const isLockScroll = (e) => {
|
||||
is_lock_scroll.value = e
|
||||
/* uni.pageScrollTo({
|
||||
scrollTop: uni.getWindowInfo().windowHeight - mall_filter.value.offsetTop,
|
||||
duration: 0
|
||||
}) */
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* align-items: center; */
|
||||
justify-content: center;
|
||||
background-color: #f2f3f5;
|
||||
}
|
||||
|
||||
.index-content-inner {
|
||||
padding-top: 10px
|
||||
}
|
||||
|
||||
.index-class-card-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
margin: 0 10px 10px;
|
||||
}
|
||||
|
||||
.index-class-card-body {
|
||||
background-color: #fff;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.navbar-list-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navbar-item-content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
width: 20%;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.navbar-item-content-img {
|
||||
width: 37px;
|
||||
height: 37px;
|
||||
}
|
||||
|
||||
.navbar-item-content-name {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************客服******************/
|
||||
|
||||
.index-kefu-card-box {
|
||||
flex: 1;
|
||||
border-radius: 10px;
|
||||
margin: 0 10px 10px;
|
||||
overflow: hidden;
|
||||
background-image: -webkit-gradient(linear, left top, right top, from(#8d7bfb), color-stop(30%, #8d7bfb), to(#8d7bfb));
|
||||
background-image: -webkit-linear-gradient(left, #8d7bfb, #8d7bfb 30%, #8d7bfb);
|
||||
background-image: linear-gradient(90deg, #8d7bfb 0, #8d7bfb 30%, #8d7bfb);
|
||||
}
|
||||
|
||||
.index-kefu-card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
/* 垂直居中 */
|
||||
padding: 5px 20px
|
||||
}
|
||||
|
||||
.index-kefu-card-header-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.index-kefu-card-header-text {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
color: #e7e8ea;
|
||||
}
|
||||
|
||||
.index-kefu-card-body {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.index-kefu-item {
|
||||
width: 49%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #e7e8ea;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-avatar {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-info {
|
||||
text-align: left;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-info-name-phone {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-info-name-phone-name {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-info-name-phone-phone {
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.index-kefu-item-profile-info-address {
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/*************客服******************/
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,717 +0,0 @@
|
||||
<template>
|
||||
<view class="page-content">
|
||||
<z-paging ref="paging" :refresher-enabled="false" :auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false" v-model="dataList" @query="queryList">
|
||||
<view style="z-index: 10000;position: sticky;" :style="'top:0px'">
|
||||
<view class="top-bar">
|
||||
<nut-button type="primary" block plain @click="navigateTo('/pages/index/orderAdd')">
|
||||
新增订单
|
||||
</nut-button>
|
||||
</view>
|
||||
<!-- <nut-searchbar placeholder="请输入商品名称" clearable v-model="state.search_val" input-background="#eee"
|
||||
@search="onSearch" @clear="onClear">
|
||||
<template #rightout>
|
||||
<nut-button type="primary" @click="onSearch">搜索</nut-button>
|
||||
</template>
|
||||
</nut-searchbar> -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<view class="goods-item" v-for="(item, index) in dataList" :key="index">
|
||||
<view class="goods-item-image">
|
||||
<!-- @click="showGoodsImages(item)" -->
|
||||
<image class="goods-item-image-img" :src="getImg(item)" @click="navigateTo('/pages/config/goodsDetail?id=' + item.goods_id)"
|
||||
mode="scaleToFill">
|
||||
</image>
|
||||
</view>
|
||||
<view class="goods-item-content">
|
||||
<!-- @click="navigateTo('/pages/control/goods/edit?id=' + item.goods_id)" -->
|
||||
<view class="goods-item-content-header">
|
||||
<nut-tag custom-color="#1a1a1a">{{ item.degree.degree_name }}</nut-tag>
|
||||
<view>{{item.goods_name}}</view>
|
||||
</view>
|
||||
<!-- @click="navigateTo('/pages/control/goods/edit?id=' + item.goods_id)" -->
|
||||
<view class="goods-item-content-body">
|
||||
<view class="goods-item-content-body-desc">
|
||||
{{item.content}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-item-content-footer">
|
||||
<view style="font-size: 24rpx;color: red;">
|
||||
<text>¥{{item.goods_price}}</text>
|
||||
</view>
|
||||
<view style="font-size: 24rpx;">
|
||||
状态:<text>{{item.status.text}}</text>
|
||||
</view>
|
||||
<view class="goods-item-content-footer-btn">
|
||||
<nut-button size="small" type="primary"
|
||||
v-if="item.status.value == 10 || item.status.value == 20"
|
||||
@click="navigateTo('/pages/config/goodsEdit?id=' + item.goods_id)">
|
||||
编辑商品
|
||||
</nut-button>
|
||||
<nut-button size="small" type="primary" v-if="item.status.value == 40 "
|
||||
@click="navigateTo('/pages/config/goodsEdit?id=' + item.goods_id)">
|
||||
售后(重新上架)
|
||||
</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted,
|
||||
computed
|
||||
} from 'vue'
|
||||
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
} from '@dcloudio/uni-app'
|
||||
// import {
|
||||
|
||||
// fetchFilterParmas
|
||||
// } from '@/api/goods';
|
||||
import {
|
||||
fetchFilterParmas,
|
||||
fetchSysGoodsList
|
||||
} from '@/api/goods';
|
||||
|
||||
import {
|
||||
navigateTo,
|
||||
// switchTab,
|
||||
// goToOtherMiniProgram
|
||||
} from '@/utils/helper';
|
||||
|
||||
|
||||
// 显示商品图片
|
||||
const showGoodsImages = (goods) => {
|
||||
console.log(goods);
|
||||
uni.previewImage({
|
||||
// current: index, // 指定当前显示的图片索引
|
||||
urls: goods?.image.map(e => {
|
||||
return e.file_path
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
const getImg = (goods) => {
|
||||
const url = goods?.image?.[0]?.file_path
|
||||
return url ? url + '?imageView2/1/w/200/h/200' : ''
|
||||
}
|
||||
|
||||
|
||||
// zp
|
||||
const paging = ref(null);
|
||||
// 商品列表
|
||||
const dataList = ref([]);
|
||||
|
||||
// 价格排序
|
||||
const selectPriceSortRef = ref(null);
|
||||
// 成色选择
|
||||
const selectDegreeRef = ref(null);
|
||||
// 机型选择
|
||||
const selectProductRef = ref(null)
|
||||
|
||||
const state = reactive({
|
||||
type_params: [], // 产品类型
|
||||
drop_down_options: [], // 产品类型下的品牌列表
|
||||
o_drop_down_options: [],
|
||||
// 价格排序
|
||||
price_sort_params: [{
|
||||
text: '默认排序',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
text: '价格升序',
|
||||
value: 'ascend'
|
||||
},
|
||||
{
|
||||
text: '价格降序',
|
||||
value: 'descend'
|
||||
}
|
||||
],
|
||||
// 成色所有选项
|
||||
degree_params: [],
|
||||
price_sort: '',
|
||||
price_sort_name: "默认排序",
|
||||
degree_ids: [],
|
||||
degree_name: "成色",
|
||||
product_name: "机型",
|
||||
type_id: 1, // 产品类型id 默认 1 手机
|
||||
type_name: '手机',
|
||||
brand_id: 0, // 品牌id // 默认 0 全部
|
||||
brand_name: '全部',
|
||||
product_ids: [0], // 机型ids 默认 0 全部
|
||||
search_val: '', // 搜索
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 搜索
|
||||
const onSearch = () => {
|
||||
console.log("搜索:", state.search_val);
|
||||
paging.value.reload();
|
||||
|
||||
}
|
||||
// 清空搜索框
|
||||
const onClear = () => {
|
||||
console.log("搜索:", state.search_val);
|
||||
paging.value.reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 机型重置
|
||||
const onResetProduct = () => {
|
||||
console.log("重置产品");
|
||||
state.type_id = 1
|
||||
state.type_name = '手机'
|
||||
state.brand_id = 0
|
||||
state.brand_name = '全部'
|
||||
state.product_ids = [0]
|
||||
state.product_name = '机型'
|
||||
}
|
||||
// 机型确定
|
||||
const onConfirmProduct = () => {
|
||||
console.log("当前产品类型", {
|
||||
"type_id": state.type_id,
|
||||
"type_name": state.type_name,
|
||||
"brand_id": state.brand_id,
|
||||
"brand_name": state.brand_name,
|
||||
"product_ids": state.product_ids,
|
||||
});
|
||||
selectProductRef.value?.toggle(false);
|
||||
// 4. 刷新数据
|
||||
paging.value.reload();
|
||||
}
|
||||
|
||||
// 选择机型
|
||||
const selectProduct = (product) => {
|
||||
if (product.value === 0) {
|
||||
state.product_ids = [0]
|
||||
} else {
|
||||
state.product_ids = state.product_ids.filter(e => e != 0)
|
||||
// 判断是否存在
|
||||
const index = state.product_ids.indexOf(product.value);
|
||||
if (index > -1) {
|
||||
state.product_ids.splice(index, 1); // 存在则删除
|
||||
if (state.product_ids.length === 0) {
|
||||
state.product_ids = [0]
|
||||
}
|
||||
} else {
|
||||
state.product_ids.push(product.value); // 新增
|
||||
}
|
||||
}
|
||||
console.log(product);
|
||||
}
|
||||
|
||||
const productOptions = computed(() => {
|
||||
return state?.o_drop_down_options[state.type_id]?.children[state.brand_id].children
|
||||
})
|
||||
|
||||
|
||||
// 选择品牌
|
||||
const selectBrand = (brand) => {
|
||||
console.log(brand);
|
||||
// 选中的品牌id
|
||||
state.brand_id = brand.value;
|
||||
state.brand_name = brand.label
|
||||
// 品牌下的产品ids
|
||||
state.product_ids = [0];
|
||||
state.product_name = brand.label
|
||||
}
|
||||
// 选择type
|
||||
const selectType = (type) => {
|
||||
console.log(type);
|
||||
// 选中产品类型id
|
||||
state.type_id = type.type_id;
|
||||
state.type_name = type.name;
|
||||
// 选中的品牌id
|
||||
state.brand_id = 0;
|
||||
state.brand_name = '全部';
|
||||
// 品牌下的产品ids
|
||||
state.product_ids = [0];
|
||||
}
|
||||
|
||||
// 选择价格排序
|
||||
const selectPriceSort = (item) => {
|
||||
if (state.price_sort !== item.value) {
|
||||
state.price_sort = item.value
|
||||
state.price_sort_name = item.text
|
||||
} else {
|
||||
state.price_sort_name = '默认排序'
|
||||
state.price_sort = ''
|
||||
}
|
||||
selectPriceSortRef.value?.toggle(false);
|
||||
// 4. 刷新数据
|
||||
paging.value.reload();
|
||||
};
|
||||
|
||||
// 选择成色
|
||||
const selectDegree = (item) => {
|
||||
const index = state.degree_ids.indexOf(item.value);
|
||||
if (index > -1) {
|
||||
state.degree_ids.splice(index, 1);
|
||||
} else {
|
||||
state.degree_ids.push(item.value);
|
||||
}
|
||||
if (state.degree_ids.length > 0) {
|
||||
state.degree_name = '已选' + state.degree_ids.length.toString() + '项'
|
||||
} else {
|
||||
state.degree_name = '成色'
|
||||
}
|
||||
}
|
||||
|
||||
// 重置选择成色
|
||||
const onResetDegree = () => {
|
||||
state.degree_ids = [];
|
||||
state.degree_name = '成色'
|
||||
selectDegreeRef.value?.toggle(false);
|
||||
// 4. 刷新数据
|
||||
paging.value.reload();
|
||||
}
|
||||
// 确认选择成色
|
||||
const onConfirmDegree = () => {
|
||||
if (state.degree_ids.length > 0) {
|
||||
state.degree_name = '已选' + state.degree_ids.length.toString() + '项'
|
||||
} else {
|
||||
state.degree_name = '成色'
|
||||
}
|
||||
selectDegreeRef.value?.toggle(false);
|
||||
// 4. 刷新数据
|
||||
paging.value.reload();
|
||||
}
|
||||
|
||||
|
||||
// 获取列表
|
||||
const queryList = (pageNo, pageSize) => {
|
||||
const params = {
|
||||
pageSize,
|
||||
page: pageNo,
|
||||
price_sort: state.price_sort,
|
||||
degree_ids: state.degree_ids,
|
||||
type_id: state.type_id,
|
||||
brand_id: state.brand_id,
|
||||
product_ids: state.product_ids,
|
||||
search: state.search_val,
|
||||
}
|
||||
console.log(params);
|
||||
fetchSysGoodsList(params).then(res => {
|
||||
console.log('res=>', res.list);
|
||||
paging.value.complete(res.list);
|
||||
|
||||
}).catch(res => {
|
||||
paging.value.complete(false);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const init = () => {
|
||||
console.log('init111');
|
||||
// 加载默认筛选项内容
|
||||
fetchFilterParmas().then(res => {
|
||||
console.log(res);
|
||||
// 处理成色
|
||||
let degree_params = res.degree_list;
|
||||
state.degree_params = degree_params.reduce((it, cit) => {
|
||||
it.push({
|
||||
text: cit.degree_name,
|
||||
value: cit.degree_id
|
||||
});
|
||||
return it;
|
||||
}, state.degree_params) || [];
|
||||
// 产品类型
|
||||
state.type_params = res.type_list
|
||||
// 产品下品牌列表
|
||||
state.drop_down_options = res.drop_down_options
|
||||
state.o_drop_down_options = res.o_drop_down_options
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
console.log("onshow---");
|
||||
console.log('paging.value', paging.value);
|
||||
if (paging.value) {
|
||||
// paging.value.pageNo = 1;
|
||||
paging.value.refresh();
|
||||
// paging.value.refreshToPage(1)
|
||||
// paging.value.reload();
|
||||
}
|
||||
|
||||
});
|
||||
onMounted(() => {
|
||||
init();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-content {
|
||||
min-height: 100vh;
|
||||
background-color: #f2f3f5;
|
||||
--nut-menu-bar-box-shadow: none;
|
||||
--nut-menu-item-content-padding: 20rpx;
|
||||
--nut-menu-item-content-max-height: 900rpx;
|
||||
|
||||
|
||||
|
||||
// --nut-searchbar-input-padding:5px 0 5px 13px;
|
||||
--nut-searchbar-input-height: 40px;
|
||||
}
|
||||
|
||||
:deep(.titleClass) .nut-menu__title-text {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
background: #fff;
|
||||
// padding: 20rpx;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 20rpx 60rpx;
|
||||
// display: flex;
|
||||
// justify-content: space-between;
|
||||
// border-top: 1px solid #eee;
|
||||
// position: sticky;
|
||||
// bottom: 0;
|
||||
// z-index: 999;
|
||||
}
|
||||
|
||||
|
||||
.goods-item {
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
background-color: #ffffff;
|
||||
// border-radius: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
gap: 20rpx;
|
||||
|
||||
.goods-item-image {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
|
||||
.goods-item-image-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item-content {
|
||||
// width: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
/* 首尾贴边,中间均分 */
|
||||
|
||||
// gap: 15px;
|
||||
.goods-item-content-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6rpx 0;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.goods-item-content-body {
|
||||
padding: 6rpx 0;
|
||||
|
||||
.goods-item-content-body-desc {
|
||||
color: #7c7c7c;
|
||||
font-size: 26rpx;
|
||||
/* 关键属性 */
|
||||
display: -webkit-box;
|
||||
/* 使用弹性盒子布局 */
|
||||
-webkit-box-orient: vertical;
|
||||
/* 垂直方向排列 */
|
||||
-webkit-line-clamp: 2;
|
||||
/* 限制显示两行 */
|
||||
overflow: hidden;
|
||||
/* 超出部分隐藏 */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出时显示省略号 */
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item-content-stock {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.goods-item-content-stock-desc {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.goods-item-content-status-desc {
|
||||
font-size: 26rpx;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item-content-footer {
|
||||
padding: 6rpx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
// width: 100%;
|
||||
// flex-direction: row;
|
||||
|
||||
.goods-item-content-footer-btn {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
|
||||
.share-btn {
|
||||
border-radius: 50rpx;
|
||||
border: 2rpx solid red;
|
||||
font-size: 26rpx;
|
||||
align-items: center;
|
||||
height: 54rpx;
|
||||
color: red;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.filter-types {
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
gap: 10rpx;
|
||||
padding: 10rpx;
|
||||
// position: fixed;
|
||||
// top: 0;
|
||||
height: 60rpx;
|
||||
// z-index: 9999;
|
||||
background-color: #fff;
|
||||
border-bottom: 2rpx solid gainsboro;
|
||||
border-top: 2rpx solid gainsboro;
|
||||
|
||||
.filter-type-inner {
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, .05);
|
||||
border-radius: 16rpx;
|
||||
box-sizing: border-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
font-size: 28rpx;
|
||||
gap: 15rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
// image {
|
||||
// height: 22px;
|
||||
// width: 22px;
|
||||
// }
|
||||
}
|
||||
|
||||
.filter-type-inner.active {
|
||||
background-color: rgba(250, 44, 25, .1);
|
||||
color: var(--nutui-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-container {
|
||||
display: flex;
|
||||
|
||||
.tab-pane-inner {
|
||||
height: 600rpx;
|
||||
}
|
||||
|
||||
.tabs-inner {
|
||||
overflow-y: scroll;
|
||||
height: 600rpx;
|
||||
width: 160rpx;
|
||||
background-color: #F5F5F5;
|
||||
|
||||
.tab-inner {
|
||||
display: flex;
|
||||
height: 60rpx;
|
||||
padding: 10rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #F5F5F5;
|
||||
|
||||
text {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-inner-active {
|
||||
// background: #FFF;
|
||||
background-color: rgba(250, 44, 25, .1);
|
||||
color: var(--nutui-color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.degree-inner {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
// gap: 20rpx;
|
||||
gap: 10rpx;
|
||||
// padding: 11px;
|
||||
width: 100%;
|
||||
margin-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.degree-item {
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, .05);
|
||||
border-radius: 10rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
font-size: 26rpx;
|
||||
gap: 10rpx;
|
||||
justify-content: center;
|
||||
min-height: 80rpx;
|
||||
width: calc(50% - 10rpx);
|
||||
}
|
||||
|
||||
.degree-item.active {
|
||||
background-color: rgba(250, 44, 25, .1);
|
||||
color: var(--nutui-color-primary);
|
||||
}
|
||||
|
||||
.product-btns {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 20rpx 0;
|
||||
|
||||
// border-bottom: 2rpx solid gainsboro;
|
||||
// border-top: 2rpx solid gainsboro;
|
||||
|
||||
.reset {
|
||||
flex: 1;
|
||||
|
||||
}
|
||||
|
||||
.confirm {
|
||||
flex: 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.degree-btns {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.reset {
|
||||
flex: 1;
|
||||
/* 重置按钮占 1 份 */
|
||||
}
|
||||
|
||||
.confirm {
|
||||
flex: 2;
|
||||
/* 确认按钮占 2 份 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.main-nav-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 45%;
|
||||
height: 160rpx;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
.phone-button {
|
||||
background: linear-gradient(135deg, #6a5ae0, #8d7bfb);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.parts-button {
|
||||
background: linear-gradient(135deg, #ff6b6b, #ee5253);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-button-bg {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
opacity: 0.2;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.nav-button-icon {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin-right: 20rpx;
|
||||
// border-radius: 20rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.nav-button-content {
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nav-button-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.nav-button-desc {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.85;
|
||||
}
|
||||
</style>
|
||||
@@ -1,618 +0,0 @@
|
||||
<template>
|
||||
<view class="page-content">
|
||||
<view style=" padding: 10rpx;">
|
||||
<view class="title">基础台费 </view>
|
||||
<nut-form>
|
||||
<!-- <nut-form-item>
|
||||
<template v-slot:label>房间</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="visibleRoomsPopup = true">
|
||||
<text>{{form.room_name}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item> -->
|
||||
|
||||
|
||||
<!-- 台费类型、套餐、支付状态 三者在同一行布局 -->
|
||||
<view class="inline-form">
|
||||
<!-- 台费类型选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>结算方式</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="visibleFeeTypePopup = true">
|
||||
<text>{{form.fee_type_name}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<!-- 套餐选择 -->
|
||||
<nut-form-item label-position="top" v-if="form.fee_type === 1 || form.fee_type === 2">
|
||||
<template v-slot:label>选择团购</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="visibleCombosPopup = true">
|
||||
<text>{{form.fee_combo_name}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<!-- 金额输入框 -->
|
||||
<nut-form-item label-position="top" v-else>
|
||||
<template v-slot:label>线下收款</template>
|
||||
<template v-slot:default>
|
||||
<nut-input v-model="form.fee_amount" placeholder="请输入金额" type="number" />
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<!-- 支付状态选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>支付状态</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="openPayStatusPopup('fee')">
|
||||
<text>{{form.fee_pay_status_txt}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
</view>
|
||||
</nut-form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<view class="title">超时收费 </view>
|
||||
<nut-form>
|
||||
<!-- 台费类型、套餐、支付状态 三者在同一行布局 -->
|
||||
<view class="inline-form">
|
||||
<!-- 台费类型选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>时长(小时)</template>
|
||||
<template v-slot:default>
|
||||
<nut-input v-model="form.often" placeholder="请输入小时" type="number" />
|
||||
</template>
|
||||
</nut-form-item>
|
||||
|
||||
<!-- 金额输入框 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>超时金额</template>
|
||||
<template v-slot:default>
|
||||
<nut-input v-model="form.over_amount" placeholder="请输入金额" type="number" />
|
||||
</template>
|
||||
</nut-form-item>
|
||||
|
||||
<!-- 支付状态选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>支付状态</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="openPayStatusPopup('over')">
|
||||
<text>{{form.over_pay_status_txt}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
</view>
|
||||
</nut-form>
|
||||
|
||||
|
||||
<view class="title">商品 </view>
|
||||
<view class="top-bar">
|
||||
<nut-button type="primary" plain size="small" @click="addGoods">新增商品</nut-button>
|
||||
</view>
|
||||
<nut-form>
|
||||
<!-- 台费类型、套餐、支付状态 三者在同一行布局 -->
|
||||
<view class="inline-goods-form" v-for="(item, index) in orderGoods" :key="index">
|
||||
|
||||
<view class="form-row">
|
||||
<!-- 台费类型选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>商品</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="visibleGoodsCascader = true;goodsIndex = index">
|
||||
<text v-if="item.goods_type_name && item.goods_name">
|
||||
{{ item.goods_type_name }} - {{ item.goods_name }}
|
||||
</text>
|
||||
<text v-else>请选择商品</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
|
||||
<!-- 套餐选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>售价</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;">
|
||||
<text>{{item.goods_price}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="form-row">
|
||||
<!-- 支付状态选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>支付状态</template>
|
||||
<template v-slot:default>
|
||||
<view style="color: black;" @click="openPayStatusPopup('goods',index)">
|
||||
<text>{{item.goods_pay_status_txt}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
<!-- 套餐选择 -->
|
||||
<nut-form-item label-position="top">
|
||||
<template v-slot:label>操作</template>
|
||||
<template v-slot:default>
|
||||
<view>
|
||||
<nut-button type="danger" size="mini" @click="removeGoods(index)">删除商品</nut-button>
|
||||
</view>
|
||||
</template>
|
||||
</nut-form-item>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</nut-form>
|
||||
|
||||
<view class="title">订单优惠 </view>
|
||||
|
||||
<nut-form>
|
||||
<nut-form-item>
|
||||
<template v-slot:label>优惠金额</template>
|
||||
<template v-slot:default>
|
||||
<nut-input v-model="form.discount_amount" placeholder="请输入金额" type="number" />
|
||||
</template>
|
||||
</nut-form-item>
|
||||
</nut-form>
|
||||
|
||||
|
||||
|
||||
|
||||
<view style="align-items: center;text-align: center; padding: 20rpx 60rpx;">
|
||||
<nut-button type="primary" block @click="submitForm">
|
||||
保存订单
|
||||
</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<nut-cascader title="商品选择" v-model:visible="visibleGoodsCascader" v-model="cascaderGoodsValue"
|
||||
@change="onGoodsChange" @pathChange="onGoodsPathChange" text-key="label" value-key="value"
|
||||
children-key="children" :options="selectGoods" :title-ellipsis="false" @open="onOpenGoodsCascader"
|
||||
@close="onCloseGoodsCascader"></nut-cascader>
|
||||
|
||||
|
||||
|
||||
<!-- v-model="popupPaymentStatusVal" -->
|
||||
<nut-popup v-model:visible="visiblePaymentStatusPopup" position="bottom" safe-area-inset-bottom>
|
||||
<nut-picker :columns="paymentStatuses" :field-names="{text:'label',value:'value'}" title="选择支付状态"
|
||||
@confirm="onConfirmPaymentStatus" @cancel="visiblePaymentStatusPopup = false">
|
||||
</nut-picker>
|
||||
</nut-popup>
|
||||
|
||||
<nut-popup v-model:visible="visibleCombosPopup" position="bottom" safe-area-inset-bottom>
|
||||
<nut-picker v-model="popupCombosVal" :columns="combos" :field-names="{text:'label',value:'value'}"
|
||||
title="选择团购套餐" @confirm="onConfirmCombos" @cancel="visibleCombosPopup = false">
|
||||
</nut-picker>
|
||||
</nut-popup>
|
||||
<!-- v-model="popupFeeTypeVal" -->
|
||||
<nut-popup v-model:visible="visibleFeeTypePopup" position="bottom" safe-area-inset-bottom>
|
||||
<nut-picker :columns="feeTypes" :field-names="{text:'label',value:'value'}" title="选择结算方式"
|
||||
@confirm="onConfirmFeeType" @cancel="visibleFeeTypePopup = false">
|
||||
</nut-picker>
|
||||
</nut-popup>
|
||||
|
||||
|
||||
<!-- <nut-popup v-model:visible="visibleRoomsPopup" position="bottom" safe-area-inset-bottom>
|
||||
<nut-picker v-model="popupRoomsVal" :columns="rooms" :field-names="{text:'label',value:'value'}"
|
||||
title="选择房间" @confirm="onConfirmRoom" @cancel="visibleRoomsPopup = false">
|
||||
</nut-picker>
|
||||
</nut-popup> -->
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
computed,
|
||||
onMounted,
|
||||
reactive,
|
||||
ref,
|
||||
toValue
|
||||
} from 'vue';
|
||||
|
||||
|
||||
import {
|
||||
fetchCombos,
|
||||
fetchGoods,
|
||||
} from '@/api/index';
|
||||
|
||||
|
||||
// // 选择房间弹窗
|
||||
// const visibleRoomsPopup = ref(false);
|
||||
// // 选中的房间
|
||||
// const popupRoomsVal = ref([])
|
||||
// // 房间列表
|
||||
// const rooms = [{
|
||||
// value: 1,
|
||||
// label: '房间 101'
|
||||
// },
|
||||
// {
|
||||
// value: 2,
|
||||
// label: '房间 102'
|
||||
// },
|
||||
// {
|
||||
// value: 3,
|
||||
// label: '房间 103'
|
||||
// }
|
||||
// ];
|
||||
// // 选择房间
|
||||
// const onConfirmRoom = (selectedValue) => {
|
||||
// console.log(selectedValue);
|
||||
// form.room_name = selectedValue.selectedOptions[0].label
|
||||
// form.room_id = selectedValue.selectedOptions[0].value
|
||||
// console.log(form);
|
||||
// visibleRoomsPopup.value = false
|
||||
// }
|
||||
|
||||
// 选择房间弹窗
|
||||
const visibleFeeTypePopup = ref(false);
|
||||
// 台费结算类型
|
||||
// const popupFeeTypeVal = ref([])
|
||||
// 台费类型选择列表
|
||||
const feeTypes = [{
|
||||
value: 1,
|
||||
label: '美团'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '抖音'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '线下'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
// 选择房间
|
||||
const onConfirmFeeType = (selectedValue) => {
|
||||
console.log(selectedValue);
|
||||
form.fee_type_name = selectedValue.selectedOptions[0].label
|
||||
form.fee_type = selectedValue.selectedOptions[0].value
|
||||
console.log(form);
|
||||
if (form.fee_type !== 3) {
|
||||
getCombos();
|
||||
}
|
||||
|
||||
visibleFeeTypePopup.value = false
|
||||
}
|
||||
|
||||
const getCombos = () => {
|
||||
console.log("获取套餐");
|
||||
fetchCombos({
|
||||
type: form.fee_type
|
||||
}).then(res => {
|
||||
console.log(res);
|
||||
combos.value = res;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 选择套餐弹窗
|
||||
const visibleCombosPopup = ref(false);
|
||||
// 选中的套餐
|
||||
const popupCombosVal = ref([])
|
||||
// 套餐列表
|
||||
const combos = ref([]);
|
||||
// 选择套餐
|
||||
const onConfirmCombos = (selectedValue) => {
|
||||
console.log(selectedValue);
|
||||
form.fee_combo_name = selectedValue.selectedOptions[0].label
|
||||
form.fee_combo_id = selectedValue.selectedOptions[0].value
|
||||
console.log(form);
|
||||
visibleCombosPopup.value = false
|
||||
}
|
||||
// 支付状态弹窗
|
||||
const visiblePaymentStatusPopup = ref(false);
|
||||
// 选中的支付状态
|
||||
const popupPaymentStatusVal = ref([])
|
||||
// 支付类型
|
||||
const popupPaymentTypeVal = ref('')
|
||||
// 支付状态
|
||||
const paymentStatuses = [{
|
||||
value: 1,
|
||||
label: '已付'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '未付'
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '赠送'
|
||||
}
|
||||
];
|
||||
|
||||
const openPayStatusPopup = (type, index = -1) => {
|
||||
popupPaymentTypeVal.value = type
|
||||
goodsPayIndex.value = index // 只有type = goods 生效
|
||||
visiblePaymentStatusPopup.value = true
|
||||
console.log(type);
|
||||
}
|
||||
|
||||
const onConfirmPaymentStatus = (selectedValue) => {
|
||||
|
||||
if (popupPaymentTypeVal.value == 'fee') {
|
||||
form.fee_pay_status_txt = selectedValue.selectedOptions[0].label
|
||||
form.payment_status = selectedValue.selectedOptions[0].value
|
||||
}
|
||||
if (popupPaymentTypeVal.value == 'over') {
|
||||
form.over_pay_status_txt = selectedValue.selectedOptions[0].label
|
||||
form.over_pay_status = selectedValue.selectedOptions[0].value
|
||||
}
|
||||
if (popupPaymentTypeVal.value == 'goods' && goodsPayIndex.value >= 0) {
|
||||
console.log("处理商品支付状态", goodsPayIndex.value);
|
||||
orderGoods.value[goodsPayIndex.value].goods_pay_status_txt = selectedValue.selectedOptions[0].label
|
||||
orderGoods.value[goodsPayIndex.value].goods_pay_status = selectedValue.selectedOptions[0].value
|
||||
}
|
||||
console.log(form);
|
||||
visiblePaymentStatusPopup.value = false
|
||||
popupPaymentTypeVal.value = ''
|
||||
goodsPayIndex.value = -1
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 订单商品列表
|
||||
const orderGoods = ref([
|
||||
// {
|
||||
// goods_type_name: null,
|
||||
// goods_type_id: null,
|
||||
// goods_name: null,
|
||||
// goods_id: null,
|
||||
// goods_price: null,
|
||||
// goods_pay_status: 0,
|
||||
// goods_pay_status_txt: "请选择",
|
||||
// cascader_val: []
|
||||
// },
|
||||
])
|
||||
// 当前操作的商品
|
||||
const goodsPayIndex = ref(0)
|
||||
// 当前操作的商品
|
||||
const goodsIndex = ref(0)
|
||||
// 添加规则
|
||||
const addGoods = () => {
|
||||
console.log(orderGoods.value);
|
||||
orderGoods.value.push({
|
||||
goods_type_name: null,
|
||||
goods_type_id: null,
|
||||
goods_name: null,
|
||||
goods_id: null,
|
||||
goods_price: null,
|
||||
goods_pay_status: 0,
|
||||
goods_pay_status_txt: "请选择",
|
||||
cascader_val: []
|
||||
})
|
||||
}
|
||||
// 删除商品
|
||||
const removeGoods = (index) => {
|
||||
orderGoods.value.splice(index, 1)
|
||||
}
|
||||
// 显示商品选择
|
||||
const visibleGoodsCascader = ref(false)
|
||||
// 商品选中
|
||||
const cascaderGoodsValue = computed(() => {
|
||||
let cascader_val = [];
|
||||
if (goodsIndex.value >= 0) {
|
||||
return orderGoods.value[goodsIndex.value]?.cascader_val ?? []
|
||||
} else {
|
||||
return cascader_val;
|
||||
}
|
||||
});
|
||||
const onGoodsChange = (...args) => {
|
||||
console.log("onGoodsChange", args);
|
||||
}
|
||||
// 选择商品
|
||||
const onGoodsPathChange = (args) => {
|
||||
console.log("onGoodsPathChange", args);
|
||||
console.log("goodsIndex", goodsIndex.value);
|
||||
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
|
||||
orderGoods.value[goodsIndex.value].goods_type_name = null
|
||||
orderGoods.value[goodsIndex.value].goods_type_id = null
|
||||
orderGoods.value[goodsIndex.value].goods_name = null
|
||||
orderGoods.value[goodsIndex.value].goods_id = null
|
||||
orderGoods.value[goodsIndex.value].goods_price = null
|
||||
if (args.length >= 1 && args[0] !== null) {
|
||||
orderGoods.value[goodsIndex.value].goods_type_name = args[0].text
|
||||
orderGoods.value[goodsIndex.value].goods_type_id = args[0].value
|
||||
}
|
||||
if (args.length >= 2 && args[1] !== null) {
|
||||
orderGoods.value[goodsIndex.value].goods_name = args[1].text
|
||||
orderGoods.value[goodsIndex.value].goods_id = args[1].value
|
||||
orderGoods.value[goodsIndex.value].goods_price = args[1].goods_price
|
||||
|
||||
}
|
||||
console.log("orderGoods.value[goodsIndex.value]", orderGoods.value[goodsIndex.value]);
|
||||
}
|
||||
const onCloseGoodsCascader = () => {
|
||||
console.log("onCloseGoodsCascader");
|
||||
console.log("goodsIndex.value", goodsIndex.value);
|
||||
if (orderGoods.value[goodsIndex.value].goods_type_id && orderGoods.value[goodsIndex.value].goods_id) {
|
||||
orderGoods.value[goodsIndex.value].cascader_val = [
|
||||
orderGoods.value[goodsIndex.value].goods_type_id,
|
||||
orderGoods.value[goodsIndex.value].goods_id
|
||||
]
|
||||
}
|
||||
goodsIndex.value = 0
|
||||
console.log("goodsIndex.value", goodsIndex.value);
|
||||
}
|
||||
const onOpenGoodsCascader = () => {
|
||||
console.log("onOpenGoodsCascader");
|
||||
console.log("goodsIndex.value", goodsIndex.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const form = reactive({
|
||||
// room_id: 0,
|
||||
// room_name: '选择房间',
|
||||
|
||||
fee_type: 0,
|
||||
fee_type_name: '选择方式',
|
||||
fee_combo_id: 0, // 套餐费用ID
|
||||
fee_combo_name: '请选择', // 套餐费用名称
|
||||
fee_amount: null, // 线下支付费用
|
||||
fee_pay_status: 0, // 费用支付状态
|
||||
fee_pay_status_txt: '请选择', // 费用支付状态
|
||||
|
||||
over_often: null, // 超时小时
|
||||
over_amount: null, // 超时金额
|
||||
over_pay_status: 0, // 超时支付状态
|
||||
over_pay_status_txt: "请选择", // 超时支付状态
|
||||
|
||||
discount_amount: null, // 优惠金额
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
const selectGoods = ref([])
|
||||
onMounted(() => {
|
||||
fetchGoods().then(res => {
|
||||
selectGoods.value = res;
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 提交表单
|
||||
const submitForm = () => {
|
||||
// const formData = {
|
||||
// room: room.value,
|
||||
// feeType: feeType.value,
|
||||
// selectedPackage: selectedPackage.value,
|
||||
// amount: amount.value,
|
||||
// paymentStatus: paymentStatus.value
|
||||
// };
|
||||
console.log('提交的订单数据:', orderGoods.value);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-content {
|
||||
min-height: 100vh;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
// font-weight: 400;
|
||||
color: #909ca4;
|
||||
}
|
||||
|
||||
.inline-form {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10rpx;
|
||||
/* 在元素之间添加间距 */
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
background: #fff;
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-top: 1px solid #eee;
|
||||
// position: sticky;
|
||||
// bottom: 0;
|
||||
// z-index: 999;
|
||||
}
|
||||
|
||||
/* 每个商品项容器 */
|
||||
.inline-goods-form {
|
||||
// box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 行容器 */
|
||||
.form-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
// .inline-goods-form {
|
||||
// display: flex;
|
||||
// justify-content: space-between;
|
||||
// gap: 10rpx;
|
||||
// /* 在元素之间添加间距 */
|
||||
// }
|
||||
// .inline-goods-form {
|
||||
// display: flex;
|
||||
// flex-wrap: nowrap;
|
||||
// /* 防止换行 */
|
||||
// align-items: flex-start;
|
||||
// gap: 10rpx;
|
||||
// margin-bottom: 20rpx;
|
||||
// padding: 20rpx;
|
||||
// background-color: #f8f9fa;
|
||||
// border-radius: 16rpx;
|
||||
// box-sizing: border-box;
|
||||
// overflow: hidden;
|
||||
// /* 防止溢出 */
|
||||
// }
|
||||
|
||||
// /* 关键:为每个表单项设置适当的flex属性 */
|
||||
// .inline-goods-form .nut-form-item {
|
||||
// flex: 1; /* 平均分配空间 */
|
||||
// min-width: 0; /* 重要:允许内容收缩 */
|
||||
// max-width: 100%; /* 防止溢出 */
|
||||
// word-break: break-word; /* 文本换行 */
|
||||
// overflow: hidden; /* 隐藏溢出内容 */
|
||||
// }
|
||||
|
||||
// /* 确保内部元素不会撑开 */
|
||||
// .inline-goods-form .nut-form-item__body {
|
||||
// width: 100%;
|
||||
// overflow: hidden;
|
||||
// }
|
||||
|
||||
// /* 调整按钮大小 */
|
||||
// .inline-goods-form .nut-button {
|
||||
// max-width: 100%;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
// }
|
||||
|
||||
// .inline-goods-form {
|
||||
// display: flex;
|
||||
// flex-wrap: wrap; /* 确保元素在不足的宽度时换行 */
|
||||
// justify-content: space-between;
|
||||
|
||||
// gap: 10rpx; /* 设置每个表单项之间的间距 */
|
||||
// width: 100%;
|
||||
// // box-sizing: border-box;
|
||||
// }
|
||||
// .inline-goods-form-item-50 {
|
||||
// flex: 0 0 50% !important; /* 第一个表单项占 50% */
|
||||
// }
|
||||
|
||||
// .inline-goods-form-item-25 {
|
||||
// flex: 0 0 25% !important; /* 其他两个表单项各占 25% */
|
||||
// }
|
||||
|
||||
// .inline-item {
|
||||
// flex: 1;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// }
|
||||
</style>
|
||||
@@ -1,379 +0,0 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
|
||||
|
||||
<nut-watermark v-if="detail.status?.value === 10" class="mark1" :z-index="1" content="此商品已下架"></nut-watermark>
|
||||
<nut-watermark v-if="detail.status?.value === 30" class="mark1" :z-index="1" content="此商品已锁定"></nut-watermark>
|
||||
<nut-watermark v-if="detail.status?.value === 40" class="mark1" :z-index="1" content="此商品已售出"></nut-watermark>
|
||||
|
||||
<!-- <nut-watermark v-if="detail.is_locked" class="mark1" :z-index="1" content="此商品被锁单"></nut-watermark> -->
|
||||
|
||||
<swiper class="swiper" circular indicator-dots autoplay>
|
||||
<swiper-item @click="showGoodsImages(idx)" v-for="(item,idx) in detail.image" :key="idx">
|
||||
<image :src="item.file_path" mode="aspectFill"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
|
||||
|
||||
<view class='goods_info'>
|
||||
<nut-cell-group>
|
||||
<view class="price">
|
||||
<text class="unit">¥</text>
|
||||
<text class="value">{{detail.goods_price}}</text>
|
||||
</view>
|
||||
</nut-cell-group>
|
||||
<nut-cell-group>
|
||||
<view class="name">
|
||||
<view class="top">
|
||||
<view class="tag">
|
||||
<text>{{detail.degree?.degree_name}}</text>
|
||||
</view>
|
||||
<text class="title">{{detail.goods_name}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="info">{{detail.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</nut-cell-group>
|
||||
<view class="service">
|
||||
<view class="info">
|
||||
<text class="title">服务</text>
|
||||
<text class="value">{{serviceTxt}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
<view class="bottom-action">
|
||||
<view class="bottom-action-icon">
|
||||
<button plain open-type="contact" style="border:none;border-width: 0;" class="bottom-action-icon-item">
|
||||
<nut-icon name='service'></nut-icon>
|
||||
<text>客服</text>
|
||||
</button>
|
||||
<!-- <button plain style="border:none;border-width: 0;" class="bottom-action-icon-item"
|
||||
@click="switchTab('/pages/cart/index')">
|
||||
<nut-icon name='cart'></nut-icon>
|
||||
<text>购物车</text>
|
||||
</button> -->
|
||||
</view>
|
||||
|
||||
<!-- detail.goods_status?.value === 10 && -->
|
||||
<!-- @click="navigateTo('/pages/order/preview?ids=' + detail.goods_id+'&from=item')" -->
|
||||
<view class="bottom-action-btn" v-if="detail.status?.value === 20">
|
||||
<nut-button type="primary" v-if="!audit" @click="buyNow(detail.goods_id)">立即购买</nut-button>
|
||||
</view>
|
||||
<view class="bottom-action-btn" v-else>
|
||||
<nut-button plain v-if="!audit">暂不支持购买</nut-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
navigateTo,
|
||||
switchTab,
|
||||
goToLoginPage
|
||||
} from '@/utils/helper';
|
||||
import {
|
||||
onShareAppMessage,
|
||||
onShareTimeline,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
fetchGoodsDetail,
|
||||
} from '@/api/goods';
|
||||
|
||||
|
||||
import {
|
||||
fetchGetConfig,
|
||||
} from '@/api/config';
|
||||
|
||||
// 审核模式 默认开启 true
|
||||
const audit = ref(true);
|
||||
const serviceTxt = ref('')
|
||||
|
||||
|
||||
|
||||
const id = ref(0)
|
||||
const detail = reactive({})
|
||||
|
||||
|
||||
onLoad(options => {
|
||||
console.log('init');
|
||||
// 获取配置
|
||||
getConfig()
|
||||
|
||||
// 获取商品详情
|
||||
id.value = options.id
|
||||
fetchGoodsDetail(id.value).then(res => {
|
||||
Object.assign(detail, res)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 立即购买
|
||||
const buyNow = (goodsId) => {
|
||||
let token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
console.log("已经登陆");
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/preview?ids=${goodsId}&from=item`
|
||||
})
|
||||
} else {
|
||||
goToLoginPage(); // 未登陆
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 获取配置
|
||||
const getConfig = () => {
|
||||
fetchGetConfig().then(res => {
|
||||
console.log('getConfig=====>', res)
|
||||
audit.value = res.appConfig.is_audit == 1
|
||||
serviceTxt.value = res.appConfig.service_txt
|
||||
})
|
||||
}
|
||||
|
||||
// 分享给朋友圈
|
||||
onShareTimeline((res) => {
|
||||
return {
|
||||
title: detail.goods_name,
|
||||
path: '/pages/mall/detail?id=' + detail.goods_id,
|
||||
imageUrl: detail.image[0].file_path
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// 分享
|
||||
onShareAppMessage((res) => {
|
||||
return {
|
||||
title: detail.goods_name,
|
||||
path: '/pages/mall/detail?id=' + detail.goods_id,
|
||||
imageUrl: detail.image[0].file_path
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 显示图片
|
||||
const showGoodsImages = (index) => {
|
||||
uni.previewImage({
|
||||
current: index, // 指定当前显示的图片索引
|
||||
urls: detail.image.map(e => {
|
||||
return e.file_path
|
||||
}),
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bottom-action {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 50px;
|
||||
background: #fff;
|
||||
width: calc(100% - 20px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
padding: 5px 10px;
|
||||
|
||||
.bottom-action-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.bottom-action-icon-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
text {
|
||||
color: rgba(0, 0, 0, .5);
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bottom-action-btn {
|
||||
-ms-flex-align: center;
|
||||
-ms-flex-pack: end;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
-webkit-justify-content: flex-end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: calc(100vh - 50px); //100vh;
|
||||
/* align-items: center; */
|
||||
// justify-content: center;
|
||||
background-color: #f2f3f5;
|
||||
// height: calc(100% - 50px);
|
||||
--nut-cell-group-title-color: #000;
|
||||
--nut-collapse-item-padding: 10px 10px 10px 10px;
|
||||
--nut-collapse-wrapper-content-padding: 10px 10px 10px 10px;
|
||||
--nut-collapse-item-color: #000;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.report-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.report-item {
|
||||
.report-item-name {
|
||||
color: rgba(0, 0, 0, .9);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.report-item-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.report-item-content-item {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.count-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 414px;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods_info {
|
||||
padding: 5px;
|
||||
color: #000;
|
||||
|
||||
.price {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
.unit {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-direction: column;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
|
||||
.tag {
|
||||
background: #000;
|
||||
padding: 1px 2px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
border-radius: 2px;
|
||||
|
||||
text {
|
||||
font-size: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
color: rgba(0, 0, 0, .7);
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.service {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: rgba(0, 0, 0, .7);
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.right_icon {
|
||||
background-color: currentColor;
|
||||
mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiPjxwYXRoIGZpbGw9IiMxQTFBMUEiIGQ9Ik0zNTMuODMgMTU4LjE3YTQyLjY3IDQyLjY3IDAgMSAxIDYwLjM0LTYwLjM0bDM4NCAzODRhNDIuNjcgNDIuNjcgMCAwIDEgMCA2MC4zNmwtMzg0IDM4NGE0Mi42NyA0Mi42NyAwIDEgMS02MC4zNC02MC4zNkw3MDcuNjcgNTEyeiIvPjwvc3ZnPg==') 0 0/100% 100% no-repeat;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.report {
|
||||
border-radius: 5px;
|
||||
padding: 1px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,579 +0,0 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
|
||||
|
||||
<nut-watermark v-if="detail.shelves_status?.value === 10" class="mark1" :z-index="1"
|
||||
content="此商品已下架"></nut-watermark>
|
||||
<nut-watermark v-if="detail.shelves_status?.value === 30" class="mark1" :z-index="1"
|
||||
content="此商品已售出"></nut-watermark>
|
||||
|
||||
<nut-watermark v-if="detail.is_locked" class="mark1" :z-index="1" content="此商品被锁单"></nut-watermark>
|
||||
|
||||
<swiper class="swiper" circular indicator-dots autoplay>
|
||||
<swiper-item @click="showGoodsImages(idx)" v-for="(item,idx) in detail.image" :key="idx">
|
||||
<image :src="item.file_path" mode="aspectFill"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class='goods_info'>
|
||||
<nut-cell-group>
|
||||
<view class="price">
|
||||
<text class="unit">¥</text>
|
||||
<text class="value">{{getPrice(detail)}}</text>
|
||||
</view>
|
||||
</nut-cell-group>
|
||||
<nut-cell-group>
|
||||
<view class="name">
|
||||
<view class="top">
|
||||
<view class="tag">
|
||||
<text>{{detail.degree?.degree_name}}</text>
|
||||
</view>
|
||||
<text class="title">{{detail.goods_name}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="info">{{detail.content}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</nut-cell-group>
|
||||
<view class="service">
|
||||
<view class="info">
|
||||
<text class="title">服务</text>
|
||||
<text class="value">{{detail.service_txt}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<nut-cell-group title="验机报告">
|
||||
<nut-collapse v-model="activeNames" @change="onChange">
|
||||
<nut-collapse-item :name="1" icon="rect-down">
|
||||
<template v-slot:title>
|
||||
瑕疵项
|
||||
</template>
|
||||
<template v-slot:value>
|
||||
<view class="count-item">
|
||||
|
||||
<nut-icon name="tips" size="12"
|
||||
custom-color='#ff3535'></nut-icon><text>{{detail.report_tags?.bad_count}}项</text>
|
||||
</view>
|
||||
</template>
|
||||
<view class="report-inner">
|
||||
<view class="report-item" v-for="(item,idx) in detail?.report_tags?.bad" :key="idx">
|
||||
<view class="report-item-name">{{item.name}}</view>
|
||||
<view class="report-item-content">
|
||||
<view class="report-item-content-item" v-for="(iitem,iidx) in item.value_list"
|
||||
:key="iidx">
|
||||
<nut-icon name="tips" size="12" custom-color="#ff3535"></nut-icon>
|
||||
<text>{{iitem.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</nut-collapse-item>
|
||||
<nut-collapse-item :name="2" icon="rect-down">
|
||||
<template v-slot:title>
|
||||
正常项
|
||||
</template>
|
||||
<template v-slot:value>
|
||||
<view class="count-item">
|
||||
<nut-icon name="success" size="12" custom-color="#5dcc30"></nut-icon>
|
||||
<text>{{detail.report_tags?.ok_count}}项</text>
|
||||
</view>
|
||||
</template>
|
||||
<view class="report-inner">
|
||||
<view class="report-item" v-for="(item,idx) in detail?.report_tags?.ok" :key="idx">
|
||||
<view class="report-item-name">{{item.name}}</view>
|
||||
<view class="report-item-content">
|
||||
<view class="report-item-content-item" v-for="(iitem,iidx) in item.value_list"
|
||||
:key="iidx">
|
||||
<nut-icon name="success" size="12" custom-color="#5dcc30"></nut-icon>
|
||||
<text>{{iitem.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</nut-collapse-item>
|
||||
</nut-collapse>
|
||||
</nut-cell-group>
|
||||
</view>
|
||||
<view class="bottom-action">
|
||||
<view class="bottom-action-icon">
|
||||
<button plain open-type="contact" style="border:none;border-width: 0;" class="bottom-action-icon-item">
|
||||
<nut-icon name='service'></nut-icon>
|
||||
<text>客服</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- detail.goods_status?.value === 10 && -->
|
||||
<view class="bottom-action-btn"
|
||||
v-if="detail.shelves_status?.value === 20 && !goods_cart_ids.includes(detail.goods_id) ">
|
||||
<!-- @click="navigateTo('/pages/order/housePreview?ids=' + detail.goods_id+'&from=item')" -->
|
||||
<nut-button type="primary" v-if="!audit" @click="buyNow(detail.goods_id)">立即购买</nut-button>
|
||||
</view>
|
||||
<!-- detail.goods_status?.value === 10 && -->
|
||||
<!-- <view class="bottom-action-btn"
|
||||
v-else-if="detail.shelves_status?.value === 20 && goods_cart_ids.includes(detail.goods_id) && user_goods_cart_ids.includes(detail.goods_id)">
|
||||
<nut-button plain>已在购物车</nut-button>
|
||||
</view> -->
|
||||
|
||||
<view class="bottom-action-btn" v-else>
|
||||
<nut-button plain v-if="!audit">已锁定</nut-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
navigateTo,
|
||||
switchTab,
|
||||
goToLoginPage
|
||||
} from '@/utils/helper';
|
||||
import {
|
||||
onShareAppMessage,
|
||||
onShareTimeline,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
houseFetchCartGoodsIds,
|
||||
houseFetchGoodsDetail
|
||||
} from '@/api/house_goods';
|
||||
import {
|
||||
// fetchOrderbuyNow,
|
||||
houseFetchCheckGoods
|
||||
} from '@/api/house_order';
|
||||
import {
|
||||
fetchGetConfig,
|
||||
fetchGetPriceRules,
|
||||
} from '@/api/config';
|
||||
|
||||
|
||||
// 审核模式
|
||||
const audit = ref(true);
|
||||
// 是否开启整仓调价
|
||||
const isWarehouse = ref(false)
|
||||
|
||||
|
||||
// 单个商品规则列表
|
||||
const singleRule = ref([])
|
||||
// 价格区间规则列表
|
||||
const rangeRule = ref([])
|
||||
// 整仓规则
|
||||
const warehouseRule = reactive({
|
||||
val: 0,
|
||||
val_type: 1,
|
||||
})
|
||||
|
||||
|
||||
// 获取全部调价规则
|
||||
const GetPriceRules = () => {
|
||||
fetchGetPriceRules().then(res => {
|
||||
console.log('res', res);
|
||||
// 区间调价
|
||||
rangeRule.value = res?.range ?? [];
|
||||
// 单机调价
|
||||
singleRule.value = res?.single ?? [];
|
||||
// 整仓调价
|
||||
Object.assign(warehouseRule, res?.warehouse?.[0] ?? {
|
||||
val: 0,
|
||||
val_type: 1,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取价格
|
||||
const getPrice = (goods) => {
|
||||
// 判断是否开启整仓调价
|
||||
if (isWarehouse.value) {
|
||||
console.log("开启整仓调价");
|
||||
// 查找单机器加价规则
|
||||
const list = singleRule.value || singleRule; // 兼容 ref 和 reactive
|
||||
// 根据 product_id == goods_id 找对应规则
|
||||
const rule = list.find(item => item.product_id === goods.goods_id);
|
||||
if (rule) {
|
||||
// 存在单机加价规则
|
||||
const basePrice = Number(goods.goods_price);
|
||||
const val = Number(rule.val);
|
||||
let finalPrice = basePrice;
|
||||
// val_type 处理
|
||||
if (rule.val_type == 1) {
|
||||
finalPrice = basePrice + val; // 固定加价
|
||||
} else if (rule.val_type == 2) {
|
||||
finalPrice = basePrice + (basePrice * val / 100); // 按百分比加
|
||||
}
|
||||
return finalPrice.toFixed(2); // 保留两位小数
|
||||
} else {
|
||||
// 不存在则使用整仓加价
|
||||
const basePrice = Number(goods.goods_price);
|
||||
const val = Number(warehouseRule.val);
|
||||
let finalPrice = basePrice;
|
||||
// val_type 处理
|
||||
if (warehouseRule.val_type == 1) {
|
||||
finalPrice = basePrice + val; // 固定加价
|
||||
} else if (warehouseRule.val_type == 2) {
|
||||
finalPrice = basePrice + (basePrice * val / 100); // 按百分比加
|
||||
}
|
||||
return finalPrice.toFixed(2); // 保留两位小数
|
||||
}
|
||||
} else {
|
||||
console.log("未开启整仓调价");
|
||||
// 查找单机器加价规则
|
||||
const singleRuleList = singleRule.value || singleRule; // 兼容 ref 和 reactive
|
||||
// 根据 product_id == goods_id 找对应规则
|
||||
const oneRule = singleRuleList.find(item => item.product_id === goods.goods_id);
|
||||
if (oneRule) {
|
||||
// 存在单机加价规则
|
||||
const basePrice = Number(goods.goods_price);
|
||||
const val = Number(oneRule.val);
|
||||
let finalPrice = basePrice;
|
||||
// val_type 处理
|
||||
if (oneRule.val_type == 1) {
|
||||
finalPrice = basePrice + val; // 固定加价
|
||||
} else if (oneRule.val_type == 2) {
|
||||
finalPrice = basePrice + (basePrice * val / 100); // 按百分比加
|
||||
}
|
||||
return finalPrice.toFixed(2); // 保留两位小数
|
||||
} else {
|
||||
// 不存在则使用区间加价
|
||||
const basePrice = Number(goods.goods_price)
|
||||
// // 查找区间加价规则
|
||||
const rangeRulelist = rangeRule.value || rangeRule; // 兼容 ref 和 reactive
|
||||
const quRule = rangeRulelist.find(item => {
|
||||
const min = Number(item.min_price)
|
||||
const max = Number(item.max_price)
|
||||
return basePrice >= min && basePrice < max
|
||||
}) || null
|
||||
if (quRule) {
|
||||
// 存在区间加价
|
||||
const val = Number(quRule.val);
|
||||
let finalPrice = basePrice;
|
||||
// val_type 处理
|
||||
if (quRule.val_type == 1) {
|
||||
finalPrice = basePrice + val; // 固定加价
|
||||
} else if (quRule.val_type == 2) {
|
||||
finalPrice = basePrice + (basePrice * val / 100); // 按百分比加
|
||||
}
|
||||
return finalPrice.toFixed(2); // 保留两位小数
|
||||
} else {
|
||||
// 不存在区间加价
|
||||
return basePrice
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const id = ref(0)
|
||||
const detail = reactive({})
|
||||
|
||||
// 用户购物车商品列表
|
||||
const user_goods_cart_ids = ref([]);
|
||||
// 全部购物车商品列表
|
||||
const goods_cart_ids = ref([]);
|
||||
|
||||
|
||||
|
||||
// 立即购买
|
||||
const buyNow = (goodsId) => {
|
||||
let token = uni.getStorageSync('token')
|
||||
if (token) {
|
||||
// 检测是否可以购买
|
||||
houseFetchCheckGoods({
|
||||
goods_id: goodsId,
|
||||
}).then(res => {
|
||||
console.log(res);
|
||||
console.log("已经登陆");
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/housePreview?ids=${goodsId}&from=item`
|
||||
})
|
||||
});
|
||||
} else {
|
||||
goToLoginPage(); // 未登陆
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取配置
|
||||
const getConfig = () => {
|
||||
fetchGetConfig().then(res => {
|
||||
console.log('getConfig=====>', res)
|
||||
audit.value = res.appConfig.is_audit == 1
|
||||
isWarehouse.value = res.appConfig.is_warehouse == 1
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(options => {
|
||||
|
||||
console.log('init');
|
||||
// 获取配置
|
||||
getConfig()
|
||||
GetPriceRules()
|
||||
|
||||
// 获取商品详情
|
||||
id.value = options.id
|
||||
houseFetchGoodsDetail(id.value).then(res => {
|
||||
Object.assign(detail, res)
|
||||
})
|
||||
|
||||
|
||||
// 获取购买记录
|
||||
houseFetchCartGoodsIds().then(res => {
|
||||
console.log(res);
|
||||
user_goods_cart_ids.value = res.user_cart_goods_ids;
|
||||
goods_cart_ids.value = res.cart_goods_ids;
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 分享给朋友圈
|
||||
onShareTimeline((res) => {
|
||||
return {
|
||||
title: detail.goods_name,
|
||||
path: '/pages/mall/houseDetail?id=' + detail.goods_id,
|
||||
imageUrl: detail.image[0].file_path
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
// 分享
|
||||
onShareAppMessage((res) => {
|
||||
return {
|
||||
title: detail.goods_name,
|
||||
path: '/pages/mall/houseDetail?id=' + detail.goods_id,
|
||||
imageUrl: detail.image[0].file_path
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const activeNames = ref([1, 2]);
|
||||
|
||||
const onChange = (modelValue, currName, status) => {
|
||||
// currName: 当前操作的 collapse-item 的 name
|
||||
// status: true 打开 false 关闭
|
||||
console.log(modelValue, currName, status);
|
||||
}
|
||||
|
||||
|
||||
// 显示图片
|
||||
const showGoodsImages = (index) => {
|
||||
uni.previewImage({
|
||||
current: index, // 指定当前显示的图片索引
|
||||
urls: detail.image.map(e => {
|
||||
return e.file_path
|
||||
}),
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bottom-action {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 50px;
|
||||
background: #fff;
|
||||
width: calc(100% - 20px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
padding: 5px 10px;
|
||||
|
||||
.bottom-action-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.bottom-action-icon-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
text {
|
||||
color: rgba(0, 0, 0, .5);
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.bottom-action-btn {
|
||||
-ms-flex-align: center;
|
||||
-ms-flex-pack: end;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
-webkit-justify-content: flex-end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* align-items: center; */
|
||||
// justify-content: center;
|
||||
background-color: #f2f3f5;
|
||||
height: calc(100% - 50px);
|
||||
--nut-cell-group-title-color: #000;
|
||||
--nut-collapse-item-padding: 10px 10px 10px 10px;
|
||||
--nut-collapse-wrapper-content-padding: 10px 10px 10px 10px;
|
||||
--nut-collapse-item-color: #000;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.report-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.report-item {
|
||||
.report-item-name {
|
||||
color: rgba(0, 0, 0, .9);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.report-item-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.report-item-content-item {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.count-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
width: 100%;
|
||||
height: 414px;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.goods_info {
|
||||
padding: 5px;
|
||||
color: #000;
|
||||
|
||||
.price {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
.unit {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-direction: column;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
|
||||
.tag {
|
||||
background: #000;
|
||||
padding: 1px 2px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
border-radius: 2px;
|
||||
|
||||
text {
|
||||
font-size: 10px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
color: rgba(0, 0, 0, .7);
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.service {
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: rgba(0, 0, 0, .7);
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.right_icon {
|
||||
background-color: currentColor;
|
||||
mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiPjxwYXRoIGZpbGw9IiMxQTFBMUEiIGQ9Ik0zNTMuODMgMTU4LjE3YTQyLjY3IDQyLjY3IDAgMSAxIDYwLjM0LTYwLjM0bDM4NCAzODRhNDIuNjcgNDIuNjcgMCAwIDEgMCA2MC4zNmwtMzg0IDM4NGE0Mi42NyA0Mi42NyAwIDEgMS02MC4zNC02MC4zNkw3MDcuNjcgNTEyeiIvPjwvc3ZnPg==') 0 0/100% 100% no-repeat;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.report {
|
||||
border-radius: 5px;
|
||||
padding: 1px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -38,10 +38,10 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="price" v-if="order?.fee_type?.value == 0 || order?.fee_type?.value == 3">
|
||||
{{order?.fee_amount}}
|
||||
¥{{order?.fee_amount}}
|
||||
</view>
|
||||
<view class="price" v-else-if="order?.fee_type?.value == 1 || order?.fee_type?.value == 2 ">
|
||||
{{order?.fee_combo_price}}
|
||||
¥{{order?.fee_combo_price}}
|
||||
</view>
|
||||
<view class="goods-pay-status">
|
||||
{{order?.fee_pay_status?.text}}
|
||||
@@ -56,7 +56,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="price">
|
||||
{{order?.over_amount}}
|
||||
¥{{order?.over_amount}}
|
||||
</view>
|
||||
<view class="goods-pay-status">
|
||||
{{order?.over_pay_status?.text}}
|
||||
@@ -70,7 +70,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="price">
|
||||
{{goods?.goods_price}}
|
||||
¥{{goods?.goods_price}}
|
||||
</view>
|
||||
<view class="goods-pay-status">
|
||||
{{goods?.goods_pay_status_txt}}
|
||||
@@ -78,8 +78,16 @@
|
||||
</view>
|
||||
<view class="footer">
|
||||
<view class="order-inner-price">
|
||||
<view>优惠:<nut-price :price="order.discount_amount" size="normal" :need-symbol="true" /></view>
|
||||
<view>总计:<nut-price :price="order.total_price" size="normal" :need-symbol="true" /></view>
|
||||
<view style="display: flex;">优惠:
|
||||
<view style="color: #fa2c19;font-size: 26rpx;">
|
||||
¥{{order?.discount_amount}}
|
||||
</view>
|
||||
</view>
|
||||
<view style="display: flex;">总计:
|
||||
<view style="color: #fa2c19;font-size: 26rpx;">
|
||||
¥{{order?.discount_amount}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="order.remarks" style="padding-left:20rpx;font-size: 26rpx;">备注</view>
|
||||
<view v-if="order.remarks" class="remarks">
|
||||
|
||||
40
types/contorl.d.ts
vendored
40
types/contorl.d.ts
vendored
@@ -1,40 +0,0 @@
|
||||
export
|
||||
interface EditGoodsParams {
|
||||
/**
|
||||
* 子类
|
||||
*/
|
||||
degree_id: number;
|
||||
/**
|
||||
* 配件id
|
||||
*/
|
||||
goods_id: number;
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
goods_price: number;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
goods_sort: number;
|
||||
/**
|
||||
* 状态 10 上架 20 下架
|
||||
*/
|
||||
goods_status: number;
|
||||
/**
|
||||
* 库存
|
||||
*/
|
||||
goods_stock: number;
|
||||
/**
|
||||
* 图片传递id数组
|
||||
*/
|
||||
images: number[];
|
||||
/**
|
||||
* 机型
|
||||
*/
|
||||
product_id: number;
|
||||
/**
|
||||
* 分类
|
||||
*/
|
||||
type_id: number;
|
||||
[property: string]: any;
|
||||
}
|
||||
8
types/tabbar.d.ts
vendored
8
types/tabbar.d.ts
vendored
@@ -1,8 +0,0 @@
|
||||
|
||||
export interface TabItem {
|
||||
pagePath : string;
|
||||
iconPath : string;
|
||||
selectedIconPath : string;
|
||||
text : string;
|
||||
// badge ?: number | string;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\t// import {ShoppingCartType} from '@/common/constants';\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\t// const shoppingCartType = uni.getStorageSync('SHOPPING_CART_TYPE');\r\n\t\t\t// if (!shoppingCartType) {\r\n\t\t\t// \tuni.setStorageSync('SHOPPING_CART_TYPE', ShoppingCartType.PHONE)\r\n\t\t\t// }\r\n\r\n\t\t\t// uni.hideTabBar()\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\t// uni.hideTabBar()\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n\t@import \"@/uni_modules/nutui-uni/styles/index.scss\";\r\n</style>","import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip = false\nApp.mpType = 'app'\nconst app = new Vue({\n ...App\n})\napp.$mount()\n// #endif\n\n// #ifdef VUE3\nimport { createSSRApp } from 'vue'\nexport function createApp() {\n const app = createSSRApp(App)\n return {\n app\n }\n}\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;;;;;;;;;AAEC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AAOpBA,kBAAAA,MAAA,MAAA,OAAA,iBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAElBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACJM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;;;"}
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\t// import {ShoppingCartType} from '@/common/constants';\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\t// const shoppingCartType = uni.getStorageSync('SHOPPING_CART_TYPE');\r\n\t\t\t// if (!shoppingCartType) {\r\n\t\t\t// \tuni.setStorageSync('SHOPPING_CART_TYPE', ShoppingCartType.PHONE)\r\n\t\t\t// }\r\n\r\n\t\t\t// uni.hideTabBar()\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\t// uni.hideTabBar()\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n\t@import \"@/uni_modules/nutui-uni/styles/index.scss\";\r\n</style>","import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nimport './uni.promisify.adaptor'\nVue.config.productionTip = false\nApp.mpType = 'app'\nconst app = new Vue({\n ...App\n})\napp.$mount()\n// #endif\n\n// #ifdef VUE3\nimport { createSSRApp } from 'vue'\nexport function createApp() {\n const app = createSSRApp(App)\n return {\n app\n }\n}\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;;;;;;;;AAEC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AAOpBA,kBAAAA,MAAA,MAAA,OAAA,iBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAElBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACJM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;;;"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"version":3,"file":"helper.js","sources":["utils/helper.ts"],"sourcesContent":["\n\n\nconst tabbar_pages = [\n\t'/pages/index/index',\n\t'/pages/cart/index',\n\t'/pages/mine/index',\n]\n\n\nexport const navigateTo = (url : string) => {\n\tlet is_tabbar_pages = false\n\ttabbar_pages.forEach(item => {\n\t\tif (url.indexOf(item) === 0) {\n\t\t\tis_tabbar_pages = true\n\t\t}\n\t})\n\tif (is_tabbar_pages) {\n\t\tswitchTab(url)\n\t} else {\n\t\tuni.navigateTo({\n\t\t\turl: url\n\t\t})\n\t}\n\n}\n\nexport const switchTab = (url : string) => {\n\tuni.switchTab({\n\t\turl: url\n\t})\n}\n\nexport const goToLoginPage = (redirect_url ?: string) => {\n\tnavigateTo('/pages/login/index?redirect_url=' + redirect_url)\n}\n\n\n\n// export const showWechatImg = () => {\n// \tuni.previewImage({\n// \t\turls: ['https://qn.19year.cn/20250329143234415bb1067.jpg']\n// \t})\n// }\n// export const showWechatPayImg = () => {\n// \tuni.previewImage({\n// \t\turls: ['https://qn.19year.cn/20250330193232a6aca4595.jpg']\n// \t})\n// }\n\nexport const goToOtherMiniProgram = async () => {\n\ttry {\n\t\tconst res = await fetchConfig();\n\t\tconsole.log('config response:', res);\n\t\tconst appid = res.go_to_app_id;\n\t\tconst path = res.go_to_app_path;\n\t\tuni.navigateToMiniProgram({\n\t\t\tappId: appid, // 替换为目标小程序的appid\n\t\t\tpath: path,\n\t\t\tsuccess(res) {\n\t\t\t\tconsole.log('跳转成功', res);\n\t\t\t},\n\t\t\tfail(err) {\n\t\t\t\tconsole.error('跳转失败', err);\n\t\t\t}\n\t\t});\n\t} catch (error) {\n\t\tconsole.error('Failed to load shop config:', error);\n\t\tuni.showToast({\n\t\t\ttitle: '加载失败',\n\t\t\ticon: 'none'\n\t\t});\n\t}\n}\n\nexport const showPayImgs = async () => {\n try {\n const res = await fetchConfig();\n console.log('config response:', res);\n // 注意这里可能要根据你的实际数据结构调整\n const store_qr_codes = res.pay_qr_code?.map(item => item.url) || [];\n if (store_qr_codes.length === 0) {\n uni.showToast({\n title: '暂无图片',\n icon: 'none'\n });\n return;\n }\n console.log('preview images:', store_qr_codes);\n uni.previewImage({\n urls: store_qr_codes\n });\n } catch (error) {\n console.error('Failed to load shop config:', error);\n uni.showToast({\n title: '加载失败',\n icon: 'none'\n });\n }\n}\n\nexport const clearReactiveData = (obj) => {\n\tfor (const key in obj) {\n\t\tdelete obj[key]\n\t}\n}\n\n\n// export const switchCart = (type) => {\n// \tuni.setStorageSync('SHOPPING_CART_TYPE', type)\n// \tuni.switchTab({ url: '/pages/cart/index' })\n// }"],"names":["uni"],"mappings":";;AAGA,MAAM,eAAe;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACD;AAGa,MAAA,aAAa,CAAC,QAAiB;AAC3C,MAAI,kBAAkB;AACtB,eAAa,QAAQ,CAAQ,SAAA;AAC5B,QAAI,IAAI,QAAQ,IAAI,MAAM,GAAG;AACV,wBAAA;AAAA,IACnB;AAAA,EAAA,CACA;AACD,MAAI,iBAAiB;AACpB,cAAU,GAAG;AAAA,EAAA,OACP;AACNA,kBAAAA,MAAI,WAAW;AAAA,MACd;AAAA,IAAA,CACA;AAAA,EACF;AAED;AAEa,MAAA,YAAY,CAAC,QAAiB;AAC1CA,gBAAAA,MAAI,UAAU;AAAA,IACb;AAAA,EAAA,CACA;AACF;AAEa,MAAA,gBAAgB,CAAC,iBAA2B;AACxD,aAAW,qCAAqC,YAAY;AAC7D;;;"}
|
||||
{"version":3,"file":"helper.js","sources":["utils/helper.ts"],"sourcesContent":["\n\n\nconst tabbar_pages = [\n\t'/pages/index/index',\n\t'/pages/todo/todoList',\n\t'/pages/mine/index',\n]\n\n\nexport const navigateTo = (url : string) => {\n\tlet is_tabbar_pages = false\n\ttabbar_pages.forEach(item => {\n\t\tif (url.indexOf(item) === 0) {\n\t\t\tis_tabbar_pages = true\n\t\t}\n\t})\n\tif (is_tabbar_pages) {\n\t\tswitchTab(url)\n\t} else {\n\t\tuni.navigateTo({\n\t\t\turl: url\n\t\t})\n\t}\n\n}\n\nexport const switchTab = (url : string) => {\n\tuni.switchTab({\n\t\turl: url\n\t})\n}\n\nexport const goToLoginPage = (redirect_url ?: string) => {\n\tnavigateTo('/pages/login/index?redirect_url=' + redirect_url)\n}\n\n\n\n// export const showWechatImg = () => {\n// \tuni.previewImage({\n// \t\turls: ['https://qn.19year.cn/20250329143234415bb1067.jpg']\n// \t})\n// }\n// export const showWechatPayImg = () => {\n// \tuni.previewImage({\n// \t\turls: ['https://qn.19year.cn/20250330193232a6aca4595.jpg']\n// \t})\n// }\n\n// export const goToOtherMiniProgram = async () => {\n// \ttry {\n// \t\tconst res = await fetchConfig();\n// \t\tconsole.log('config response:', res);\n// \t\tconst appid = res.go_to_app_id;\n// \t\tconst path = res.go_to_app_path;\n// \t\tuni.navigateToMiniProgram({\n// \t\t\tappId: appid, // 替换为目标小程序的appid\n// \t\t\tpath: path,\n// \t\t\tsuccess(res) {\n// \t\t\t\tconsole.log('跳转成功', res);\n// \t\t\t},\n// \t\t\tfail(err) {\n// \t\t\t\tconsole.error('跳转失败', err);\n// \t\t\t}\n// \t\t});\n// \t} catch (error) {\n// \t\tconsole.error('Failed to load shop config:', error);\n// \t\tuni.showToast({\n// \t\t\ttitle: '加载失败',\n// \t\t\ticon: 'none'\n// \t\t});\n// \t}\n// }\n\n// export const showPayImgs = async () => {\n// try {\n// const res = await fetchConfig();\n// console.log('config response:', res);\n// // 注意这里可能要根据你的实际数据结构调整\n// const store_qr_codes = res.pay_qr_code?.map(item => item.url) || [];\n// if (store_qr_codes.length === 0) {\n// uni.showToast({\n// title: '暂无图片',\n// icon: 'none'\n// });\n// return;\n// }\n// console.log('preview images:', store_qr_codes);\n// uni.previewImage({\n// urls: store_qr_codes\n// });\n// } catch (error) {\n// console.error('Failed to load shop config:', error);\n// uni.showToast({\n// title: '加载失败',\n// icon: 'none'\n// });\n// }\n// }\n\nexport const clearReactiveData = (obj) => {\n\tfor (const key in obj) {\n\t\tdelete obj[key]\n\t}\n}\n\n\n// export const switchCart = (type) => {\n// \tuni.setStorageSync('SHOPPING_CART_TYPE', type)\n// \tuni.switchTab({ url: '/pages/cart/index' })\n// }"],"names":["uni"],"mappings":";;AAGA,MAAM,eAAe;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACD;AAGa,MAAA,aAAa,CAAC,QAAiB;AAC3C,MAAI,kBAAkB;AACtB,eAAa,QAAQ,CAAQ,SAAA;AAC5B,QAAI,IAAI,QAAQ,IAAI,MAAM,GAAG;AACV,wBAAA;AAAA,IACnB;AAAA,EAAA,CACA;AACD,MAAI,iBAAiB;AACpB,cAAU,GAAG;AAAA,EAAA,OACP;AACNA,kBAAAA,MAAI,WAAW;AAAA,MACd;AAAA,IAAA,CACA;AAAA,EACF;AAED;AAEa,MAAA,YAAY,CAAC,QAAiB;AAC1CA,gBAAAA,MAAI,UAAU;AAAA,IACb;AAAA,EAAA,CACA;AACF;AAEa,MAAA,gBAAgB,CAAC,iBAA2B;AACxD,aAAW,qCAAqC,YAAY;AAC7D;;;"}
|
||||
1
unpackage/dist/dev/mp-weixin/app.js
vendored
1
unpackage/dist/dev/mp-weixin/app.js
vendored
@@ -11,7 +11,6 @@ if (!Math) {
|
||||
"./pages/index/goodsOrderAdd.js";
|
||||
"./pages/mine/index.js";
|
||||
"./pages/order/index.js";
|
||||
"./pages/order/detail.js";
|
||||
}
|
||||
const _sfc_main = {
|
||||
onLaunch: function() {
|
||||
|
||||
3
unpackage/dist/dev/mp-weixin/app.json
vendored
3
unpackage/dist/dev/mp-weixin/app.json
vendored
@@ -8,8 +8,7 @@
|
||||
"pages/index/orderEdit",
|
||||
"pages/index/goodsOrderAdd",
|
||||
"pages/mine/index",
|
||||
"pages/order/index",
|
||||
"pages/order/detail"
|
||||
"pages/order/index"
|
||||
],
|
||||
"window": {
|
||||
"navigationBarTextStyle": "black",
|
||||
|
||||
@@ -30,12 +30,12 @@ const _sfc_main = {
|
||||
let staff_name = common_vendor.index.getStorageSync("staff_name");
|
||||
common_vendor.index.getStorageSync("role");
|
||||
let user_id = common_vendor.index.getStorageSync("uid");
|
||||
common_vendor.index.__f__("log", "at pages/mine/index.vue:188", "staff_name", staff_name);
|
||||
common_vendor.index.__f__("log", "at pages/mine/index.vue:69", "staff_name", staff_name);
|
||||
uid.value = user_id;
|
||||
staffName.value = staff_name;
|
||||
};
|
||||
common_vendor.onShow(() => {
|
||||
common_vendor.index.__f__("log", "at pages/mine/index.vue:203", "init");
|
||||
common_vendor.index.__f__("log", "at pages/mine/index.vue:79", "init");
|
||||
init();
|
||||
});
|
||||
return (_ctx, _cache) => {
|
||||
|
||||
@@ -5,17 +5,15 @@ if (!Array) {
|
||||
const _easycom_nut_tabs2 = common_vendor.resolveComponent("nut-tabs");
|
||||
const _easycom_nut_sticky2 = common_vendor.resolveComponent("nut-sticky");
|
||||
const _easycom_nut_tag2 = common_vendor.resolveComponent("nut-tag");
|
||||
const _easycom_nut_price2 = common_vendor.resolveComponent("nut-price");
|
||||
const _easycom_z_paging2 = common_vendor.resolveComponent("z-paging");
|
||||
(_easycom_nut_tabs2 + _easycom_nut_sticky2 + _easycom_nut_tag2 + _easycom_nut_price2 + _easycom_z_paging2)();
|
||||
(_easycom_nut_tabs2 + _easycom_nut_sticky2 + _easycom_nut_tag2 + _easycom_z_paging2)();
|
||||
}
|
||||
const _easycom_nut_tabs = () => "../../uni_modules/nutui-uni/components/tabs/tabs.js";
|
||||
const _easycom_nut_sticky = () => "../../uni_modules/nutui-uni/components/sticky/sticky.js";
|
||||
const _easycom_nut_tag = () => "../../uni_modules/nutui-uni/components/tag/tag.js";
|
||||
const _easycom_nut_price = () => "../../uni_modules/nutui-uni/components/price/price.js";
|
||||
const _easycom_z_paging = () => "../../uni_modules/z-paging/components/z-paging/z-paging.js";
|
||||
if (!Math) {
|
||||
(_easycom_nut_tabs + _easycom_nut_sticky + _easycom_nut_tag + _easycom_nut_price + _easycom_z_paging)();
|
||||
(_easycom_nut_tabs + _easycom_nut_sticky + _easycom_nut_tag + _easycom_z_paging)();
|
||||
}
|
||||
const _sfc_main = {
|
||||
__name: "index",
|
||||
@@ -46,14 +44,14 @@ const _sfc_main = {
|
||||
paging.value.reload();
|
||||
};
|
||||
const queryList = (pageNo = 1, pageSize = 10) => {
|
||||
common_vendor.index.__f__("log", "at pages/order/index.vue:164", tabs_config[current_tab_idx.value]["status"]);
|
||||
common_vendor.index.__f__("log", "at pages/order/index.vue:172", tabs_config[current_tab_idx.value]["status"]);
|
||||
const params = {
|
||||
page: pageNo,
|
||||
pageSize: 10,
|
||||
status: tabs_config[current_tab_idx.value]["status"]
|
||||
};
|
||||
api_index.fetchOrderList(params).then((res) => {
|
||||
common_vendor.index.__f__("log", "at pages/order/index.vue:171", res);
|
||||
common_vendor.index.__f__("log", "at pages/order/index.vue:179", res);
|
||||
paging.value.complete(res.list);
|
||||
}).catch((res) => {
|
||||
paging.value.complete(false);
|
||||
@@ -168,27 +166,17 @@ const _sfc_main = {
|
||||
f: iidx
|
||||
};
|
||||
}),
|
||||
M: "17a44f9d-11-" + i0 + ",17a44f9d-2",
|
||||
N: common_vendor.p({
|
||||
price: order.discount_amount,
|
||||
size: "normal",
|
||||
["need-symbol"]: true
|
||||
}),
|
||||
O: "17a44f9d-12-" + i0 + ",17a44f9d-2",
|
||||
P: common_vendor.p({
|
||||
price: order.total_price,
|
||||
size: "normal",
|
||||
["need-symbol"]: true
|
||||
}),
|
||||
Q: order.remarks
|
||||
M: common_vendor.t(order == null ? void 0 : order.discount_amount),
|
||||
N: common_vendor.t(order == null ? void 0 : order.discount_amount),
|
||||
O: order.remarks
|
||||
}, order.remarks ? {} : {}, {
|
||||
R: order.remarks
|
||||
P: order.remarks
|
||||
}, order.remarks ? {
|
||||
S: common_vendor.t(order.remarks)
|
||||
Q: common_vendor.t(order.remarks)
|
||||
} : {}, {
|
||||
T: common_vendor.t(order.create_time),
|
||||
U: common_vendor.t((_C = order == null ? void 0 : order.user) == null ? void 0 : _C.staff_name),
|
||||
V: index
|
||||
R: common_vendor.t(order.create_time),
|
||||
S: common_vendor.t((_C = order == null ? void 0 : order.user) == null ? void 0 : _C.staff_name),
|
||||
T: index
|
||||
});
|
||||
}),
|
||||
e: common_vendor.p({
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"nut-tabs": "../../uni_modules/nutui-uni/components/tabs/tabs",
|
||||
"nut-sticky": "../../uni_modules/nutui-uni/components/sticky/sticky",
|
||||
"nut-tag": "../../uni_modules/nutui-uni/components/tag/tag",
|
||||
"nut-price": "../../uni_modules/nutui-uni/components/price/price",
|
||||
"z-paging": "../../uni_modules/z-paging/components/z-paging/z-paging"
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<view class="page-content data-v-17a44f9d"><nut-sticky class="data-v-17a44f9d" u-s="{{['d']}}" u-i="17a44f9d-0" bind:__l="__l"><nut-tabs wx:if="{{c}}" class="data-v-17a44f9d" u-s="{{['titles']}}" u-i="17a44f9d-1,17a44f9d-0" bind:__l="__l" bindupdateModelValue="{{b}}" u-p="{{c}}"><view class="title-list data-v-17a44f9d" slot="titles"><view wx:for="{{a}}" wx:for-item="item" wx:key="b" class="{{['title-item', 'data-v-17a44f9d', item.c && 'tabs-active']}}" bindtap="{{item.d}}"><view class="nut-tabs__titles-item__text data-v-17a44f9d">{{item.a}}</view><view class="item__line data-v-17a44f9d"/></view></view></nut-tabs></nut-sticky><z-paging wx:if="{{i}}" u-s="{{['d']}}" u-r="paging" style="height:88vh" class="order-list r data-v-17a44f9d" bindquery="{{g}}" u-i="17a44f9d-2" bind:__l="__l" bindupdateModelValue="{{h}}" u-p="{{i}}"><view wx:for="{{d}}" wx:for-item="order" wx:key="V" class="order-inner data-v-17a44f9d"><view class="order-inner-header data-v-17a44f9d"><nut-tag wx:if="{{order.a}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.b}}" bind:__l="__l" u-p="{{order.c}}">房间订单</nut-tag><nut-tag wx:else class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.e}}" bind:__l="__l" u-p="{{order.f||''}}">商品订单</nut-tag><nut-tag wx:if="{{order.g}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.i}}" bind:__l="__l" u-p="{{order.j}}">{{order.h}}</nut-tag><nut-tag wx:if="{{order.k}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.m}}" bind:__l="__l" u-p="{{order.n}}">{{order.l}}</nut-tag><nut-tag wx:elif="{{order.o}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.q}}" bind:__l="__l" u-p="{{order.r}}">{{order.p}}</nut-tag></view><view wx:if="{{order.s}}" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{order.w}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.v}}" bind:__l="__l" u-p="{{order.w}}">{{order.t}}</nut-tag><text wx:if="{{order.x}}" class="data-v-17a44f9d" style="margin-left:10rpx"></text><text wx:elif="{{order.y}}" class="data-v-17a44f9d" style="margin-left:10rpx">{{order.z}}</text></view></view><view wx:if="{{order.A}}" class="price data-v-17a44f9d">{{order.B}}</view><view wx:elif="{{order.C}}" class="price data-v-17a44f9d">{{order.D}}</view><view class="goods-pay-status data-v-17a44f9d">{{order.E}}</view></view><view wx:if="{{order.F}}" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{order.H}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.G}}" bind:__l="__l" u-p="{{order.H}}">超时</nut-tag><text class="data-v-17a44f9d" style="margin-left:10rpx">{{order.I}}小时</text></view></view><view class="price data-v-17a44f9d">{{order.J}}</view><view class="goods-pay-status data-v-17a44f9d">{{order.K}}</view></view><view wx:for="{{order.L}}" wx:for-item="goods" wx:key="f" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{e}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{goods.b}}" bind:__l="__l" u-p="{{e}}">{{goods.a}}</nut-tag><text class="data-v-17a44f9d" style="margin-left:10rpx">{{goods.c}}</text></view></view><view class="price data-v-17a44f9d">{{goods.d}}</view><view class="goods-pay-status data-v-17a44f9d">{{goods.e}}</view></view><view class="footer data-v-17a44f9d"><view class="order-inner-price data-v-17a44f9d"><view class="data-v-17a44f9d">优惠:<nut-price wx:if="{{order.N}}" class="data-v-17a44f9d" u-i="{{order.M}}" bind:__l="__l" u-p="{{order.N}}"/></view><view class="data-v-17a44f9d">总计:<nut-price wx:if="{{order.P}}" class="data-v-17a44f9d" u-i="{{order.O}}" bind:__l="__l" u-p="{{order.P}}"/></view></view><view wx:if="{{order.Q}}" class="data-v-17a44f9d" style="padding-left:20rpx;font-size:26rpx">备注</view><view wx:if="{{order.R}}" class="remarks data-v-17a44f9d">{{order.S}}</view><view class="order-inner-price data-v-17a44f9d"><view class="data-v-17a44f9d" style="color:rgba(0, 0, 0, .5);font-size:24rpx">订单时间:{{order.T}}</view><view class="data-v-17a44f9d" style="color:rgba(0, 0, 0, .5);font-size:24rpx">员工:{{order.U}}</view></view></view></view></z-paging></view>
|
||||
<view class="page-content data-v-17a44f9d"><nut-sticky class="data-v-17a44f9d" u-s="{{['d']}}" u-i="17a44f9d-0" bind:__l="__l"><nut-tabs wx:if="{{c}}" class="data-v-17a44f9d" u-s="{{['titles']}}" u-i="17a44f9d-1,17a44f9d-0" bind:__l="__l" bindupdateModelValue="{{b}}" u-p="{{c}}"><view class="title-list data-v-17a44f9d" slot="titles"><view wx:for="{{a}}" wx:for-item="item" wx:key="b" class="{{['title-item', 'data-v-17a44f9d', item.c && 'tabs-active']}}" bindtap="{{item.d}}"><view class="nut-tabs__titles-item__text data-v-17a44f9d">{{item.a}}</view><view class="item__line data-v-17a44f9d"/></view></view></nut-tabs></nut-sticky><z-paging wx:if="{{i}}" u-s="{{['d']}}" u-r="paging" style="height:88vh" class="order-list r data-v-17a44f9d" bindquery="{{g}}" u-i="17a44f9d-2" bind:__l="__l" bindupdateModelValue="{{h}}" u-p="{{i}}"><view wx:for="{{d}}" wx:for-item="order" wx:key="T" class="order-inner data-v-17a44f9d"><view class="order-inner-header data-v-17a44f9d"><nut-tag wx:if="{{order.a}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.b}}" bind:__l="__l" u-p="{{order.c}}">房间订单</nut-tag><nut-tag wx:else class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.e}}" bind:__l="__l" u-p="{{order.f||''}}">商品订单</nut-tag><nut-tag wx:if="{{order.g}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.i}}" bind:__l="__l" u-p="{{order.j}}">{{order.h}}</nut-tag><nut-tag wx:if="{{order.k}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.m}}" bind:__l="__l" u-p="{{order.n}}">{{order.l}}</nut-tag><nut-tag wx:elif="{{order.o}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.q}}" bind:__l="__l" u-p="{{order.r}}">{{order.p}}</nut-tag></view><view wx:if="{{order.s}}" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{order.w}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.v}}" bind:__l="__l" u-p="{{order.w}}">{{order.t}}</nut-tag><text wx:if="{{order.x}}" class="data-v-17a44f9d" style="margin-left:10rpx"></text><text wx:elif="{{order.y}}" class="data-v-17a44f9d" style="margin-left:10rpx">{{order.z}}</text></view></view><view wx:if="{{order.A}}" class="price data-v-17a44f9d"> ¥{{order.B}}</view><view wx:elif="{{order.C}}" class="price data-v-17a44f9d"> ¥{{order.D}}</view><view class="goods-pay-status data-v-17a44f9d">{{order.E}}</view></view><view wx:if="{{order.F}}" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{order.H}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{order.G}}" bind:__l="__l" u-p="{{order.H}}">超时</nut-tag><text class="data-v-17a44f9d" style="margin-left:10rpx">{{order.I}}小时</text></view></view><view class="price data-v-17a44f9d"> ¥{{order.J}}</view><view class="goods-pay-status data-v-17a44f9d">{{order.K}}</view></view><view wx:for="{{order.L}}" wx:for-item="goods" wx:key="f" class="goods-info-row data-v-17a44f9d"><view class="left-text data-v-17a44f9d"><view class="goods-name data-v-17a44f9d"><nut-tag wx:if="{{e}}" class="data-v-17a44f9d" u-s="{{['d']}}" u-i="{{goods.b}}" bind:__l="__l" u-p="{{e}}">{{goods.a}}</nut-tag><text class="data-v-17a44f9d" style="margin-left:10rpx">{{goods.c}}</text></view></view><view class="price data-v-17a44f9d"> ¥{{goods.d}}</view><view class="goods-pay-status data-v-17a44f9d">{{goods.e}}</view></view><view class="footer data-v-17a44f9d"><view class="order-inner-price data-v-17a44f9d"><view class="data-v-17a44f9d" style="display:flex">优惠: <view class="data-v-17a44f9d" style="color:#fa2c19;font-size:26rpx"> ¥{{order.M}}</view></view><view class="data-v-17a44f9d" style="display:flex">总计: <view class="data-v-17a44f9d" style="color:#fa2c19;font-size:26rpx"> ¥{{order.N}}</view></view></view><view wx:if="{{order.O}}" class="data-v-17a44f9d" style="padding-left:20rpx;font-size:26rpx">备注</view><view wx:if="{{order.P}}" class="remarks data-v-17a44f9d">{{order.Q}}</view><view class="order-inner-price data-v-17a44f9d"><view class="data-v-17a44f9d" style="color:rgba(0, 0, 0, .5);font-size:24rpx">订单时间:{{order.R}}</view><view class="data-v-17a44f9d" style="color:rgba(0, 0, 0, .5);font-size:24rpx">员工:{{order.S}}</view></view></view></view></z-paging></view>
|
||||
2
unpackage/dist/dev/mp-weixin/utils/helper.js
vendored
2
unpackage/dist/dev/mp-weixin/utils/helper.js
vendored
@@ -2,7 +2,7 @@
|
||||
const common_vendor = require("../common/vendor.js");
|
||||
const tabbar_pages = [
|
||||
"/pages/index/index",
|
||||
"/pages/cart/index",
|
||||
"/pages/todo/todoList",
|
||||
"/pages/mine/index"
|
||||
];
|
||||
const navigateTo = (url) => {
|
||||
|
||||
100
utils/helper.ts
100
utils/helper.ts
@@ -3,7 +3,7 @@
|
||||
|
||||
const tabbar_pages = [
|
||||
'/pages/index/index',
|
||||
'/pages/cart/index',
|
||||
'/pages/todo/todoList',
|
||||
'/pages/mine/index',
|
||||
]
|
||||
|
||||
@@ -48,56 +48,56 @@ export const goToLoginPage = (redirect_url ?: string) => {
|
||||
// })
|
||||
// }
|
||||
|
||||
export const goToOtherMiniProgram = async () => {
|
||||
try {
|
||||
const res = await fetchConfig();
|
||||
console.log('config response:', res);
|
||||
const appid = res.go_to_app_id;
|
||||
const path = res.go_to_app_path;
|
||||
uni.navigateToMiniProgram({
|
||||
appId: appid, // 替换为目标小程序的appid
|
||||
path: path,
|
||||
success(res) {
|
||||
console.log('跳转成功', res);
|
||||
},
|
||||
fail(err) {
|
||||
console.error('跳转失败', err);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load shop config:', error);
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
// export const goToOtherMiniProgram = async () => {
|
||||
// try {
|
||||
// const res = await fetchConfig();
|
||||
// console.log('config response:', res);
|
||||
// const appid = res.go_to_app_id;
|
||||
// const path = res.go_to_app_path;
|
||||
// uni.navigateToMiniProgram({
|
||||
// appId: appid, // 替换为目标小程序的appid
|
||||
// path: path,
|
||||
// success(res) {
|
||||
// console.log('跳转成功', res);
|
||||
// },
|
||||
// fail(err) {
|
||||
// console.error('跳转失败', err);
|
||||
// }
|
||||
// });
|
||||
// } catch (error) {
|
||||
// console.error('Failed to load shop config:', error);
|
||||
// uni.showToast({
|
||||
// title: '加载失败',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
export const showPayImgs = async () => {
|
||||
try {
|
||||
const res = await fetchConfig();
|
||||
console.log('config response:', res);
|
||||
// 注意这里可能要根据你的实际数据结构调整
|
||||
const store_qr_codes = res.pay_qr_code?.map(item => item.url) || [];
|
||||
if (store_qr_codes.length === 0) {
|
||||
uni.showToast({
|
||||
title: '暂无图片',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
console.log('preview images:', store_qr_codes);
|
||||
uni.previewImage({
|
||||
urls: store_qr_codes
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to load shop config:', error);
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
// export const showPayImgs = async () => {
|
||||
// try {
|
||||
// const res = await fetchConfig();
|
||||
// console.log('config response:', res);
|
||||
// // 注意这里可能要根据你的实际数据结构调整
|
||||
// const store_qr_codes = res.pay_qr_code?.map(item => item.url) || [];
|
||||
// if (store_qr_codes.length === 0) {
|
||||
// uni.showToast({
|
||||
// title: '暂无图片',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// console.log('preview images:', store_qr_codes);
|
||||
// uni.previewImage({
|
||||
// urls: store_qr_codes
|
||||
// });
|
||||
// } catch (error) {
|
||||
// console.error('Failed to load shop config:', error);
|
||||
// uni.showToast({
|
||||
// title: '加载失败',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
export const clearReactiveData = (obj) => {
|
||||
for (const key in obj) {
|
||||
|
||||
Reference in New Issue
Block a user