mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-03-29 16:50:52 +00:00
up
This commit is contained in:
parent
504b4c96a8
commit
0c0e65be1c
@ -211,13 +211,23 @@ export function setShopDeliveryConfig(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/setConfig`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/********************************* 配送员 ***************************************/
|
||||
/**
|
||||
* 获取 配送员列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDelivery(params: Record<string, any>) {
|
||||
return request.get('shop/delivery/staff', { params })
|
||||
return request.get('shop/shop_delivery/staff', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 配送员列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliverList(params: Record<string, any>) {
|
||||
return request.get('shop/shop_delivery/staff/list', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,7 +236,7 @@ export function getShopDelivery(params: Record<string, any>) {
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliverInfo(staff_id: number) {
|
||||
return request.get(`shop/delivery/staff/${ staff_id }`);
|
||||
return request.get(`shop/shop_delivery/staff/${ staff_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +245,7 @@ export function getShopDeliverInfo(staff_id: number) {
|
||||
* @returns
|
||||
*/
|
||||
export function addShopDeliver(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/staff', params, { showSuccessMessage: true })
|
||||
return request.post('shop/shop_delivery/staff', params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +254,7 @@ export function addShopDeliver(params: Record<string, any>) {
|
||||
* @returns
|
||||
*/
|
||||
export function editShopDeliver(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/staff/${ params.deliver_id }`, params, { showSuccessMessage: true })
|
||||
return request.put(`shop/shop_delivery/staff/${ params.deliver_id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,15 +263,48 @@ export function editShopDeliver(params: Record<string, any>) {
|
||||
* @returns
|
||||
*/
|
||||
export function deleteShopDeliver(staff_id: number) {
|
||||
return request.delete(`shop/delivery/staff/${ staff_id }`)
|
||||
return request.delete(`shop/shop_delivery/staff/${ staff_id }`)
|
||||
}
|
||||
|
||||
|
||||
/********************************* 配送服务商 ***************************************/
|
||||
|
||||
/**
|
||||
* 获取配送服务商列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryServiceList(id: number) {
|
||||
return request.get(`shop/delivery_store/delivery_service_list/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商开通门店
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function deliveryShopOpen(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery_store/delivery_shop_open/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务商门店品类修改
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function deliveryShopEdit(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery_store/delivery_shop_edit/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/********************************* 同城配送设置 ***************************************/
|
||||
|
||||
/**
|
||||
* 获取同城配送设置
|
||||
* @returns
|
||||
*/
|
||||
export function getLocal() {
|
||||
return request.get('shop/local');
|
||||
return request.get('shop/local_delivery/config');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,7 +313,42 @@ export function getLocal() {
|
||||
* @returns
|
||||
*/
|
||||
export function setLocal(params: Record<string, any>) {
|
||||
return request.put('shop/local', params, { showSuccessMessage: true })
|
||||
return request.put('shop/local_delivery/config', params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取三方配送列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getInUseLocalDeliveryList(params: Record<string, any>) {
|
||||
return request.get('shop/local_delivery/list', {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送平台列表
|
||||
*/
|
||||
export function getLocalDeliveryServiceList() {
|
||||
return request.get(`shop/local_delivery/service`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同城配送平台设置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setLocalDeliveryService(params: Record<string, any>) {
|
||||
return request.put(`shop/local_delivery/service/${params.delivery_type}`, params, {showSuccessMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 同城配送平台详情
|
||||
* @param delivery_type
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliveryServiceInfo(delivery_type: string) {
|
||||
return request.get(`shop/local_delivery/service/${delivery_type}`,)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,3 +358,218 @@ export function setLocal(params: Record<string, any>) {
|
||||
export function getThird() {
|
||||
return request.get('shop/third/init')
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************* 同城配送记录 ***************************************/
|
||||
|
||||
/**
|
||||
* 获取配送记录状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliveryStatus() {
|
||||
return request.get('shop/local_delivery/order/status')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送记录分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliveryList(params: Record<string, any>) {
|
||||
return request.get(`shop/local_delivery/order`, {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送订单详情
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliveryInfo(id: number) {
|
||||
return request.get(`shop/local_delivery/order/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送订单取消原因
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliveryCancelReason(params: Record<string, any>) {
|
||||
return request.get('shop/local_delivery/order/cancel_reason', {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送订单同步
|
||||
* @param staff_id
|
||||
* @returns
|
||||
*/
|
||||
export function getLocalDeliverySync(id: number) {
|
||||
return request.put(`shop/local_delivery/order/sync/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同城配送订单取消
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setLocalDeliveryCancel(params: Record<string, any>) {
|
||||
return request.put(`shop/local_delivery/order/cancel/${ params.id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/********************************* 商家配送记录 ***************************************/
|
||||
/**
|
||||
* 获取配送记录状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryStatus() {
|
||||
return request.get('shop/shop_delivery/order/status')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家配送记录分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryOrderList(params: Record<string, any>) {
|
||||
return request.get(`shop/shop_delivery/order`, {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送订单详情
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryInfo(id: number) {
|
||||
return request.get(`shop/shop_delivery/order/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家配送记录订单完成
|
||||
* @param staff_id
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryFinish(id: number) {
|
||||
return request.put(`shop/shop_delivery/order/finish/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家配送记录订单完成
|
||||
* @param staff_id
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryFinish(id: number) {
|
||||
return request.put(`shop/local_delivery/order/finish/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家配送记录订单取消
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setShopDeliveryCancel(params: Record<string, any>) {
|
||||
return request.put(`shop/shop_delivery/order/cancel/${ params.id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送方式
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryType() {
|
||||
return request.get(`shop/delivery/type`);
|
||||
}
|
||||
|
||||
|
||||
/********************************* 门店自提 ***************************************/
|
||||
|
||||
/**
|
||||
* 获取门店自提分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryStoreList(params: Record<string, any>) {
|
||||
return request.get(`shop/delivery/store`, {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店选择列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryStoreListAll(params: Record<string, any>) {
|
||||
return request.get(`shop/delivery/store/list`, {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提货方式
|
||||
* @returns
|
||||
*/
|
||||
export function getStorePickUpType() {
|
||||
return request.get(`shop/delivery/store/pick_up_type`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送门店详情
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryStoreDetail(id: number) {
|
||||
return request.get(`shop/delivery/store/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加配送门店
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addDeliveryStore(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/store', params, {showErrorMessage: true, showSuccessMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑配送门店
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editDeliveryStore(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/store/${params.store_id}`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
/**
|
||||
* 删除运费模版
|
||||
* @param template_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteDeliveryStore(store_id: number) {
|
||||
return request.delete(`shop/delivery/store/${store_id}`, {showErrorMessage: true, showSuccessMessage: true})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑配送门店状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editDeliveryStoreStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/store/modify_status`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取距离配置
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliveryConfig() {
|
||||
return request.get('shop/local_delivery/base_config')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 编辑距离配置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setDeliveryConfig(params: Record<string, any>) {
|
||||
return request.put('shop/local_delivery/base_config', params, {showSuccessMessage: true})
|
||||
}
|
||||
|
||||
|
||||
@ -129,7 +129,7 @@ export function editGoodsStatus(params: Record<string, any>) {
|
||||
* @param params
|
||||
*/
|
||||
export function copyGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/copy/${ params.goods_id }`, params, { showSuccessMessage: true })
|
||||
return request.put(`shop/goods/copy/${ params.goods_id }`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -279,3 +279,19 @@ export function getOrderBatchDeliveryType() {
|
||||
export function closeRefund(order_refund_no: number) {
|
||||
return request.put(`shop/order/refund/close/${order_refund_no}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已选订单项总重量
|
||||
* @return
|
||||
*/
|
||||
export function getSelectOrderGoodsWeight(params: Record<string, any>) {
|
||||
return request.get(`shop/order/select/weight`, {params})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已选订单项配送费用
|
||||
* @return
|
||||
*/
|
||||
export function getDeliveryFee(params: Record<string, any>) {
|
||||
return request.get(`shop/order/delivery/fee`, {params})
|
||||
}
|
||||
@ -87,5 +87,6 @@
|
||||
"notLessThanZero": "不能小于0",
|
||||
"mustBeGreaterThanZero": "必须大于0",
|
||||
"thridRequire": "请选择一个三方配送服务",
|
||||
"thridSeting": "请填写完整的三方配送配置"
|
||||
"thridSeting": "请填写完整的三方配送配置",
|
||||
"deliveryArea": "配送区域"
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"isStoreSelect":"是否开启门店选择",
|
||||
"isShowPolyline":"是否显示配送轨迹"
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "三方配送类型",
|
||||
"dadaThirdDelivery":"达达秒送",
|
||||
"isUse":"是否启用",
|
||||
"config":"设置",
|
||||
"dadaAppKey": "APP_KEY",
|
||||
"dadaAppSecret":"APP_SECRET",
|
||||
"dadaSourceId": "商户ID",
|
||||
"dadaAppKeyPlaceholder": "请输入APP_KEY",
|
||||
"dadaAppSecretPlaceholder":"请输入APP_SECRET",
|
||||
"dadaSourceIdPlaceholder":"请输入商户ID"
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"deliveryNo": "配送单号",
|
||||
"tradeNo": "交易单号",
|
||||
"tradeNoPlaceholder":"请输入交易单号",
|
||||
"deliveryNoPlaceholder":"请输入配送单号",
|
||||
"createTime":"配送时间",
|
||||
"startDate":"开始日期",
|
||||
"endDate":"结束日期",
|
||||
"deliveryServiceName":"配送服务名称",
|
||||
"goodsInfo":"商品信息",
|
||||
"deliveryStart":"配送起点",
|
||||
"deliveryEnd":"配送终点",
|
||||
"deliveryStatus":"状态",
|
||||
"deliveryStatusPlaceholder":"请选择状态",
|
||||
"deliveryDistance":"配送距离",
|
||||
"deliveryMoney":"配送费用",
|
||||
"remark":"备注",
|
||||
"detail": "详情",
|
||||
"sync":"同步",
|
||||
"syncTips":"您确定要同步配送订单吗?",
|
||||
"finish":"完成",
|
||||
"finishTips":"您确定要完成配送订单吗?",
|
||||
"cancelTime":"取消时间",
|
||||
"riderName":"配送员姓名",
|
||||
"riderMobile":"配送员手机号",
|
||||
"outDeliveryNo":"外部配送单号",
|
||||
"deliveryCancel":"取消配送",
|
||||
"cancelReasonSelectPlaceholder":"请选择取消原因类型",
|
||||
"cancelReasonType":"取消原因类型",
|
||||
"cancelReason":"取消原因",
|
||||
"cancelReasonPlaceholder":"请输入取消原因"
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
{
|
||||
"deliveryNo": "配送单号",
|
||||
"tradeNo": "交易单号",
|
||||
"tradeNoPlaceholder":"请输入交易单号",
|
||||
"deliveryNoPlaceholder":"请输入配送单号",
|
||||
"createTime":"配送时间",
|
||||
"startDate":"开始日期",
|
||||
"endDate":"结束日期",
|
||||
"deliveryServiceName":"配送服务名称",
|
||||
"goodsInfo":"商品信息",
|
||||
"deliveryStart":"配送起点",
|
||||
"deliveryEnd":"配送终点",
|
||||
"deliveryStatus":"状态",
|
||||
"deliveryStatusPlaceholder":"请选择状态",
|
||||
"deliveryDistance":"配送距离",
|
||||
"deliveryMoney":"配送费用",
|
||||
"remark":"备注",
|
||||
"detail": "详情",
|
||||
"finish":"完成",
|
||||
"finishTips":"您确定要完成配送订单吗?",
|
||||
"cancelTime":"取消时间",
|
||||
"riderName":"配送员姓名",
|
||||
"riderMobile":"配送员手机号",
|
||||
"outDeliveryNo":"外部配送单号",
|
||||
"deliveryCancel":"取消配送",
|
||||
"cancelReasonSelectPlaceholder":"请选择取消原因类型",
|
||||
"cancelReasonType":"取消原因类型",
|
||||
"cancelReason":"取消原因",
|
||||
"cancelReasonPlaceholder":"请输入取消原因"
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"deliveryServiceName": "服务商",
|
||||
"openService": "开通",
|
||||
"editService": "修改品类",
|
||||
"business": "门店品类",
|
||||
"businessPlaceholder": "请选择门店品类",
|
||||
"openStatus": "开通状态",
|
||||
"editStatus": "门店信息变更状态",
|
||||
"reason": "备注",
|
||||
"pass": "通过",
|
||||
"notPass": "未通过"
|
||||
}
|
||||
103
niucloud/addon/shop/admin/lang/zh-cn/delivery_store.edit.json
Normal file
103
niucloud/addon/shop/admin/lang/zh-cn/delivery_store.edit.json
Normal file
@ -0,0 +1,103 @@
|
||||
{
|
||||
"basicSettings": "同城配送基础设置",
|
||||
"timeIsOpen": "配送时间设置",
|
||||
"timeIsOpenTips": "开启后,买家下单选择同城配送时,可选择配送时间,提交订单后,将在买家备注中显示。关闭后,买家下单默认为立即配送",
|
||||
"close": "关闭",
|
||||
"open": "开启",
|
||||
"everyDay": "每天",
|
||||
"monday": "周一",
|
||||
"tuesday": "周二",
|
||||
"wednesday": "周三",
|
||||
"thursday": "周四",
|
||||
"friday": "周五",
|
||||
"saturday": "周六",
|
||||
"sunday": "周日",
|
||||
"timeWeekRequire": "请选择配送时间",
|
||||
"deliveryTimeSetting": "配送时间设置",
|
||||
"feeType": "收费标准",
|
||||
"region": "按区域收取配送费",
|
||||
"distance": "按距离收取配送费",
|
||||
"district": "按行政区域收取配送费",
|
||||
"feeSetting": "费用设置",
|
||||
"weightFee": "续重收费",
|
||||
"feeSettingTextOne": "km内按",
|
||||
"feeSettingTextTwo": "元收取配送费,每超出",
|
||||
"feeSettingTextThree": "km费用增加",
|
||||
"priceUnit": "元",
|
||||
"weightFeeTextOne": "商品重量",
|
||||
"weightFeeTextTwo": "kg 内不额外收费,每超出",
|
||||
"weightFeeTextThree": "kg 费用增加",
|
||||
"areaName": "区域名称",
|
||||
"startPrice": "起送价",
|
||||
"deliveryPrice": "配送费",
|
||||
"areaType": "划分方式",
|
||||
"radius": "半径",
|
||||
"custom": "自定义",
|
||||
"addDeliveryArea": "添加配送区域",
|
||||
"baseDistRequire": "请输入起始公里数",
|
||||
"gradDistRequire": "请输入超出公里数",
|
||||
"basePriceRequire": "请输入起始公里内的配送费用",
|
||||
"gradPriceRequire": "请输入每超出公里部分的费用",
|
||||
"areaNameRequire": "请输入区域名称",
|
||||
"startPriceRequire": "请输入起送价",
|
||||
"startPriceMin": "起送价不能小于0",
|
||||
"deliveryPriceRequire": "请输入配送费",
|
||||
"deliveryPriceMin": "配送费不能小于0",
|
||||
"areaPlaceholder": "请添加配送区域",
|
||||
"deliveryType": "配送方式",
|
||||
"business": "商家自配送",
|
||||
"deliveryTypeRequire": "至少需选择一种配送方式",
|
||||
"deliveryAddress": "取货地址",
|
||||
"defaultDeliveryAddressEmpty": "请先配置默认发货地址",
|
||||
"toSetting": "去配置",
|
||||
"update": "修改",
|
||||
"deliveryAddressChange": "取货地址已变更请注意是否需重新调整配送区域",
|
||||
"tradeTimePlaceholderTwo": "请选择提货时段",
|
||||
"tradeTimePlaceholderThree": "请选择细分时段",
|
||||
"tradeTimePlaceholderFour": "结束时间不能小于或等于开始时间",
|
||||
"tradeTimePlaceholderFive": "后一个时间段的开始时间不能小于前一个时间段的结束时间",
|
||||
"thrid":"三方配送",
|
||||
"AppKey":"AppKey",
|
||||
"AppSecret":"AppSecret",
|
||||
"shopId":"商户ID",
|
||||
"shopStoreNo":"商户门店编号",
|
||||
"AppKeyRequire":"请输入AppKey",
|
||||
"AppSecretRequire":"请输入AppSecret",
|
||||
"shopIdRequire":"请输入商户ID",
|
||||
"shopStoreNoRequire":"请输入商户门店编号",
|
||||
"deliveryTime":"配送时段设置",
|
||||
"startTime":"开始时间",
|
||||
"endTime":"结束时间",
|
||||
"timeInterval":"细分时段",
|
||||
"addTime":"添加配送时段",
|
||||
"deliveryTimeTips":"配送时段设置,若不在配送时段内,则无法进行配送",
|
||||
"30minute": "30分钟",
|
||||
"90minute": "90分钟",
|
||||
"oneHour": "一小时",
|
||||
"twoHour": "两小时",
|
||||
"advancaDay": "提前预约",
|
||||
"advance": "提前",
|
||||
"day": "天",
|
||||
"reservationAvailable":"可预约",
|
||||
"withinDays":"天内",
|
||||
"advanceTips": "若设置了提前预约,则用户在当前日期前多少天可以预约配送,不可以立即配送",
|
||||
"mostDays": "最长预约",
|
||||
"mostDaysTips": "预约配送最长可预约多少天内进行提货",
|
||||
"formatError": "格式不正确",
|
||||
"notLessThanZero": "不能小于0",
|
||||
"mustBeGreaterThanZero": "必须大于0",
|
||||
"thridRequire": "请选择一个三方配送服务",
|
||||
"thridSeting": "请填写完整的三方配送配置",
|
||||
"addressPlaceholder":"请输入详细地址",
|
||||
"fullAddressPlaceholder":"请输入地址",
|
||||
"storeName": "提货点名称",
|
||||
"storeNamePlaceholder": "请输入提货点名称",
|
||||
"contactName": "联系人姓名",
|
||||
"contactNamePlaceholder": "请输入联系人姓名",
|
||||
"storeMobile": "联系人电话",
|
||||
"storeMobilePlaceholder": "请输入联系人电话",
|
||||
"tradeTime": "营业时间",
|
||||
"tradeTimePlaceholder": "请输入营业时间",
|
||||
"tradeTimeTips": "例:上午9:00-12:00,下午2:00-6:00",
|
||||
"deliveryStoreTips": "当前提货点为系统自建提货点,无法删除且提货点名称、联系人电话、营业时间及地址只能在店铺设置中统一配置。"
|
||||
}
|
||||
@ -116,6 +116,22 @@
|
||||
"refundInstructionsOne": "1、如果是退部分金额,退款后可以是部分退款状态或退款完成状态",
|
||||
"refundInstructionsTwo": "2、如果是退全部金额,则退款后一定是退款完成状态",
|
||||
"refundInstructionsThree": "3、退款完成才会执行相关业务如核销码失效,卡包失效等操作",
|
||||
"storeDeliveryWay": "商家配送",
|
||||
"thirdPartyDeliveryWay": "第三方配送",
|
||||
"deliverName": "配送员",
|
||||
"deliverNamePlaceholder": "请选择配送员",
|
||||
"deliverMobile": "配送员手机号",
|
||||
"deliverMobilePlaceholder": "请输入配送员手机号",
|
||||
"thirdDeliveryName": "配送平台",
|
||||
"thirdDeliveryNamePlaceholder": "请选择配送平台",
|
||||
"goodsWeight": "商品重量",
|
||||
"goodsWeightPlaceholder": "请输入商品重量",
|
||||
"weightTips": "[商品重量(kg)]格式输入错误",
|
||||
"weightNotZeroTips": "商品重量(kg)必须大于0",
|
||||
"deliveryAddress": "发货地址",
|
||||
"deliveryPlatform": "配送平台",
|
||||
"deliveryStatus": "配送状态",
|
||||
"modifyDelivery": "修改发货信息",
|
||||
"backRefund": "原路退款",
|
||||
"offlineRefund": "线下退款",
|
||||
"refundToBalance": "退款到余额",
|
||||
|
||||
@ -160,5 +160,22 @@
|
||||
"orderInfoEmpty": "暂无数据",
|
||||
"buyerAskDeliveryTime": "要求自提时间",
|
||||
"deleteTips": "是否确认删除该订单?",
|
||||
"batchDeleteTips": "是否确认批量删除选中的订单?"
|
||||
"batchDeleteTips": "是否确认批量删除选中的订单?",
|
||||
"storeDeliveryWay": "商家配送",
|
||||
"thirdPartyDeliveryWay": "第三方配送",
|
||||
"deliverName": "配送员",
|
||||
"deliverNamePlaceholder": "请选择配送员",
|
||||
"deliverMobile": "配送员手机号",
|
||||
"deliverMobilePlaceholder": "请输入配送员手机号",
|
||||
"thirdDeliveryName": "配送平台",
|
||||
"thirdDeliveryNamePlaceholder": "请选择配送平台",
|
||||
"goodsWeight": "商品重量",
|
||||
"goodsWeightPlaceholder": "请输入商品重量",
|
||||
"weightTips": "[商品重量(kg)]格式输入错误",
|
||||
"weightNotZeroTips": "商品重量(kg)必须大于0",
|
||||
"deliveryStore": "提货点",
|
||||
"deliveryStorePlaceholder": "请选择提货点",
|
||||
"deliveryPlatform": "配送平台",
|
||||
"deliveryStatus": "配送状态",
|
||||
"goActive":"去开通"
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ const router = useRouter()
|
||||
* 添加商家地址库
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/order/address/edit')
|
||||
router.push('/shop/address/edit')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +125,7 @@ const addEvent = () => {
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/order/address/edit?id=' + data.id)
|
||||
router.push('/shop/address/edit?id=' + data.id)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="main-container">
|
||||
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push('/shop/order/delivery')" />
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push('/shop/delivery/config')" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
@ -118,7 +118,7 @@ loadCompanyList(getTablePageStorage(companyTable.searchParam).page);
|
||||
* 添加物流公司
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/order/delivery/company_add')
|
||||
router.push('/shop/delivery/company_add')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +126,7 @@ const addEvent = () => {
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/order/delivery/company_edit?company_id=' + data.company_id)
|
||||
router.push('/shop/delivery/company_edit?company_id=' + data.company_id)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -135,7 +135,7 @@ const router = useRouter()
|
||||
const loading = ref(true)
|
||||
|
||||
const back = () => {
|
||||
router.push('/shop/order/delivery/company')
|
||||
router.push('/shop/delivery/company')
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,7 +301,7 @@ const save = async(formEl: FormInstance | undefined) => {
|
||||
|
||||
const data = formData
|
||||
api(data).then(res => {
|
||||
router.push('/shop/order/delivery/company')
|
||||
router.push('/shop/delivery/company')
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" :title="t('dadaThirdDelivery')" width="580px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="140px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('isUse')">
|
||||
<el-radio-group v-model="formData.is_use">
|
||||
<el-radio :label="1">{{ t('startUsing') }}</el-radio>
|
||||
<el-radio :label="0">{{ t('statusDeactivate') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('dadaAppKey')" prop="app_key">
|
||||
<el-input v-model.trim="formData.app_key" :placeholder="t('dadaAppKeyPlaceholder')" class="input-width" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('dadaAppSecret')" prop="app_secret">
|
||||
<el-input v-model.trim="formData.app_secret" :placeholder="t('dadaAppSecretPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('dadaSourceId')" prop="source_id">
|
||||
<el-input v-model.trim="formData.source_id" :placeholder="t('dadaSourceIdPlaceholder')" class="input-width" clearable />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{t('confirm')}}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { setLocalDeliveryService, getLocalDeliveryServiceInfo } from '@/addon/shop/api/delivery'
|
||||
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(true)
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
delivery_type: '',
|
||||
app_key: '',
|
||||
app_secret: '',
|
||||
source_id: '',
|
||||
is_use: ''
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
app_key: [
|
||||
{ required: true, message: t('dadaAppKeyPlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
app_secret: [
|
||||
{ required: true, message: t('dadaAppSecretPlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
source_id: [
|
||||
{ required: true, message: t('dadaSourceIdPlaceholder'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['complete'])
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
const data = formData
|
||||
|
||||
setLocalDeliveryService(data).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
emit('complete')
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
// showDialog.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const setFormData = async (row: any = null) => {
|
||||
loading.value = true
|
||||
Object.assign(formData, initialFormData)
|
||||
if (row) {
|
||||
const data = await (await getLocalDeliveryServiceInfo(row.delivery_type)).data
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
if (data.params[key] != undefined) formData[key] = data.params[key].value
|
||||
})
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDialog,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="local-record-detail-drawer">
|
||||
<div class="main-container" v-loading="loading">
|
||||
<el-form :model="detailData" label-width="100px" ref="formRef" class="page-form" label-position="left">
|
||||
<div class="row-bg px-[20px] mb-[20px] multiple-layout">
|
||||
<el-form-item :label="t('deliveryServiceName')">
|
||||
<div class="input-width">{{ detailData.delivery_service_name }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsInfo')">
|
||||
<div class="input-width">{{ detailData.body }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryNo')">
|
||||
<div class="input-width">{{ detailData.delivery_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('tradeNo')">
|
||||
<div class="input-width text-primary cursor-pointer" @click="toLink">{{ detailData.trade_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStart')">
|
||||
<div class="input-width">{{ detailData.delivery_start }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryEnd')">
|
||||
<div class="input-width">{{ detailData.delivery_end }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStatus')">
|
||||
<div class="input-width">{{ detailData.status_name }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryDistance')">
|
||||
<div class="input-width">{{ distance(detailData.delivery_distance) }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryMoney')">
|
||||
<div class="input-width">¥{{ detailData.delivery_money }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('cancelTime')" v-if="detailData.cancel_time">
|
||||
<div class="input-width">{{ detailData.cancel_time }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('riderName')" v-if="detailData.rider_name">
|
||||
<div class="input-width">{{ detailData.rider_name }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('riderMobile')" v-if="detailData.rider_mobile">
|
||||
<div class="input-width">{{ detailData.rider_mobile }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('outDeliveryNo')">
|
||||
<div class="input-width">{{ detailData.out_delivery_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('remark')">
|
||||
<div class="input-width">{{ detailData.remark }}</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div>
|
||||
<h3 class="mt-[50px] mb-[20px]" v-if="detailData.orderLog.length > 0">配送日志</h3>
|
||||
<div class="mb-[100px]" style="min-height: 100px" v-if="detailData.orderLog.length > 0">
|
||||
<div class="flex" v-for="(items, index) in detailData.orderLog" :key="index">
|
||||
<div class="mr-[20px] min-w-[71px]">
|
||||
<div class="leading-[1] w-full text-[14px] w-[100px] flex justify-end">
|
||||
{{ items.create_time && items.create_time.split(' ')[0] }}
|
||||
</div>
|
||||
<div class="leading-[1] w-full text-[14px] w-[100px] flex justify-end mt-[15px]">
|
||||
{{ items.create_time && items.create_time.split(' ')[1] }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="w-[16px] h-[16px] flex items-center bg-[#D1EBFF] border-[1px] border-[#0091FF] rounded-[999px]">
|
||||
<div class="w-[8px] h-[8px] mx-auto bg-[#0091FF] rounded-[999px]"></div>
|
||||
</div>
|
||||
<div v-if="(index + 1) != detailData.orderLog.length" class="w-[2px] h-[50px] bg-[#D1EBFF] mx-auto">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="leading-[1] ml-[20px] text-[14px]">
|
||||
{{ items.main_type_name }}{{ items.main_name }}
|
||||
</div>
|
||||
<div class="leading-[1] ml-[20px] text-[14px] mt-[15px]">
|
||||
<span>{{ items.remark }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { distance } from '@/utils/common'
|
||||
import { getLocalDeliveryInfo } from '@/addon/shop/api/delivery'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
const popTitle: string = '配送详情'
|
||||
const detailData = ref<any>({})
|
||||
let id: any = ''
|
||||
|
||||
const handleClose = (done: () => void) => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
const getLocalDeliveryInfoFn = async () => {
|
||||
loading.value = true
|
||||
if (id) {
|
||||
detailData.value = await (await getLocalDeliveryInfo(id)).data
|
||||
loading.value = false
|
||||
} else {
|
||||
loading.value = false
|
||||
}
|
||||
showDialog.value = true
|
||||
}
|
||||
const setFormData = async (row: any = null) => {
|
||||
id = row.id
|
||||
getLocalDeliveryInfoFn()
|
||||
}
|
||||
|
||||
const toLink = () => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/order/detail',
|
||||
query: {
|
||||
order_id: detailData.value.trade_id
|
||||
}
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDialog,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.local-record-detail-drawer{
|
||||
width: 1300px !important;
|
||||
.input-width{
|
||||
width: 280px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<el-drawer v-model="showDialog" :title="popTitle" direction="rtl" :before-close="handleClose" class="local-record-detail-drawer">
|
||||
<div class="main-container" v-loading="loading">
|
||||
<el-form :model="detailData" label-width="100px" ref="formRef" class="page-form" label-position="left">
|
||||
<div class="row-bg px-[20px] mb-[20px] multiple-layout">
|
||||
<el-form-item :label="t('deliveryNo')">
|
||||
<div class="input-width">{{ detailData.delivery_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsInfo')">
|
||||
<div class="input-width">{{ detailData.body }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('tradeNo')">
|
||||
<div class="input-width text-primary cursor-pointer" @click="toLink">{{ detailData.trade_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStart')">
|
||||
<div class="input-width">{{ detailData.delivery_start }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryEnd')">
|
||||
<div class="input-width">{{ detailData.delivery_end }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStatus')">
|
||||
<div class="input-width">{{ detailData.status_name }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryDistance')">
|
||||
<div class="input-width">{{ distance(detailData.delivery_distance) }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryMoney')">
|
||||
<div class="input-width">¥{{ detailData.delivery_money }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('cancelTime')" v-if="detailData.cancel_time">
|
||||
<div class="input-width">{{ detailData.cancel_time }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('riderName')" v-if="detailData.rider_name">
|
||||
<div class="input-width">{{ detailData.rider_name }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('riderMobile')" v-if="detailData.rider_mobile">
|
||||
<div class="input-width">{{ detailData.rider_mobile }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('outDeliveryNo')">
|
||||
<div class="input-width">{{ detailData.out_delivery_no }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('remark')">
|
||||
<div class="input-width">{{ detailData.remark }}</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div>
|
||||
<h3 class="mt-[50px] mb-[20px]" v-if="detailData.orderLog.length > 0">配送日志</h3>
|
||||
<div class="mb-[100px]" style="min-height: 100px" v-if="detailData.orderLog.length > 0">
|
||||
<div class="flex" v-for="(items, index) in detailData.orderLog" :key="index">
|
||||
<div class="mr-[20px] min-w-[71px]">
|
||||
<div class="leading-[1] w-full text-[14px] w-[100px] flex justify-end">
|
||||
{{ items.create_time && items.create_time.split(' ')[0] }}
|
||||
</div>
|
||||
<div class="leading-[1] w-full text-[14px] w-[100px] flex justify-end mt-[15px]">
|
||||
{{ items.create_time && items.create_time.split(' ')[1] }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="w-[16px] h-[16px] flex items-center bg-[#D1EBFF] border-[1px] border-[#0091FF] rounded-[999px]">
|
||||
<div class="w-[8px] h-[8px] mx-auto bg-[#0091FF] rounded-[999px]"></div>
|
||||
</div>
|
||||
<div v-if="index + 1 != detailData.orderLog.length" class="w-[2px] h-[50px] bg-[#D1EBFF] mx-auto">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="leading-[1] ml-[20px] text-[14px]">
|
||||
{{ items.main_type_name }}{{ items.main_name }}
|
||||
</div>
|
||||
<div class="leading-[1] ml-[20px] text-[14px] mt-[15px]">
|
||||
<span>{{ items.remark }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { distance } from '@/utils/common'
|
||||
import { getShopDeliveryInfo } from '@/addon/shop/api/delivery'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
const popTitle: string = '配送详情'
|
||||
const detailData = ref<any>({})
|
||||
let id: any = ''
|
||||
|
||||
const handleClose = (done: () => void) => {
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
const getShopDeliveryInfoFn = async () => {
|
||||
loading.value = true
|
||||
if (id) {
|
||||
detailData.value = await (await getShopDeliveryInfo(id)).data
|
||||
loading.value = false
|
||||
} else {
|
||||
loading.value = false
|
||||
}
|
||||
showDialog.value = true
|
||||
}
|
||||
const setFormData = async (row: any = null) => {
|
||||
id = row.id
|
||||
getShopDeliveryInfoFn()
|
||||
}
|
||||
|
||||
const toLink = () => {
|
||||
const path = '/shop/order/detail'
|
||||
const url = router.resolve({
|
||||
path,
|
||||
query: {
|
||||
order_id: detailData.value.trade_id
|
||||
}
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
showDialog,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.local-record-detail-drawer{
|
||||
width: 1300px !important;
|
||||
.input-width{
|
||||
width: 280px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -25,16 +25,16 @@
|
||||
<span class="text-[#666666] text-[14px]">{{ t(item.key) }}</span>
|
||||
<div>
|
||||
<template v-if="item.key === 'local_delivery'">
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/staff')">{{ t('deliveryStaff') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/local')">{{ t('localConfig') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/delivery/local_config')">基础配置</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/delivery/local')">{{ t('localConfig') }}</el-button>
|
||||
</template>
|
||||
<template v-if="item.key === 'express'">
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/company')">{{ t('deliveryCompany') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/shipping/template')">{{ t('deliveryTemplate') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/search')">{{ t('deliverySearch') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/delivery/company')">{{ t('deliveryCompany') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/shipping/template')">{{ t('deliveryTemplate') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/delivery/search')">{{ t('deliverySearch') }}</el-button>
|
||||
</template>
|
||||
<template v-if="item.key === 'store'">
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/store')">{{ t('deliveryStore') }}</el-button>
|
||||
<el-button type="primary" link @click="goRouter('/shop/delivery_store')">{{ t('deliveryStore') }}</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,141 +5,7 @@
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-form label-width="120px" ref="formRef" :rules="formRules" :model="formData" class="page-form"
|
||||
v-loading="loading">
|
||||
<!-- <h3 class="panel-title">{{t('basicSettings')}}</h3> -->
|
||||
<el-form-item :label="t('deliveryType')" prop="delivery_type">
|
||||
<!-- <el-checkbox-group v-model="formData.delivery_type">
|
||||
<el-checkbox label="business">{{ t('business') }}</el-checkbox>
|
||||
<el-checkbox label="third">{{ t('三方配送') }}</el-checkbox>
|
||||
</el-checkbox-group> -->
|
||||
<el-radio-group v-model="formData.delivery_type">
|
||||
<el-radio :label="'business'">{{ t('business') }}</el-radio>
|
||||
<el-radio :label="'third'">{{ t('thrid') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('thrid')" prop="time_is_open" v-if="formData.delivery_type=='third'">
|
||||
<div v-for="(service, index) in thirdPartyData" :key="service.type">
|
||||
<div class="flex items-center mr-[20px]">
|
||||
<span class="mr-[10px]">{{ service.name }}</span>
|
||||
<el-switch v-model="service.isEnabled" @change="handleServiceChange(index)"></el-switch>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<template v-if="activeService && formData.delivery_type=='third'">
|
||||
<el-form-item :label="t('AppKey')" prop="app_key">
|
||||
<el-input v-model="activeService.config.app_key" clearable :placeholder="t('AppKeyRequire')" class="input-width" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('AppSecret')" prop="app_secret">
|
||||
<el-input v-model="activeService.config.app_secret" clearable :placeholder="t('AppSecretRequire')" class="input-width" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('shopId')" prop="shop_id">
|
||||
<el-input v-model="activeService.config.shop_id" clearable :placeholder="t('shopIdRequire')" class="input-width" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('shopStoreNo')" prop="shop_store_no">
|
||||
<el-input v-model="activeService.config.shop_store_no" clearable :placeholder="t('shopStoreNoRequire')" class="input-width" maxlength="100" show-word-limit />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="t('timeIsOpen')" prop="time_is_open">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.time_is_open">
|
||||
<el-radio :label="1">{{ t('open') }}</el-radio>
|
||||
<el-radio :label="0">{{ t('close') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="mt-[10px] text-[12px] text-[#999] leading-[20px]">{{t('timeIsOpenTips')}}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<template v-if="formData.time_is_open === 1">
|
||||
<el-form-item>
|
||||
<el-radio-group v-model="formData.time_type">
|
||||
<el-radio :label="0">{{ t('everyDay') }}</el-radio>
|
||||
<el-radio :label="1">{{ t('custom') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="time_week" v-if="formData.time_type===1">
|
||||
<el-checkbox-group v-model="formData.time_week">
|
||||
<el-checkbox label="1">{{ t('monday') }}</el-checkbox>
|
||||
<el-checkbox label="2">{{ t('tuesday') }}</el-checkbox>
|
||||
<el-checkbox label="3">{{ t('wednesday') }}</el-checkbox>
|
||||
<el-checkbox label="4">{{ t('thursday') }}</el-checkbox>
|
||||
<el-checkbox label="5">{{ t('friday') }}</el-checkbox>
|
||||
<el-checkbox label="6">{{ t('saturday') }}</el-checkbox>
|
||||
<el-checkbox label="0">{{ t('sunday') }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryTime')" prop="delivery_time">
|
||||
<div>
|
||||
<div>
|
||||
<div v-for="(timeRange, index) in formData.delivery_time" :key="index" class="mb-3">
|
||||
<el-time-picker v-model="timeRange.start_time" :placeholder="t('startTime')"
|
||||
format="HH:mm" value-format="HH:mm"
|
||||
:picker-options="{selectableRange: '00:00 - 23:59'}" />
|
||||
<span class="mx-2">-</span>
|
||||
<el-time-picker v-model="timeRange.end_time" :placeholder="t('endTime')" format="HH:mm"
|
||||
value-format="HH:mm" :picker-options="{selectableRange: '00:00 - 23:59'}" />
|
||||
<span v-if="index > 0" class="text-primary cursor-pointer ml-[10px]"
|
||||
@click="removeTimeRange(index)"> {{ t('delete') }}</span>
|
||||
</div>
|
||||
<span class="text-primary cursor-pointer mr-[10px]" @click="addTimeRange"
|
||||
v-if="formData.delivery_time.length < 3"> {{ t('addTime') }}</span>
|
||||
</div>
|
||||
<div class="text-[12px] text-[#999]">{{ t('deliveryTimeTips') }}</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('timeInterval')" prop="time_interval">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.time_interval">
|
||||
<el-radio :label="30">{{ t('30minute') }}</el-radio>
|
||||
<el-radio :label="60">{{ t('oneHour') }}</el-radio>
|
||||
<el-radio :label="90">{{ t('90minute') }}</el-radio>
|
||||
<el-radio :label="120">{{ t('twoHour') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- <p class="text-[12px] text-[#999]">{{ t('storeTimeIntervalTips') }}</p> -->
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('advancaDay')" prop="advance_day">
|
||||
<div>
|
||||
<div class="flex">
|
||||
{{ t('advance') }}
|
||||
<div class="w-[100px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.advance_day" />
|
||||
</div>
|
||||
{{ t('day') }}
|
||||
</div>
|
||||
<p class="text-[12px] text-[#999]">{{ t('advanceTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('mostDays')" prop="most_day">
|
||||
<div>
|
||||
<div class="flex">
|
||||
{{ t('reservationAvailable') }}
|
||||
<div class="w-[100px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.most_day" />
|
||||
</div>
|
||||
{{ t('withinDays') }}
|
||||
</div>
|
||||
<p class="text-[12px] text-[#999]">{{ t('mostDaysTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<el-form-item :label="t('deliveryAddress')" prop="delivery_address">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex">
|
||||
{{ defaultDeliveryAddress ? defaultDeliveryAddress.full_address :
|
||||
t('defaultDeliveryAddressEmpty') }}
|
||||
<el-button type="primary" @click="router.push('/shop/order/address')" link
|
||||
class="ml-[10px]">{{ defaultDeliveryAddress ? t('update') : t('toSetting')
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="text-error leading-none"
|
||||
v-if="formData.center.lat && defaultDeliveryAddress && (formData.center.lat != defaultDeliveryAddress.lat || formData.center.lng != defaultDeliveryAddress.lng)">
|
||||
{{ t('deliveryAddressChange') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form label-width="80px" ref="formRef" :rules="formRules" :model="formData" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('feeType')">
|
||||
<el-radio-group v-model="formData.fee_type">
|
||||
<el-radio label="region">{{ t('region') }}</el-radio>
|
||||
@ -166,7 +32,7 @@
|
||||
{{ t('priceUnit') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('weightFee')" prop="">
|
||||
<el-form-item :label="t('weightFee')" prop="weight">
|
||||
<div class="flex">
|
||||
{{ t('weightFeeTextOne') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
@ -183,36 +49,53 @@
|
||||
{{ t('priceUnit') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="area" v-loading="mapLoading">
|
||||
<div class="relative w-full">
|
||||
<div id="container" class="w-full h-[520px]"></div>
|
||||
<div class="absolute bg-white w-[270px] h-[500px] top-[10px] left-[10px] region-list">
|
||||
<el-scrollbar>
|
||||
<div class="p-[10px] region-item pr-[50px] relative"
|
||||
v-for="(item, index) in formData.area" :key="index"
|
||||
:class="{ '!border-primary': index == currArea }" @click="selectArea(index)">
|
||||
<el-form label-width="80px" :model="item" :rules="formRules" class="page-form"
|
||||
ref="areaFromRef">
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('areaName')" prop="area_name">
|
||||
<el-input v-model.trim="formData.area[index].area_name" type="text" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryArea')" prop="delivery_area">
|
||||
<div class="w-full border-[1px] border-solid border-[#dcdfe6] flex" v-loading="mapLoading">
|
||||
<div class="store-wrap w-[270px] h-[520px] border-r-[1px] border-solid border-[#dcdfe6]">
|
||||
<div class="relative h-[520px]" v-if="deliveryStoreList.length">
|
||||
<div class="h-[450px] overflow-y-auto">
|
||||
<div class="h-[70px] cursor-pointer px-[10px] flex flex flex-col justify-center border-b-[1px] border-solid border-[#dcdfe6] box-border" :class="{'bg-[#E6F1FE] text-primary': curDelivery.store_id == item.store_id }" v-for="(item,index) in deliveryStoreList" :key="index" @click="handleMap(item)">
|
||||
<div class="text-[16px] leading-[20px] mb-[6px] flex items-center justify-between">
|
||||
<span class="using-hidden">{{ item.store_name }}</span>
|
||||
<el-button type="primary" @click.stop="toLink(item)" link class="ml-[10px] !text-[12px]">配置</el-button>
|
||||
</div>
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('startPrice')" prop="start_price">
|
||||
<el-input v-model.trim="formData.area[index].start_price" maxlength="8" type="text"
|
||||
@keyup="filterDigit($event)" />
|
||||
<div class="text-[12px] text-[#999] leading-[16px] multi-hidden" :class="{'!text-primary': curDelivery.store_id == item.store_id }">地址:{{ item.full_address }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute left-0 right-0 bottom-0 h-[70px] flex items-center bg-[#fff] px-[20px]">
|
||||
<el-button type="primary" @click="newWindow()" class="w-full box-border">新增配送点</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="h-full flex flex-col items-center justify-center">
|
||||
<span class="text-[14px] mb-[10px]">请到配送点中添加配送区域</span>
|
||||
<el-button type="primary" @click="newWindow()" link class="ml-[10px]">{{ t('toSetting') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative flex-1">
|
||||
<div id="container" class="w-full h-[520px]"></div>
|
||||
<div class="absolute bg-white w-[270px] h-[500px] top-[10px] left-[10px] region-list" v-if="deliveryStoreList.length">
|
||||
<el-scrollbar>
|
||||
<div class="p-[10px] region-item pr-[50px] relative" v-for="(item, index) in curDelivery.area" :key="index" :class="{ '!border-primary': index == currArea }" @click="selectArea(index)">
|
||||
<el-form label-width="80px" :model="item" :rules="formRules" class="page-form" ref="areaFromRef">
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('areaName')" prop="area_name">
|
||||
<el-input v-model.trim="curDelivery.area[index].area_name" type="text" @click.stop=""/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('startPrice')" prop="start_price">
|
||||
<el-input v-model.trim="curDelivery.area[index].start_price" maxlength="8" type="text"
|
||||
@keyup="filterDigit($event)" @click.stop="" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="pb-[10px]" v-show="formData.fee_type == 'region'">
|
||||
<el-form-item :label="t('deliveryPrice')" prop="delivery_price">
|
||||
<el-input v-model.trim="formData.area[index].delivery_price" type="text"
|
||||
@keyup="filterDigit($event)" />
|
||||
<el-input v-model.trim="curDelivery.area[index].delivery_price" type="text"
|
||||
@keyup="filterDigit($event)" @click.stop=""/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item :label="t('areaType')">
|
||||
<el-radio-group v-model="formData.area[index].area_type" @change="areaTypeChange(index)">
|
||||
<el-radio-group v-model="curDelivery.area[index].area_type" @change="areaTypeChange(index)">
|
||||
<el-radio label="radius" size="large" class="!mr-[10px]">{{ t('radius') }}</el-radio>
|
||||
<el-radio label="custom" size="large" class="!mr-[0px]">{{ t('custom') }}</el-radio>
|
||||
</el-radio-group>
|
||||
@ -225,6 +108,7 @@
|
||||
<el-button plain @click="addArea">{{ t('addDeliveryArea') }}</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@ -240,111 +124,25 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted, onBeforeUnmount,toRaw } from 'vue'
|
||||
import { ref, computed, onMounted, onBeforeUnmount, toRaw } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getMap } from '@/app/api/sys'
|
||||
import { guid, filterDigit, deepClone } from '@/utils/common'
|
||||
import { createCircle, deleteGeometry, createPolygon, selectGeometry, createMarker } from '@/utils/qqmap'
|
||||
import { setLocal, getLocal ,getThird} from '@/addon/shop/api/delivery'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { setLocal, getLocal, getDeliveryStoreListAll } from '@/addon/shop/api/delivery'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
import Test from '@/utils/test'
|
||||
import { getShopDefaultDeliveryAddressInfo } from '@/addon/shop/api/shop_address'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const pageName = route.meta.title
|
||||
const formRef = ref<FormInstance>()
|
||||
const areaFromRef: any = ref<FormInstance[]>()
|
||||
interface addressType{
|
||||
full_address:string
|
||||
lat:string
|
||||
lng:string
|
||||
}
|
||||
const defaultDeliveryAddress:any = ref<addressType|null>(null)
|
||||
const getDefaultDeliveryAddress = async () => {
|
||||
await getShopDefaultDeliveryAddressInfo().then(({ data }) => {
|
||||
defaultDeliveryAddress.value = data
|
||||
}).catch()
|
||||
}
|
||||
getDefaultDeliveryAddress()
|
||||
const thirdPartyData = ref<any>(null)
|
||||
|
||||
const getThirdFn = ()=> {
|
||||
getThird().then((res) => {
|
||||
thirdPartyData.value = res.data.map((item: any) => ({
|
||||
...item,
|
||||
isEnabled: false, // 默认关闭
|
||||
config: {
|
||||
app_key: '',
|
||||
app_secret: '',
|
||||
shop_id: '',
|
||||
shop_store_id: ''
|
||||
}
|
||||
}));
|
||||
})
|
||||
}
|
||||
|
||||
const activeService = computed(() => {
|
||||
if (!thirdPartyData.value || thirdPartyData.value.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return thirdPartyData.value.find(service => service.isEnabled) || null;
|
||||
});
|
||||
|
||||
// 处理服务开关变化(只能开启一个服务)
|
||||
const handleServiceChange = (index: number) => {
|
||||
const service = thirdPartyData.value[index];
|
||||
if (service.isEnabled) {
|
||||
thirdPartyData.value.forEach((s, i) => {
|
||||
if (i !== index) {
|
||||
s.isEnabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const buildThirdPartyConfig = () => {
|
||||
const config: Record<string, any> = {};
|
||||
|
||||
thirdPartyData.value.forEach(service => {
|
||||
config[service.type] = {
|
||||
app_key: service.config.app_key,
|
||||
app_secret: service.config.app_secret,
|
||||
shop_id: service.config.shop_id,
|
||||
shop_store_no: service.config.shop_store_no
|
||||
};
|
||||
|
||||
if (service.isEnabled) {
|
||||
config.default = service.type;
|
||||
}
|
||||
});
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
|
||||
getThirdFn()
|
||||
const formData = ref({
|
||||
center: {
|
||||
lat: '',
|
||||
lng: ''
|
||||
},
|
||||
// delivery_type: ['business'],
|
||||
delivery_type: 'business',
|
||||
fee_type: 'region',
|
||||
time_is_open:1,
|
||||
time_type:0,
|
||||
time_week: <any>[],
|
||||
base_dist: '',
|
||||
base_price: '',
|
||||
grad_dist: '',
|
||||
grad_price: '',
|
||||
weight_start: 0.000,
|
||||
weight_unit: 0,
|
||||
weight_price: 0,
|
||||
const deliveryStoreList = ref<any>([])
|
||||
const curDelivery = ref<any>({
|
||||
area: [
|
||||
{
|
||||
area_name: '',
|
||||
@ -355,16 +153,27 @@ const formData = ref({
|
||||
key: guid()
|
||||
}
|
||||
}
|
||||
],
|
||||
delivery_time: [
|
||||
{ start_time: '', end_time: '' } // 初始一个时间段
|
||||
],
|
||||
time_interval: 30,
|
||||
most_day: 7,
|
||||
advance_day: 0,
|
||||
time_most: 1,
|
||||
time_advance:1,
|
||||
third_party_config:{}
|
||||
]
|
||||
})
|
||||
const getDeliveryStoreListAllFn = async () => {
|
||||
deliveryStoreList.value = await (await getDeliveryStoreListAll({ pick_up_type: 'local_delivery' })).data
|
||||
curDelivery.value = deliveryStoreList.value[0]
|
||||
}
|
||||
getDeliveryStoreListAllFn()
|
||||
|
||||
const formData = ref({
|
||||
center: {
|
||||
lat: '',
|
||||
lng: ''
|
||||
},
|
||||
fee_type: 'region',
|
||||
base_dist: '',
|
||||
base_price: '',
|
||||
grad_dist: '',
|
||||
grad_price: '',
|
||||
weight_start: 0.000,
|
||||
weight_unit: 0,
|
||||
weight_price: 0
|
||||
})
|
||||
|
||||
// 正则表达式
|
||||
@ -378,39 +187,22 @@ const regExp = {
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
time_week: [{ required: true, message: t('timeWeekRequire'), trigger: 'change' }],
|
||||
delivery_address: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!defaultDeliveryAddress.value) {
|
||||
callback(new Error(t('defaultDeliveryAddressEmpty')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
],
|
||||
// delivery_type: [
|
||||
// {
|
||||
// validator: (rule: any, value: any, callback: any) => {
|
||||
// if (!formData.value.delivery_type.length) {
|
||||
// callback(new Error(t('deliveryTypeRequire')))
|
||||
// }
|
||||
// callback()
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
distance: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (formData.value.fee_type == 'distance') {
|
||||
if (Test.require(formData.value.base_dist)) {
|
||||
callback(new Error(t('baseDistRequire')))
|
||||
} else if (Number(formData.value.base_dist) <= 0) {
|
||||
callback(new Error(t('起始公里数不能小于等于0')))
|
||||
}
|
||||
if (Test.require(formData.value.base_price)) {
|
||||
callback(new Error(t('basePriceRequire')))
|
||||
}
|
||||
if (Test.require(formData.value.grad_dist)) {
|
||||
callback(new Error(t('gradDistRequire')))
|
||||
} else if (Number(formData.value.grad_dist) <= 0) {
|
||||
callback(new Error(t('超出公里数不能小于等于0')))
|
||||
}
|
||||
if (Test.require(formData.value.grad_price)) {
|
||||
callback(new Error(t('gradPriceRequire')))
|
||||
@ -418,187 +210,32 @@ const formRules = computed(() => {
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
area_name: [{ required: true, message: t('areaNameRequire'), trigger: 'blur' }],
|
||||
start_price: [
|
||||
{ required: true, message: t('startPriceRequire'), trigger: 'blur' },
|
||||
weight: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (parseInt(value) < 0) {
|
||||
callback(new Error(t('startPriceMin')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
delivery_price: [
|
||||
{ required: formData.value.fee_type == 'region', message: t('deliveryPriceRequire'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (parseInt(value) < 0) {
|
||||
callback(new Error(t('deliveryPriceMin')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
area: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (Test.empty(formData.value.area)) {
|
||||
callback(new Error(t('areaPlaceholder')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
delivery_time: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!value || value.length === 0) {
|
||||
return callback(new Error(t('tradeTimePlaceholderTwo')))
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const timeRange = value[i]
|
||||
if (!timeRange.start_time || !timeRange.end_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderTwo')))
|
||||
if (formData.value.fee_type == 'distance') {
|
||||
if (Number(formData.value.weight_start) <= 0) { // 重量不能小于等于0
|
||||
callback(new Error(t('商品重量不能小于等于0')))
|
||||
}
|
||||
// 结束时间不能小于或等于开始时间
|
||||
if (timeRange.end_time <= timeRange.start_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderFour')))
|
||||
}
|
||||
// 确保后一个时间段的开始时间不能小于前一个时间段的结束时间
|
||||
if (i > 0 && value[i].start_time < value[i - 1].end_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderFive')))
|
||||
if (Number(formData.value.weight_unit) <= 0) { // 超出重量不能小于等于0
|
||||
callback(new Error(t('商品超出重量不能小于等于0')))
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'change',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
time_interval: [
|
||||
{ required: true, message: t('tradeTimePlaceholderThree'), trigger: 'change' }
|
||||
],
|
||||
advance_day:[
|
||||
{
|
||||
validator(rule, value, callback) {
|
||||
if (value === null || value === '') {
|
||||
callback()
|
||||
} else if (isNaN(value) || !regExp.number.test(value)) {
|
||||
callback(t('formatError'))
|
||||
} else if (value < 0) {
|
||||
callback(t('notLessThanZero'))
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
most_day:[
|
||||
{
|
||||
validator(rule, value, callback) {
|
||||
if (value === null || value === '') {
|
||||
callback()
|
||||
} else if (isNaN(value) || !regExp.number.test(value)) {
|
||||
callback(t('formatError'))
|
||||
} else if (value <= 0) {
|
||||
callback(t('mustBeGreaterThanZero'))
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
const validateThirdPartyConfig = () => {
|
||||
if (formData.value.delivery_type !== 'third') return true;
|
||||
|
||||
const active = thirdPartyData.value.find(item => item.isEnabled);
|
||||
if (!active) {
|
||||
ElMessage.error(t('thridRequire'));
|
||||
return false;
|
||||
}
|
||||
|
||||
const { app_key, app_secret, shop_id ,shop_store_no} = active.config;
|
||||
if (!app_key || !app_secret || !shop_id || !shop_store_no) {
|
||||
ElMessage.error(t('thridSeting'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// 添加时间段
|
||||
const addTimeRange = () => {
|
||||
formData.value.delivery_time.push({ start_time: '', end_time: '' })
|
||||
}
|
||||
|
||||
// 删除时间段
|
||||
const removeTimeRange = (index: number) => {
|
||||
formData.value.delivery_time.splice(index, 1)
|
||||
}
|
||||
|
||||
const timeTransition = (time:any) => {
|
||||
const arr = time.split(':')
|
||||
const num = arr[0] * 60 * 60 + arr[1] * 60
|
||||
return num
|
||||
}
|
||||
|
||||
const timestampTransition = (timeStamp:any) => {
|
||||
let hour = Math.floor(timeStamp / (60 * 60))
|
||||
let minute = Math.floor(timeStamp / 60) - (hour * 60)
|
||||
hour = hour < 10 ? ('0' + hour) : hour
|
||||
minute = minute < 10 ? ('0' + minute) : minute
|
||||
|
||||
return hour + ':' + minute
|
||||
}
|
||||
|
||||
getLocal().then(({ data }) => {
|
||||
loading.value = false
|
||||
if (data) Object.assign(formData.value, data)
|
||||
formData.value.time_week = formData.value.time_week?formData.value.time_week.split(','):[]
|
||||
if (Array.isArray(data.delivery_type) && data.delivery_type.length > 0) {
|
||||
formData.value.delivery_type = data.delivery_type[0];
|
||||
} else {
|
||||
formData.value.delivery_type = data.delivery_type || 'business';
|
||||
}
|
||||
// 处理 delivery_time 格式
|
||||
if (data.delivery_time === '' || data.delivery_time === null) {
|
||||
formData.value.delivery_time = [{ start_time: '', end_time: '' }];
|
||||
} else if (Array.isArray(data.delivery_time)) {
|
||||
formData.value.delivery_time = data.delivery_time.map((item: any) => ({
|
||||
start_time: timestampTransition(item.start_time),
|
||||
end_time: timestampTransition(item.end_time)
|
||||
}));
|
||||
}
|
||||
|
||||
// 回显 third_party_config 到 thirdPartyData
|
||||
if (data.third_party_config) {
|
||||
thirdPartyData.value.forEach(service => {
|
||||
const config = data.third_party_config[service.type];
|
||||
if (config) {
|
||||
service.isEnabled = service.type == data.third_party_config.default;
|
||||
service.config = {
|
||||
app_key: config.app_key || '',
|
||||
app_secret: config.app_secret || '',
|
||||
shop_id: config.shop_id || '',
|
||||
shop_store_id: config.shop_store_id || '',
|
||||
shop_store_no: config.shop_store_no || '',
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(()=>{
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@ -620,34 +257,37 @@ onMounted(() => {
|
||||
* 初始化地图
|
||||
*/
|
||||
let map: any
|
||||
let marker: any
|
||||
const mapLoading = ref(true)
|
||||
const initMap = () => {
|
||||
const TMap = (window as any).TMap
|
||||
const LatLng = TMap.LatLng
|
||||
const center = new LatLng(defaultDeliveryAddress.value ? defaultDeliveryAddress.value.lat : 39.980619, defaultDeliveryAddress.value ? defaultDeliveryAddress.value.lng : 116.321277)
|
||||
const center = new LatLng(
|
||||
curDelivery.value ? curDelivery.value.latitude : 39.980619,
|
||||
curDelivery.value ? curDelivery.value.longitude : 116.321277
|
||||
)
|
||||
|
||||
map = new TMap.Map('container', {
|
||||
center,
|
||||
zoom: 14
|
||||
})
|
||||
createMarker(map)
|
||||
|
||||
marker = createMarker(map)
|
||||
|
||||
map.on('tilesloaded', () => {
|
||||
mapLoading.value = false
|
||||
})
|
||||
|
||||
formData.value.area.forEach(item => {
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
if (curDelivery.value) {
|
||||
curDelivery.value.area.forEach((item: any) => {
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const currArea = ref<number>(0)
|
||||
|
||||
/**
|
||||
* 添加配送区域
|
||||
*/
|
||||
const addArea = () => {
|
||||
formData.value.area.push({
|
||||
curDelivery.value.area.push({
|
||||
area_name: '',
|
||||
area_type: 'radius',
|
||||
start_price: 0,
|
||||
@ -656,68 +296,109 @@ const addArea = () => {
|
||||
key: guid()
|
||||
}
|
||||
})
|
||||
const index = formData.value.area.length - 1
|
||||
createCircle(map, formData.value.area[index].area_json)
|
||||
const index = curDelivery.value.area.length - 1
|
||||
createCircle(map, curDelivery.value.area[index].area_json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配送区域
|
||||
*/
|
||||
const deleteArea = (index: number) => {
|
||||
const data = formData.value.area[index]
|
||||
const data = curDelivery.value.area[index]
|
||||
deleteGeometry(data.area_json.key)
|
||||
formData.value.area.splice(index, 1)
|
||||
curDelivery.value.area.splice(index, 1)
|
||||
}
|
||||
|
||||
const selectArea = (index: number) => {
|
||||
currArea.value = index
|
||||
const data = formData.value.area[index]
|
||||
const data = curDelivery.value.area[index]
|
||||
selectGeometry(data.area_json.key)
|
||||
}
|
||||
|
||||
const areaTypeChange = (index: number) => {
|
||||
const data = formData.value.area[index]
|
||||
const data = curDelivery.value.area[index]
|
||||
deleteGeometry(data.area_json.key)
|
||||
data.area_type == 'radius' ? createCircle(map, data.area_json) : createPolygon(map, data.area_json)
|
||||
}
|
||||
const handleMap = (data:any) => {
|
||||
deliveryStoreList.value.forEach((item: any) => {
|
||||
if (item.store_id == curDelivery.value.store_id) {
|
||||
item = deepClone(toRaw(item))
|
||||
}
|
||||
})
|
||||
curDelivery.value.area.forEach((item: any) => {
|
||||
deleteGeometry(item.area_json.key)
|
||||
})
|
||||
curDelivery.value = data
|
||||
setTimeout(() => {
|
||||
const latLng = new (window as any).TMap.LatLng(curDelivery.value.latitude, curDelivery.value.longitude)
|
||||
map.setCenter(latLng)
|
||||
marker.updateGeometries({
|
||||
id: 'center',
|
||||
position: latLng
|
||||
})
|
||||
curDelivery.value.area.forEach((item: any) => {
|
||||
// 重新创建图形
|
||||
item.area_json.center = {
|
||||
lat: curDelivery.value.latitude,
|
||||
lng: curDelivery.value.longitude
|
||||
}
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
map.destroy()
|
||||
map?.destroy()
|
||||
})
|
||||
|
||||
const verify = () => {
|
||||
let flag = true
|
||||
for (let i = 0; i < deliveryStoreList.value.length; i++) {
|
||||
const temp = deliveryStoreList.value[i].area
|
||||
if (Test.require(temp)) {
|
||||
flag = false
|
||||
ElMessage({ type: 'warning', message: `门店${deliveryStoreList.value[i].store_name}的配送区域不能为空` })
|
||||
break
|
||||
}
|
||||
for (let j = 0; j < temp.length; j++) {
|
||||
const val = temp[j]
|
||||
if (Test.require(val.area_name)) {
|
||||
flag = false
|
||||
ElMessage({ type: 'warning', message: `门店${deliveryStoreList.value[i].store_name}${j + 1}的配送区域名称不能为空` })
|
||||
break
|
||||
}
|
||||
if (parseInt(val.start_price) < 0) {
|
||||
flag = false
|
||||
ElMessage({ type: 'warning', message: `门店${deliveryStoreList.value[i].store_name}${j + 1}的起送价不能小于0` })
|
||||
break
|
||||
}
|
||||
if (parseInt(val.delivery_price) < 0 && formData.value.fee_type == 'region') {
|
||||
flag = false
|
||||
ElMessage({ type: 'warning', message: `门店${deliveryStoreList.value[i].store_name}${j + 1}的配送费不能小于0` })
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!flag) break
|
||||
}
|
||||
return flag
|
||||
}
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!verify()) return
|
||||
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
let areaValidate = true
|
||||
|
||||
for (let i = 0; i < areaFromRef.value?.length; i++) {
|
||||
const ref = areaFromRef.value[i]
|
||||
await ref.validate(async (valid) => {
|
||||
areaValidate = valid
|
||||
})
|
||||
if (!areaValidate) break
|
||||
}
|
||||
if (!areaValidate) return
|
||||
if (!validateThirdPartyConfig()) return;
|
||||
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
formData.value.center = {
|
||||
lat: defaultDeliveryAddress.value.lat,
|
||||
lng: defaultDeliveryAddress.value.lng
|
||||
}
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
const param = deepClone(toRaw(formData.value))
|
||||
param.time_week = param.time_week.toString()
|
||||
param.delivery_time = param.delivery_time.map(range => ({
|
||||
start_time: range.start_time ? timeTransition(range.start_time) : null,
|
||||
end_time: range.end_time ? timeTransition(range.end_time) : null
|
||||
}))
|
||||
param.third_party_config = buildThirdPartyConfig()
|
||||
param.delivery_type = [param.delivery_type]
|
||||
const data: any = {}
|
||||
deliveryStoreList.value.forEach((item: any) => {
|
||||
item = deepClone(toRaw(item))
|
||||
data[item.store_id] = item.area
|
||||
})
|
||||
param.area_data = data
|
||||
setLocal(param).then(() => {
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
@ -727,9 +408,25 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 新窗口打开
|
||||
const newWindow = () => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/delivery_store'
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
const back = () => {
|
||||
router.push({ path: '/shop/order/delivery' })
|
||||
router.push({ path: '/shop/delivery/config' })
|
||||
}
|
||||
|
||||
const toLink = (data: any) => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/delivery_store/edit',
|
||||
query: {
|
||||
store_id: data.store_id
|
||||
}
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -746,4 +443,14 @@ const back = () => {
|
||||
#container :deep(div){
|
||||
z-index: 2 !important;
|
||||
}
|
||||
|
||||
.store-wrap::-webkit-scrollbar{
|
||||
width:4px;
|
||||
border-radius:2px;
|
||||
background-color:#f1f1f1;
|
||||
}
|
||||
.store-wrap::-webkit-scrollbar-thumb{
|
||||
background-color:#c1c1c1;
|
||||
border-radius:2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
80
niucloud/addon/shop/admin/views/delivery/local_config.vue
Normal file
80
niucloud/addon/shop/admin/views/delivery/local_config.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="main-container bg-[#fff] rounded-[4px]">
|
||||
<div class="flex ml-[18px] justify-between items-center pt-[20px]">
|
||||
<span class="text-page-title">{{ pageName }}</span>
|
||||
</div>
|
||||
<el-form :model="formData" label-width="150px" ref="formRef" class="page-form" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-form-item :label="t('isStoreSelect')">
|
||||
<div>
|
||||
<el-switch v-model="formData.is_local_delivery_store_select" :active-value="1" :inactive-value="0" />
|
||||
<div class="text-[12px] text-[#999]">不开启时将默认选择就近配送门店,开启后同城配送下单时可主动选择配送门店</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('isShowPolyline')">
|
||||
<div>
|
||||
<el-switch v-model="formData.is_show_polyline" :active-value="1" :inactive-value="0" />
|
||||
<div class="text-[12px] text-[#999]">此功能需耗费配额,需要具备"驾车路线规划"接口的调用权限和配额方可使用</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" :loading="loading" @click="save(formRef)">{{ t('save') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { setDeliveryConfig, getDeliveryConfig } from '@/addon/shop/api/delivery'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
const formData = reactive<any>({
|
||||
is_local_delivery_store_select: 1,
|
||||
is_show_polyline: 1
|
||||
})
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*/
|
||||
getDeliveryConfig().then(res => {
|
||||
Object.assign(formData, res.data)
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
const save = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
setDeliveryConfig(formData).then(() => {
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<!--三方配送设置-->
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-page-title">{{ pageName }}</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-[20px]">
|
||||
<el-table :data="thirdDeliveryTableData.data" size="large" v-loading="thirdDeliveryTableData.loading">
|
||||
<template #empty>
|
||||
<span>{{ !thirdDeliveryTableData.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="name" :label="t('name')" min-width="100" :show-overflow-tooltip="true"/>
|
||||
<el-table-column :label="t('isUse')" min-width="180" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag class="ml-2" :type="row.is_use == 1 ? 'success': 'error'">{{ row.is_use == 1 ? t('statusNormal') : t('statusDeactivate')}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" fixed="right" min-width="200">
|
||||
<template #default="{ row, $index }">
|
||||
<template v-if="row.is_merchant">
|
||||
<el-button type="primary" link @click="toStaff">配送员</el-button>
|
||||
<el-button type="primary" link @click="toRecord">配送记录</el-button>
|
||||
</template>
|
||||
<el-button type="primary" link @click="editEvent(row, $index)" v-if="!row.is_merchant">{{ t('config') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<template v-for="(item, index) in thirdDeliveryTableData.data">
|
||||
<component :is="item.component" :ref="(el) => setThirdDeliveryTypeRefs(el, index)" v-if="item.component" @complete="loadThirdDeliveryList()"/>
|
||||
</template>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getLocalDeliveryServiceList } from '@/addon/shop/api/delivery'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
const thirdDeliveryTypeRefs = ref([])
|
||||
|
||||
const thirdDeliveryTableData = reactive({
|
||||
loading: true,
|
||||
data: []
|
||||
})
|
||||
|
||||
const modules: any = import.meta.glob('@/addon/**/views/delivery/components/*.vue')
|
||||
/**
|
||||
* 获取配置信息
|
||||
*/
|
||||
const loadThirdDeliveryList = () => {
|
||||
thirdDeliveryTableData.loading = true
|
||||
getLocalDeliveryServiceList().then(({ data }) => {
|
||||
Object.keys(data).forEach((key: string) => {
|
||||
data[key].component && (data[key].component = defineAsyncComponent(modules[data[key].component]))
|
||||
})
|
||||
thirdDeliveryTableData.data = data
|
||||
thirdDeliveryTableData.loading = false
|
||||
}).catch(() => {
|
||||
thirdDeliveryTableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const setThirdDeliveryTypeRefs = (el, index) => {
|
||||
thirdDeliveryTypeRefs.value[index] = (el)
|
||||
}
|
||||
|
||||
loadThirdDeliveryList()
|
||||
const editEvent = (data: any, index: number) => {
|
||||
thirdDeliveryTypeRefs.value[index].setFormData(data)
|
||||
thirdDeliveryTypeRefs.value[index].showDialog = true
|
||||
}
|
||||
|
||||
const toStaff = () => {
|
||||
router.push('/shop/delivery/staff')
|
||||
}
|
||||
const toRecord = () => {
|
||||
router.push('/shop/delivery/merchant/record')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
287
niucloud/addon/shop/admin/views/delivery/local_record.vue
Normal file
287
niucloud/addon/shop/admin/views/delivery/local_record.vue
Normal file
@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="right">{{ pageName }}</span>
|
||||
</div>
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="localRecordTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('deliveryNo')" prop="delivery_no">
|
||||
<el-input v-model.trim="localRecordTable.searchParam.delivery_no" :placeholder="t('deliveryNoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('tradeNo')" prop="trade_no">
|
||||
<el-input v-model.trim="localRecordTable.searchParam.trade_no" :placeholder="t('tradeNoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStatus')" prop="status">
|
||||
<el-select v-model="localRecordTable.searchParam.status" :placeholder="t('deliveryStatusPlaceholder')" clearable>
|
||||
<el-option v-for="(item,key) in statusList" :key="key" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('createTime')" prop="create_time">
|
||||
<el-date-picker v-model="localRecordTable.searchParam.create_time" type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||
:end-placeholder="t('endDate')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadLocalDeliveryList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="localRecordTable.data" size="large" v-loading="localRecordTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !localRecordTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="delivery_service_name" :label="t('deliveryServiceName')" min-width="120" />
|
||||
<el-table-column prop="body" :label="t('goodsInfo')" min-width="120" />
|
||||
<el-table-column prop="delivery_no" :label="t('deliveryNo')" min-width="120" />
|
||||
<el-table-column prop="trade_no" :label="t('tradeNo')" min-width="120" />
|
||||
<el-table-column prop="delivery_start" :label="t('deliveryStart')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div class="cursor-pointer" @click="openMap(row,'start')">
|
||||
<span>{{ row.delivery_start }}</span>
|
||||
<span class="text-primary ml-[4px] nc-iconfont nc-icon-chakandituV6xx" ></span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="delivery_end" :label="t('deliveryEnd')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div class="cursor-pointer" @click="openMap(row, 'end')">
|
||||
<span>{{ row.delivery_end }}</span>
|
||||
<span class="text-primary ml-[4px] nc-iconfont nc-icon-chakandituV6xx" ></span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status_name" :label="t('deliveryStatus')" min-width="120" />
|
||||
<el-table-column prop="" :label="t('deliveryDistance')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
{{ distance(row.delivery_distance) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('deliveryMoney')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
¥{{ row.delivery_money }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" :label="t('createTime')" min-width="120" />
|
||||
<el-table-column prop="remark" :label="t('remark')" min-width="120" />
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="120" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button>
|
||||
<el-button type="primary" link @click="syncEvent(row)" v-if="row.pre_status_name?.sync && row.pre_status_name?.sync.indexOf(Number(row.status)) != -1">{{ t('sync') }}</el-button>
|
||||
<el-button type="primary" link @click="finishEvent(row)" v-if="row.pre_status_name?.finish && row.pre_status_name?.finish.indexOf(Number(row.status)) != -1">{{ t('finish') }}</el-button>
|
||||
<el-button type="primary" link @click="cancelEvent(row)" v-if="row.pre_status_name?.cancel && row.pre_status_name?.cancel.indexOf(Number(row.status)) != -1">{{ t('cancel') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="localRecordTable.page" v-model:page-size="localRecordTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="localRecordTable.total"
|
||||
@size-change="loadLocalDeliveryList()" @current-change="loadLocalDeliveryList" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<local-record-detail ref="localRecordDetailRef" />
|
||||
<!-- 查看地图 -->
|
||||
<map-info ref="mapInfoRef" />
|
||||
<el-dialog v-model="showDialog" :title="t('deliveryCancel')" width="480" class="diy-dialog-wrap" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<template v-if="formData.cancel_type != 'merchant'">
|
||||
<el-form-item :label="t('cancelReason')" prop="cancel_reason_id">
|
||||
<el-select v-model="formData.cancel_reason_id" clearable class="input-item" :placeholder="t('cancelReasonSelectPlaceholder')">
|
||||
<el-option v-for="(item, index) in reasonList" :key="index" :label="item" :value="index"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="cancel_reason" v-if="formData.cancel_reason_id == 10000">
|
||||
<el-input v-model="formData.cancel_reason" type="textarea" rows="4" maxlength="200" clearable class="input-width" :placeholder="t('cancelReasonPlaceholder')" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="t('cancelReason')" prop="cancel_reason" v-if="formData.cancel_type == 'merchant'">
|
||||
<el-input v-model="formData.cancel_reason" type="textarea" rows="4" maxlength="200" clearable class="input-width" :placeholder="t('cancelReasonPlaceholder')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { t } from '@/lang'
|
||||
import { distance } from '@/utils/common'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getLocalDeliveryList, getLocalDeliveryStatus, getLocalDeliverySync, getLocalDeliveryCancelReason, getDeliveryFinish, setLocalDeliveryCancel } from '@/addon/shop/api/delivery'
|
||||
import LocalRecordDetail from '@/addon/shop/views/delivery/components/local_record_detail.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const localRecordTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
delivery_no: '',
|
||||
trade_no: route.query.trade_no || '',
|
||||
trade_type: route.query.trade_type || '',
|
||||
status: '',
|
||||
create_time: ''
|
||||
}
|
||||
})
|
||||
const statusList = ref<any>([])
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
const getLocalDeliveryStatusFn = () => {
|
||||
getLocalDeliveryStatus().then(res => {
|
||||
statusList.value = res.data
|
||||
})
|
||||
}
|
||||
getLocalDeliveryStatusFn()
|
||||
/**
|
||||
* 获取配送记录列表
|
||||
*/
|
||||
const loadLocalDeliveryList = (page: number = 1) => {
|
||||
localRecordTable.loading = true
|
||||
localRecordTable.page = page
|
||||
|
||||
getLocalDeliveryList({
|
||||
page: localRecordTable.page,
|
||||
limit: localRecordTable.limit,
|
||||
...localRecordTable.searchParam
|
||||
}).then((res: any) => {
|
||||
localRecordTable.loading = false
|
||||
localRecordTable.data = res.data.data
|
||||
localRecordTable.total = res.data.total
|
||||
}).catch(() => {
|
||||
localRecordTable.loading = false
|
||||
})
|
||||
}
|
||||
loadLocalDeliveryList()
|
||||
|
||||
// 详情
|
||||
const localRecordDetailRef = ref()
|
||||
const detailEvent = (row: any) => {
|
||||
localRecordDetailRef.value?.setFormData(row)
|
||||
}
|
||||
|
||||
// 查看地图
|
||||
const mapInfoRef = ref()
|
||||
const openMap = (data: any, type: string) => {
|
||||
const obj: any = {}
|
||||
if (type == 'start') {
|
||||
obj.taker_latitude = data.delivery_start_lat
|
||||
obj.taker_longitude = data.delivery_start_lng
|
||||
obj.taker_address = data.delivery_start
|
||||
} else {
|
||||
obj.taker_latitude = data.delivery_end_lat
|
||||
obj.taker_longitude = data.delivery_start_lng
|
||||
obj.taker_address = data.delivery_end
|
||||
}
|
||||
mapInfoRef.value?.setFormData(obj)
|
||||
}
|
||||
|
||||
// 同步
|
||||
const syncEvent = (data: any) => {
|
||||
ElMessageBox.confirm(t('syncTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
getLocalDeliverySync(data.id).then(() => {
|
||||
loadLocalDeliveryList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 完成
|
||||
const finishEvent = (data: any) => {
|
||||
ElMessageBox.confirm(t('finishTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
getDeliveryFinish(data.id).then(() => {
|
||||
loadLocalDeliveryList()
|
||||
})
|
||||
})
|
||||
}
|
||||
// 取消
|
||||
const showDialog = ref(false)
|
||||
const reasonList = ref([])
|
||||
const loading = ref(false)
|
||||
const formData = reactive<any>({
|
||||
id: '',
|
||||
cancel_reason_id: '',
|
||||
cancel_reason: '',
|
||||
cancel_type: ''
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
const cancelEvent = async (data: any) => {
|
||||
formData.id = data.id
|
||||
formData.cancel_type = data.delivery_service
|
||||
if (data.delivery_service != 'merchant') {
|
||||
reasonList.value = await (await getLocalDeliveryCancelReason({ service: data.delivery_service })).data
|
||||
}
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
cancel_reason_id: [
|
||||
{ required: formData.cancel_type != 'merchant', message: t('cancelReasonSelectPlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
cancel_reason: [
|
||||
{ required: formData.cancel_reason_id == 10000 || formData.cancel_type == 'merchant', message: t('cancelReasonPlaceholder'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
setLocalDeliveryCancel(formData).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
setTimeout(() => {
|
||||
loadLocalDeliveryList()
|
||||
}, 1500)
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadLocalDeliveryList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-form-item){
|
||||
align-items: flex-start;
|
||||
}
|
||||
</style>
|
||||
249
niucloud/addon/shop/admin/views/delivery/merchant_record.vue
Normal file
249
niucloud/addon/shop/admin/views/delivery/merchant_record.vue
Normal file
@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="right">{{ pageName }}</span>
|
||||
</div>
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="shopRecordTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('deliveryNo')" prop="delivery_no">
|
||||
<el-input v-model.trim="shopRecordTable.searchParam.delivery_no" :placeholder="t('deliveryNoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('tradeNo')" prop="trade_no">
|
||||
<el-input v-model.trim="shopRecordTable.searchParam.trade_no" :placeholder="t('tradeNoPlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryStatus')" prop="status">
|
||||
<el-select v-model="shopRecordTable.searchParam.status" :placeholder="t('deliveryStatusPlaceholder')" clearable>
|
||||
<el-option v-for="(item,key) in statusList" :key="key" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('createTime')" prop="create_time">
|
||||
<el-date-picker v-model="shopRecordTable.searchParam.create_time" type="datetimerange"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
|
||||
:end-placeholder="t('endDate')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadShopDeliveryList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="shopRecordTable.data" size="large" v-loading="shopRecordTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !shopRecordTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="delivery_no" :label="t('deliveryNo')" min-width="120" />
|
||||
<el-table-column prop="body" :label="t('goodsInfo')" min-width="120" />
|
||||
<el-table-column prop="trade_no" :label="t('tradeNo')" min-width="120" />
|
||||
<el-table-column prop="delivery_start" :label="t('deliveryStart')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div class="cursor-pointer" @click="openMap(row,'start')">
|
||||
<span>{{ row.delivery_start }}</span>
|
||||
<span class="text-primary ml-[4px] nc-iconfont nc-icon-chakandituV6xx"></span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="delivery_end" :label="t('deliveryEnd')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div class="cursor-pointer" @click="openMap(row, 'end')">
|
||||
<span>{{ row.delivery_end }}</span>
|
||||
<span class="text-primary ml-[4px] cursor-pointer nc-iconfont nc-icon-chakandituV6xx"></span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status_name" :label="t('deliveryStatus')" min-width="120" />
|
||||
<el-table-column prop="delivery_distance" :label="t('deliveryDistance')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
{{ distance(row.delivery_distance) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="delivery_money" :label="t('deliveryMoney')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
¥{{ row.delivery_money }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" :label="t('createTime')" min-width="120" />
|
||||
<el-table-column prop="remark" :label="t('remark')" min-width="120" />
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="120" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="detailEvent(row)">{{ t('detail') }}</el-button>
|
||||
<el-button type="primary" link @click="finishEvent(row)" v-if="row.pre_status_name?.finish && row.pre_status_name?.finish.indexOf(Number(row.status)) != -1">{{ t('finish') }}</el-button>
|
||||
<el-button type="primary" link @click="cancelEvent(row)" v-if="row.pre_status_name?.cancel && row.pre_status_name?.cancel.indexOf(Number(row.status)) != -1">{{ t('cancel') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="shopRecordTable.page" v-model:page-size="shopRecordTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="shopRecordTable.total"
|
||||
@size-change="loadShopDeliveryList()" @current-change="loadShopDeliveryList" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<shop-record-detail ref="shopRecordDetailRef" />
|
||||
<!-- 查看地图 -->
|
||||
<map-info ref="mapInfoRef" />
|
||||
<el-dialog v-model="showDialog" :title="t('deliveryCancel')" width="480" class="diy-dialog-wrap" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('cancelReason')" prop="cancel_reason">
|
||||
<el-input v-model="formData.cancel_reason" type="textarea" rows="4" maxlength="200" clearable class="input-width" :placeholder="t('cancelReasonPlaceholder')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { t } from '@/lang'
|
||||
import { distance } from '@/utils/common'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getShopDeliveryOrderList, getShopDeliveryStatus, getShopDeliveryFinish, setShopDeliveryCancel } from '@/addon/shop/api/delivery'
|
||||
import ShopRecordDetail from '@/addon/shop/views/delivery/components/shop_record_detail.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const shopRecordTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
delivery_no: '',
|
||||
trade_no: route.query.trade_no || '',
|
||||
trade_type: route.query.trade_type || '',
|
||||
status: '',
|
||||
create_time: ''
|
||||
}
|
||||
})
|
||||
const statusList = ref<any>([])
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
const getShopDeliveryStatusFn = () => {
|
||||
getShopDeliveryStatus().then(res => {
|
||||
statusList.value = res.data
|
||||
})
|
||||
}
|
||||
getShopDeliveryStatusFn()
|
||||
|
||||
/**
|
||||
* 获取配送记录列表
|
||||
*/
|
||||
const loadShopDeliveryList = (page: number = 1) => {
|
||||
shopRecordTable.loading = true
|
||||
shopRecordTable.page = page
|
||||
|
||||
getShopDeliveryOrderList({
|
||||
page: shopRecordTable.page,
|
||||
limit: shopRecordTable.limit,
|
||||
...shopRecordTable.searchParam
|
||||
}).then((res: any) => {
|
||||
shopRecordTable.loading = false
|
||||
shopRecordTable.data = res.data.data
|
||||
shopRecordTable.total = res.data.total
|
||||
}).catch(() => {
|
||||
shopRecordTable.loading = false
|
||||
})
|
||||
}
|
||||
loadShopDeliveryList()
|
||||
|
||||
// 详情
|
||||
const shopRecordDetailRef = ref()
|
||||
const detailEvent = (row: any) => {
|
||||
shopRecordDetailRef.value?.setFormData(row)
|
||||
}
|
||||
|
||||
// 查看地图
|
||||
const mapInfoRef = ref()
|
||||
const openMap = (data: any, type: string) => {
|
||||
const obj: any = {}
|
||||
if (type == 'start') {
|
||||
obj.taker_latitude = data.delivery_start_lat
|
||||
obj.taker_longitude = data.delivery_start_lng
|
||||
obj.taker_address = data.delivery_start
|
||||
} else {
|
||||
obj.taker_latitude = data.delivery_end_lat
|
||||
obj.taker_longitude = data.delivery_start_lng
|
||||
obj.taker_address = data.delivery_end
|
||||
}
|
||||
mapInfoRef.value?.setFormData(obj)
|
||||
}
|
||||
|
||||
// 完成
|
||||
const finishEvent = (data: any) => {
|
||||
ElMessageBox.confirm(t('finishTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
getShopDeliveryFinish(data.id).then(() => {
|
||||
loadShopDeliveryList()
|
||||
})
|
||||
})
|
||||
}
|
||||
// 取消
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
const formData = reactive<any>({
|
||||
id: '',
|
||||
cancel_reason: ''
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const cancelEvent = async (data: any) => {
|
||||
formData.id = data.id
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
cancel_reason: [
|
||||
{ required: true, message: t('cancelReasonPlaceholder'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
setShopDeliveryCancel(formData).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
loadShopDeliveryList()
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadShopDeliveryList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-form-item){
|
||||
align-items: flex-start;
|
||||
}
|
||||
</style>
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none mb-[15px]" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push({ path: '/shop/order/delivery' })" />
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push({ path: '/shop/delivery/config' })" />
|
||||
</el-card>
|
||||
<el-form :model="formData" label-width="150px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push('/shop/order/delivery')" />
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push('/shop/delivery/config')" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
@ -104,7 +104,7 @@ loadTemplateList(getTablePageStorage(templateTable.searchParam).page);
|
||||
* 添加运费模板
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push({ path: '/shop/order/shipping/template_edit' })
|
||||
router.push({ path: '/shop/shipping/template_edit' })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,7 +112,7 @@ const addEvent = () => {
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push({ path: '/shop/order/shipping/template_edit', query: { id: data.template_id } })
|
||||
router.push({ path: '/shop/shipping/template_edit', query: { id: data.template_id } })
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -474,7 +474,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
||||
data.area = Object.values(area)
|
||||
save(data).then(() => {
|
||||
loading.value = false
|
||||
router.push({ path: '/shop/order/shipping/template' })
|
||||
router.push({ path: '/shop/shipping/template' })
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
@ -483,7 +483,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push({ path: '/shop/order/shipping/template' })
|
||||
router.push({ path: '/shop/shipping/template' })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
164
niucloud/addon/shop/admin/views/delivery_store/delivery_set.vue
Normal file
164
niucloud/addon/shop/admin/views/delivery_store/delivery_set.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none mb-[15px]" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push(`/shop/delivery_store`)" />
|
||||
</el-card>
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<el-table :data="deliveryServiceTable.data" size="large" v-loading="deliveryServiceTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !deliveryServiceTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="name" :label="t('deliveryServiceName')" min-width="200" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="open_status" :label="t('openStatus')" width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.open_status == ''">—</div>
|
||||
<el-tag v-else class="cursor-pointer" :type="row.open_status == 1 ? 'success' : 'danger'">{{ row.open_status == 1 ? t('pass') : t('notPass') }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="edit_status" :label="t('editStatus')" width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.edit_status == ''">—</div>
|
||||
<el-tag v-else class="cursor-pointer" :type="row.edit_status == 1 ? 'success' : 'danger'">{{ row.edit_status == 1 ? t('pass') : t('notPass') }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="reason" :label="t('reason')" :show-overflow-tooltip="true" min-width="500"/>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="openEvent(row)" v-if="row.is_merchant == 0 && row.open_status != 1">{{ t('openService') }}</el-button>
|
||||
<el-button type="primary" link @click="editEvent(row)" v-if="row.is_merchant == 0 && row.open_status == 1">{{ t('editService') }}</el-button>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
|
||||
</el-card>
|
||||
|
||||
<!-- 开通/修改品类 -->
|
||||
<el-dialog v-model="showDialog" :title="title" width="500px" :destroy-on-close="true">
|
||||
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRulesDeliverySet" class="page-form" v-loading="loadingDeliverySet">
|
||||
<el-form-item :label="t('business')" prop="business">
|
||||
<el-select v-model="formData.business" clearable :placeholder="t('businessPlaceholder')">
|
||||
<el-option :label="value" :value="key" v-for="(value, key, index) in businessOptions" :key="index"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loadingDeliverySet" @click="confirmDeliverySet(formRef)">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getDeliveryServiceList, deliveryShopOpen, deliveryShopEdit } from '@/addon/shop/api/delivery'
|
||||
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const pageName = route.meta.title
|
||||
|
||||
const id:any = ref(route.query.id || 0)
|
||||
|
||||
const deliveryServiceTable = reactive({
|
||||
loading: true,
|
||||
data: []
|
||||
})
|
||||
|
||||
const loadDeliveryServiceList = () => {
|
||||
// 查询配送服务商列表
|
||||
getDeliveryServiceList(id.value).then((res: any) => {
|
||||
deliveryServiceTable.data = cloneDeep(res.data)
|
||||
deliveryServiceTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadDeliveryServiceList()
|
||||
|
||||
const businessOptions = ref({})
|
||||
|
||||
const showDialog = ref(false)
|
||||
const loadingDeliverySet = ref(false)
|
||||
const formRef = ref<FormInstance>()
|
||||
const formData = reactive({
|
||||
id: id.value,
|
||||
delivery_type: '',
|
||||
business: '',
|
||||
extend_data: {},
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const formRulesDeliverySet = computed(() => {
|
||||
return {
|
||||
business: [
|
||||
{ required: true, message: t('businessPlaceholder'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const title = ref('')
|
||||
const isOpen = ref(false)
|
||||
// 开通
|
||||
const openEvent = (data:any) => {
|
||||
title.value = t('openService') + data.name
|
||||
businessOptions.value = data.business_list
|
||||
formData.delivery_type = data.key
|
||||
formData.extend_data = data.extend_data
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 修改品类
|
||||
const editEvent = (data:any) => {
|
||||
title.value = t('editService')
|
||||
businessOptions.value = data.business_list
|
||||
formData.delivery_type = data.key
|
||||
formData.business = data.business
|
||||
showDialog.value = true
|
||||
isOpen.value = data.open_status == 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirmDeliverySet = async (formEl: FormInstance | undefined) => {
|
||||
if (loadingDeliverySet.value || !formEl) return
|
||||
const save = isOpen.value ? deliveryShopEdit : deliveryShopOpen
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loadingDeliverySet.value = true
|
||||
save(formData).then(res => {
|
||||
loadingDeliverySet.value = false
|
||||
showDialog.value = false
|
||||
loadDeliveryServiceList()
|
||||
}).catch(() => {
|
||||
loadingDeliverySet.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
898
niucloud/addon/shop/admin/views/delivery_store/edit.vue
Normal file
898
niucloud/addon/shop/admin/views/delivery_store/edit.vue
Normal file
@ -0,0 +1,898 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none mb-[15px]" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="back" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-alert type="warning" :closable="false" class="!mb-[15px]" v-if="formData.is_system === 1">
|
||||
<template #default>
|
||||
<p>{{ t('deliveryStoreTips') }}<span class="text-primary cursor-pointer" @click="newWindow()">去修改</span><span class="text-primary cursor-pointer ml-[10px]" @click="refreshAddress(true)">刷新</span></p>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form label-width="120px" ref="formRef" :rules="formRules" :model="formData" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('提货类型')" prop="pick_up_type">
|
||||
<el-checkbox-group v-model="formData.pick_up_type" @change="changePickUpType">
|
||||
<el-checkbox :label="index" v-for="(item,index) in pickUpType" :key="index">{{ item }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('storeName')" prop="store_name">
|
||||
<el-input v-model.trim="formData.store_name" clearable :placeholder="t('storeNamePlaceholder')" class="input-width" maxlength="30" :disabled="formData.is_system === 1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('contactName')" prop="contact_name">
|
||||
<el-input v-model.trim="formData.contact_name" clearable :placeholder="t('contactNamePlaceholder')" class="input-width" maxlength="30" :disabled="formData.is_system === 1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('storeMobile')" prop="store_mobile">
|
||||
<el-input v-model.trim="formData.store_mobile" clearable :placeholder="t('storeMobilePlaceholder')" class="input-width" @keyup="filterNumber($event)" @blur="formData.store_mobile = $event.target.value" maxlength="11" :disabled="formData.is_system === 1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('tradeTime')" prop="trade_time">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.trade_time" clearable :placeholder="t('tradeTimePlaceholder')" class="input-width" :disabled="formData.is_system === 1" />
|
||||
<p class="text-[12px] text-[#999]">{{ t('tradeTimeTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('开启状态')" prop="status">
|
||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('timeIsOpen')" prop="time_is_open">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.time_is_open">
|
||||
<el-radio :label="1">{{ t('open') }}</el-radio>
|
||||
<el-radio :label="0">{{ t('close') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="mt-[10px] text-[12px] text-[#999] leading-[20px]">{{t('timeIsOpenTips')}}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<template v-if="formData.time_is_open === 1">
|
||||
<el-form-item :label="t('自提日期')" prop="time_week" >
|
||||
<el-checkbox-group v-model="formData.time_week">
|
||||
<el-checkbox :label="'1'">{{ t('monday') }}</el-checkbox>
|
||||
<el-checkbox :label="'2'">{{ t('tuesday') }}</el-checkbox>
|
||||
<el-checkbox :label="'3'">{{ t('wednesday') }}</el-checkbox>
|
||||
<el-checkbox :label="'4'">{{ t('thursday') }}</el-checkbox>
|
||||
<el-checkbox :label="'5'">{{ t('friday') }}</el-checkbox>
|
||||
<el-checkbox :label="'6'">{{ t('saturday') }}</el-checkbox>
|
||||
<el-checkbox :label="'0'">{{ t('sunday') }}</el-checkbox>
|
||||
<br />
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliveryTime')" prop="trade_time_json">
|
||||
<div>
|
||||
<div>
|
||||
<div v-for="(timeRange, index) in formData.trade_time_json" :key="index" class="mb-3">
|
||||
<el-time-picker v-model="timeRange.start_time" :placeholder="t('startTime')"
|
||||
format="HH:mm" value-format="HH:mm"
|
||||
:picker-options="{selectableRange: '00:00 - 23:59'}" />
|
||||
<span class="mx-2">-</span>
|
||||
<el-time-picker v-model="timeRange.end_time" :placeholder="t('endTime')" format="HH:mm"
|
||||
value-format="HH:mm" :picker-options="{selectableRange: '00:00 - 23:59'}" />
|
||||
<span v-if="index > 0" class="text-primary cursor-pointer ml-[10px]"
|
||||
@click="removeTimeRange(index)"> {{ t('delete') }}</span>
|
||||
</div>
|
||||
<span class="text-primary cursor-pointer mr-[10px]" @click="addTimeRange"
|
||||
v-if="formData.trade_time_json.length < 3"> {{ t('addTime') }}</span>
|
||||
</div>
|
||||
<div class="text-[12px] text-[#999]">{{ t('deliveryTimeTips') }}</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('timeInterval')" prop="time_interval">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.time_interval">
|
||||
<el-radio v-for="(item, key) in time_interval_list" :key="key" :label="item.type">{{ item.name }}</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="formData.pick_up_type.indexOf('local_delivery') != -1">
|
||||
<el-form-item :label="t('feeType')">
|
||||
<el-radio-group v-model="initData.fee_type" >
|
||||
<el-radio label="region" disabled>{{ t('region') }}</el-radio>
|
||||
<el-radio label="distance" disabled>{{ t('distance') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('feeSetting')" prop="distance" v-show="initData.fee_type == 'distance'">
|
||||
<div class="flex">
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.number="initData.base_dist" disabled type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextOne') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="initData.base_price" disabled type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextTwo') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.number="initData.grad_dist" disabled type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextThree') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="initData.grad_price" disabled type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('priceUnit') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('weightFee')" prop="weight">
|
||||
<div class="flex">
|
||||
{{ t('weightFeeTextOne') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="initData.weight_start" disabled type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('weightFeeTextTwo') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="initData.weight_unit" disabled type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('weightFeeTextThree') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="initData.weight_price" disabled type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('priceUnit') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="t('地址')" prop="address_area">
|
||||
<el-select v-model="formData.province_id" value-key="id" @change="handleFlash" clearable class="w-[200px]" ref="provinceRef" :disabled="formData.is_system === 1">
|
||||
<el-option :label="t('provincePlaceholder')" :value="0"/>
|
||||
<el-option v-for="(item, index) in areaList.province" :key="index" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
<el-select v-model="formData.city_id" value-key="id" @change="handleFlash" clearable class="w-[200px] ml-3" ref="cityRef" :disabled="formData.is_system === 1">
|
||||
<el-option :label="t('cityPlaceholder')" :value="0"/>
|
||||
<el-option v-for="(item, index) in areaList.city " :key="index" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
<el-select v-model="formData.district_id" value-key="id" @change="handleFlash" clearable class="w-[200px] ml-3" ref="districtRef" :disabled="formData.is_system === 1">
|
||||
<el-option :label="t('districtPlaceholder')" :value="0"/>
|
||||
<el-option v-for="(item, index) in areaList.district " :key="index" :label="item.name" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="address">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.address" clearable :placeholder="t('addressPlaceholder')" @input="areaChange()" class="input-width" :disabled="formData.is_system === 1"/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="area" v-loading="mapLoading">
|
||||
<div class="relative w-full">
|
||||
<div id="container" class="w-full h-[520px]"></div>
|
||||
<div class="absolute bg-white w-[270px] h-[500px] top-[10px] left-[10px] region-list" v-if="formData.pick_up_type.indexOf('local_delivery') != -1">
|
||||
<el-scrollbar>
|
||||
<div class="p-[10px] region-item pr-[50px] relative" v-for="(item, index) in formData.area" :key="index" :class="{ '!border-primary': index == currArea }" @click="selectArea(index)">
|
||||
<el-form label-width="80px" :model="item" :rules="formRules" class="page-form"
|
||||
ref="areaFromRef">
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('areaName')" prop="area_name">
|
||||
<el-input v-model.trim="formData.area[index].area_name" type="text" @click.stop=""/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="pb-[18px]">
|
||||
<el-form-item :label="t('startPrice')" prop="start_price">
|
||||
<el-input v-model.trim="formData.area[index].start_price" maxlength="8" type="text"
|
||||
@keyup="filterDigit($event)" @click.stop="" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="pb-[10px]" v-show="initData.fee_type == 'region'">
|
||||
<el-form-item :label="t('deliveryPrice')" prop="delivery_price">
|
||||
<el-input v-model.trim="formData.area[index].delivery_price" type="text"
|
||||
@keyup="filterDigit($event)" @click.stop=""/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item :label="t('areaType')">
|
||||
<el-radio-group v-model="formData.area[index].area_type" @change="areaTypeChange(index)">
|
||||
<el-radio label="radius" size="large" class="!mr-[10px]">{{ t('radius') }}</el-radio>
|
||||
<el-radio label="custom" size="large" class="!mr-[0px]">{{ t('custom') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" link class="absolute z-1 top-[10px] right-[10px]"
|
||||
@click.stop="deleteArea(index)">{{ t('delete') }}</el-button>
|
||||
</div>
|
||||
<div class="p-[10px] text-center">
|
||||
<el-button plain @click="addArea">{{ t('addDeliveryArea') }}</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" @click="onSave(formRef)" :disabled="loading">{{ t('save') }}</el-button>
|
||||
<el-button @click="back()">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { guid, filterNumber, filterDigit, deepClone, debounce } from '@/utils/common'
|
||||
import { getMap, getAreaListByPid, getAreaByCode } from '@/app/api/sys'
|
||||
import { createCircle, deleteGeometry, createPolygon, selectGeometry, createMarker, latLngToAddress, addressToLatLng } from '@/utils/qqmap'
|
||||
import { getDeliveryStoreDetail, addDeliveryStore, editDeliveryStore, getStoreInit, getStorePickUpType } from '@/addon/shop/api/delivery'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
import Test from '@/utils/test'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
const pageName = route.meta.title
|
||||
const formRef = ref<FormInstance>()
|
||||
const areaFromRef: any = ref<FormInstance[]>()
|
||||
const initialFormData = {
|
||||
store_id: '',
|
||||
pick_up_type: [],
|
||||
store_name: '',
|
||||
contact_name: '',
|
||||
store_mobile: '',
|
||||
status: 1,
|
||||
province_id: 0,
|
||||
city_id: 0,
|
||||
district_id: 0,
|
||||
address: '',
|
||||
full_address: '',
|
||||
latitude: 39.908626,
|
||||
longitude: 116.397190,
|
||||
trade_time: '',
|
||||
time_is_open: 1,
|
||||
time_week: ['1', '2', '3', '4', '5', '6', '0'],
|
||||
area: [
|
||||
{
|
||||
area_name: '',
|
||||
area_type: 'radius',
|
||||
start_price: 0,
|
||||
delivery_price: 0,
|
||||
area_json: {
|
||||
key: guid()
|
||||
}
|
||||
}
|
||||
],
|
||||
trade_time_json: [
|
||||
{ start_time: '', end_time: '' } // 初始一个时间段
|
||||
],
|
||||
time_interval: 30,
|
||||
is_system: 0
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
formData.store_id = route.query.store_id
|
||||
const pickUpType = ref([])
|
||||
const initData = reactive<any>({
|
||||
fee_type: 'region',
|
||||
base_dist: '',
|
||||
base_price: '',
|
||||
grad_dist: '',
|
||||
grad_price: '',
|
||||
weight_start: 0.000,
|
||||
weight_unit: 0,
|
||||
weight_price: 0
|
||||
})
|
||||
const flash = ref(false)
|
||||
const getStorePickUpTypeFn = () => {
|
||||
getStorePickUpType().then(res => {
|
||||
pickUpType.value = res.data
|
||||
})
|
||||
}
|
||||
getStorePickUpTypeFn()
|
||||
|
||||
const getDeliveryStoreDetailFn = () => {
|
||||
getDeliveryStoreDetail(formData.store_id).then(({ data }) => {
|
||||
loading.value = false
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
if (key == 'trade_time_json' && Array.isArray(data[key])) {
|
||||
formData[key] = data[key].map((item: any) => ({
|
||||
start_time: timestampTransition(item.start_time),
|
||||
end_time: timestampTransition(item.end_time)
|
||||
}))
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
if (route.query.store_id) {
|
||||
getDeliveryStoreDetailFn()
|
||||
} else {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const refreshAddress = (bool = false) => {
|
||||
getDeliveryStoreDetail(formData.store_id).then(({ data }) => {
|
||||
loading.value = false
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
const addressKeyArr = ['store_name', 'contact_name', 'store_mobile', 'trade_time', 'province_id', 'city_id', 'district_id', 'address', 'full_address', 'latitude', 'longitude']
|
||||
if (addressKeyArr.includes(key)) {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
}
|
||||
})
|
||||
if (bool) {
|
||||
ElMessage({
|
||||
message: t('refreshSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const week_list = ref({})
|
||||
const time_interval_list = ref({})
|
||||
const getStoreInitFn = () => {
|
||||
getStoreInit().then(res => {
|
||||
week_list.value = res.data.week_list
|
||||
time_interval_list.value = res.data.time_interval_list
|
||||
Object.keys(initData).forEach((key: string) => {
|
||||
if (res.data.local_delivery_config[key] != undefined) initData[key] = res.data.local_delivery_config[key]
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
interface areaType{
|
||||
province: any[],
|
||||
city: any[],
|
||||
district: any[]
|
||||
}
|
||||
const areaList = reactive<areaType>({
|
||||
province: [],
|
||||
city: [],
|
||||
district: []
|
||||
})
|
||||
const provinceRef = ref()
|
||||
const cityRef = ref()
|
||||
const districtRef = ref()
|
||||
|
||||
/**
|
||||
* 获取省
|
||||
*/
|
||||
getAreaListByPid(0).then(res => {
|
||||
areaList.province = res.data
|
||||
})
|
||||
|
||||
let mapKey: string = ''
|
||||
onMounted(() => {
|
||||
const mapScript = document.createElement('script')
|
||||
getMap().then(res => {
|
||||
mapKey = res.data.key
|
||||
mapScript.type = 'text/javascript'
|
||||
mapScript.src = 'https://map.qq.com/api/gljs?libraries=tools,service&v=1.exp&key=' + res.data.key
|
||||
document.body.appendChild(mapScript)
|
||||
})
|
||||
mapScript.onload = () => {
|
||||
setTimeout(() => {
|
||||
initMap()
|
||||
}, 500)
|
||||
}
|
||||
getStoreInitFn()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
let map: any
|
||||
let marker: any
|
||||
const mapLoading = ref(true)
|
||||
const initMap = () => {
|
||||
const TMap = (window as any).TMap
|
||||
const LatLng = TMap.LatLng
|
||||
const center = new LatLng(formData.latitude, formData.longitude)
|
||||
|
||||
map = new TMap.Map('container', {
|
||||
center,
|
||||
zoom: 14
|
||||
})
|
||||
|
||||
map.on('tilesloaded', () => {
|
||||
mapLoading.value = false
|
||||
})
|
||||
|
||||
marker = createMarker(map)
|
||||
|
||||
map.on('click', (evt: any) => {
|
||||
map.setCenter(evt.latLng)
|
||||
marker.updateGeometries({
|
||||
id: 'center',
|
||||
position: evt.latLng
|
||||
})
|
||||
latLngChange(evt.latLng.lat, evt.latLng.lng)
|
||||
})
|
||||
|
||||
latLngChange(center.lat, center.lng)
|
||||
|
||||
if (formData.pick_up_type.indexOf('local_delivery') != -1) {
|
||||
formData.area.forEach(item => {
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const storeArea = reactive({
|
||||
province_id: 0,
|
||||
city_id: 0,
|
||||
district_id: 0
|
||||
})
|
||||
|
||||
const latLngChange = (lat: number, lng: number) => {
|
||||
latLngToAddress({ mapKey, lat, lng }).then(({ message, result }) => {
|
||||
if (message == 'query ok' || message == 'Success') {
|
||||
formData.latitude = result.location.lat
|
||||
formData.longitude = result.location.lng
|
||||
formData.address = result.formatted_addresses && result.formatted_addresses.recommend ? result.formatted_addresses.recommend : ''
|
||||
|
||||
getAreaByCode(result.ad_info.adcode).then(({ data }) => {
|
||||
storeArea.province_id = data.province ? data.province.id : 0
|
||||
storeArea.city_id = data.city ? data.city.id : (data.district ? data.district.id : 0)
|
||||
storeArea.district_id = data.city ? (data.district ? data.district.id : 0) : 0
|
||||
})
|
||||
} else {
|
||||
console.error(message, result)
|
||||
}
|
||||
}).catch(() => {
|
||||
// console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取市
|
||||
*/
|
||||
watch(() => formData.province_id, (nval) => {
|
||||
if (nval) {
|
||||
getAreaListByPid(formData.province_id).then(res => {
|
||||
areaList.city = res.data
|
||||
|
||||
const cityId = formData.city_id
|
||||
if (cityId) {
|
||||
let isExist = false
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
if (cityId == res.data[i].id) {
|
||||
isExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (isExist) {
|
||||
formData.city_id = cityId
|
||||
return
|
||||
}
|
||||
}
|
||||
formData.city_id = 0
|
||||
areaChange()
|
||||
})
|
||||
} else {
|
||||
formData.city_id = 0
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取区
|
||||
*/
|
||||
watch(() => formData.city_id, (nval) => {
|
||||
if (nval) {
|
||||
getAreaListByPid(formData.city_id).then(res => {
|
||||
areaList.district = res.data
|
||||
|
||||
const districtId = formData.district_id
|
||||
if (districtId) {
|
||||
let isExist = false
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
if (districtId == res.data[i].id) {
|
||||
isExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (isExist) {
|
||||
formData.district_id = districtId
|
||||
return
|
||||
}
|
||||
}
|
||||
areaChange()
|
||||
formData.district_id = 0
|
||||
})
|
||||
} else {
|
||||
formData.district_id = 0
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => formData.district_id, (nval) => {
|
||||
if (nval) {
|
||||
areaChange()
|
||||
}
|
||||
})
|
||||
|
||||
const handleFlash = () => {
|
||||
flash.value = true
|
||||
}
|
||||
|
||||
const areaChange = debounce(() => {
|
||||
setTimeout(() => {
|
||||
const province = areaList.province.map((item) => { if (item.id == formData.province_id) { return item.name } })
|
||||
const city = areaList.city.map((item) => { if (item.id == formData.city_id) { return item.name } })
|
||||
const district = areaList.district.map((item) => { if (item.id == formData.district_id) { return item.name } })
|
||||
|
||||
const address = [
|
||||
formData.province_id ? (provinceRef.value.selectedLabel || province) : '',
|
||||
formData.city_id ? (cityRef.value.selectedLabel || city) : '',
|
||||
formData.district_id ? (districtRef.value.selectedLabel || district) : '',
|
||||
formData.address
|
||||
]
|
||||
addressToLatLng({ mapKey, address: address.join('') }).then(({ message, result }) => {
|
||||
if (message == 'Success' || message == 'query ok') {
|
||||
const latLng = new (window as any).TMap.LatLng(result.location.lat, result.location.lng)
|
||||
map.setCenter(latLng)
|
||||
|
||||
marker.updateGeometries({
|
||||
id: 'center',
|
||||
position: latLng
|
||||
})
|
||||
formData.latitude = result.location.lat
|
||||
formData.longitude = result.location.lng
|
||||
if (formData.pick_up_type.indexOf('local_delivery') != -1 && flash.value) {
|
||||
formData.area.forEach(item => {
|
||||
// 先删除旧的图形
|
||||
deleteGeometry(item.area_json.key)
|
||||
// 重新创建图形
|
||||
item.area_json.center = {
|
||||
lat: result.location.lat,
|
||||
lng: result.location.lng
|
||||
}
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.error(message, result)
|
||||
}
|
||||
})
|
||||
}, 500)
|
||||
}, 500)
|
||||
|
||||
/**
|
||||
* 地图点选获取市
|
||||
*/
|
||||
watch(() => storeArea.province_id, (nval) => {
|
||||
if (nval) {
|
||||
getAreaListByPid(storeArea.province_id).then(res => {
|
||||
areaList.city = res.data
|
||||
formData.province_id = storeArea.province_id
|
||||
formData.city_id = storeArea.city_id
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 地图点选获取区
|
||||
*/
|
||||
watch(() => storeArea.city_id, (nval) => {
|
||||
if (nval) {
|
||||
getAreaListByPid(storeArea.city_id).then(res => {
|
||||
areaList.district = res.data
|
||||
formData.city_id = storeArea.city_id
|
||||
formData.district_id = storeArea.district_id
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 地图点选获取区
|
||||
*/
|
||||
watch(() => storeArea.district_id, (nval) => {
|
||||
if (nval) {
|
||||
formData.district_id = storeArea.district_id
|
||||
}
|
||||
})
|
||||
|
||||
// 正则表达式
|
||||
const regExp = {
|
||||
required: /[\S]+/,
|
||||
number: /^\d{0,10}$/,
|
||||
digit: /^\d{0,10}(.?\d{0,2})$/,
|
||||
special: /^\d{0,10}(.?\d{0,3})$/
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = reactive({
|
||||
store_name: [
|
||||
{ required: true, message: t('storeNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
contact_name: [
|
||||
{ required: true, message: t('contactNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
store_mobile: [
|
||||
{ required: true, message: t('storeMobilePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
trade_time: [
|
||||
{ required: true, message: t('tradeTimePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
time_week: [
|
||||
{ required: true, message: t('timeWeekRequire'), trigger: 'change' }
|
||||
],
|
||||
distance: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (initData.fee_type == 'distance') {
|
||||
if (Test.require(formData.base_dist)) {
|
||||
callback(new Error(t('baseDistRequire')))
|
||||
} else if (Number(formData.base_dist) <= 0) {
|
||||
callback(new Error(t('起始公里数不能小于等于0')))
|
||||
}
|
||||
if (Test.require(formData.base_price)) {
|
||||
callback(new Error(t('basePriceRequire')))
|
||||
}
|
||||
if (Test.require(formData.grad_dist)) {
|
||||
callback(new Error(t('gradDistRequire')))
|
||||
} else if (Number(formData.grad_dist) <= 0) {
|
||||
callback(new Error(t('超出公里数不能小于等于0')))
|
||||
}
|
||||
if (Test.require(formData.grad_price)) {
|
||||
callback(new Error(t('gradPriceRequire')))
|
||||
}
|
||||
if (Number(formData.weight_start) <= 0) { // 重量不能小于等于0
|
||||
callback(new Error(t('商品重量不能小于等于0')))
|
||||
}
|
||||
if (Number(formData.weight_unit) <= 0) { // 超出重量不能小于等于0
|
||||
callback(new Error(t('商品超出重量不能小于等于0')))
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
weight: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (initData.fee_type == 'distance') {
|
||||
if (Number(formData.weight_start) <= 0) { // 重量不能小于等于0
|
||||
callback(new Error(t('商品重量不能小于等于0')))
|
||||
}
|
||||
if (Number(formData.weight_unit) <= 0) { // 超出重量不能小于等于0
|
||||
callback(new Error(t('商品超出重量不能小于等于0')))
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
area_name: [{ required: true, message: t('areaNameRequire'), trigger: 'blur' }],
|
||||
start_price: [
|
||||
{ required: true, message: t('startPriceRequire'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (parseInt(value) < 0) {
|
||||
callback(new Error(t('startPriceMin')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
delivery_price: [
|
||||
{ required: initData.fee_type == 'region', message: t('deliveryPriceRequire'), trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (parseInt(value) < 0) {
|
||||
callback(new Error(t('deliveryPriceMin')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
area: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (Test.empty(formData.area)) {
|
||||
callback(new Error(t('areaPlaceholder')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
trade_time_json: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!value || value.length === 0) {
|
||||
return callback(new Error(t('tradeTimePlaceholderTwo')))
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const timeRange = value[i]
|
||||
if (!timeRange.start_time || !timeRange.end_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderTwo')))
|
||||
}
|
||||
// 结束时间不能小于或等于开始时间
|
||||
if (timeRange.end_time <= timeRange.start_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderFour')))
|
||||
}
|
||||
// 确保后一个时间段的开始时间不能小于前一个时间段的结束时间
|
||||
if (i > 0 && value[i].start_time < value[i - 1].end_time) {
|
||||
return callback(new Error(t('tradeTimePlaceholderFive')))
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'change',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
time_interval: [
|
||||
{ required: true, message: t('tradeTimePlaceholderThree'), trigger: 'change' }
|
||||
],
|
||||
|
||||
address_area: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!formData.province_id) {
|
||||
callback(new Error(t('provincePlaceholder')))
|
||||
}
|
||||
if (!formData.city_id) {
|
||||
callback(new Error(t('cityPlaceholder')))
|
||||
}
|
||||
if (areaList.district.length && !formData.district_id) {
|
||||
callback(new Error(t('districtPlaceholder')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: t('addressPlaceholder'), trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
|
||||
// 添加时间段
|
||||
const addTimeRange = () => {
|
||||
formData.trade_time_json.push({ start_time: '', end_time: '' })
|
||||
}
|
||||
|
||||
// 删除时间段
|
||||
const removeTimeRange = (index: number) => {
|
||||
formData.trade_time_json.splice(index, 1)
|
||||
}
|
||||
|
||||
const timeTransition = (time:any) => {
|
||||
const arr = time.split(':')
|
||||
const num = arr[0] * 60 * 60 + arr[1] * 60
|
||||
return num
|
||||
}
|
||||
|
||||
const timestampTransition = (timeStamp:any) => {
|
||||
let hour = Math.floor(timeStamp / (60 * 60))
|
||||
let minute = Math.floor(timeStamp / 60) - (hour * 60)
|
||||
hour = hour < 10 ? ('0' + hour) : hour
|
||||
minute = minute < 10 ? ('0' + minute) : minute
|
||||
|
||||
return hour + ':' + minute
|
||||
}
|
||||
|
||||
const currArea = ref<number>(0)
|
||||
|
||||
/**
|
||||
* 添加配送区域
|
||||
*/
|
||||
const addArea = () => {
|
||||
formData.area.push({
|
||||
area_name: '',
|
||||
area_type: 'radius',
|
||||
start_price: 0,
|
||||
delivery_price: 0,
|
||||
area_json: {
|
||||
key: guid()
|
||||
}
|
||||
})
|
||||
const index = formData.area.length - 1
|
||||
createCircle(map, formData.area[index].area_json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配送区域
|
||||
*/
|
||||
const deleteArea = (index: number) => {
|
||||
const data = formData.area[index]
|
||||
deleteGeometry(data.area_json.key)
|
||||
formData.area.splice(index, 1)
|
||||
}
|
||||
|
||||
const selectArea = (index: number) => {
|
||||
currArea.value = index
|
||||
const data = formData.area[index]
|
||||
selectGeometry(data.area_json.key)
|
||||
}
|
||||
|
||||
const areaTypeChange = (index: number) => {
|
||||
const data = formData.area[index]
|
||||
deleteGeometry(data.area_json.key)
|
||||
data.area_type == 'radius' ? createCircle(map, data.area_json) : createPolygon(map, data.area_json)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
map.destroy()
|
||||
})
|
||||
|
||||
// 当配送类型发生改变时
|
||||
const changePickUpType = (val: any) => {
|
||||
if (val.indexOf('local_delivery') == -1) {
|
||||
formData.area.forEach((item: any) => {
|
||||
deleteGeometry(item.area_json.key)
|
||||
})
|
||||
} else {
|
||||
formData.area.forEach((item: any) => {
|
||||
deleteGeometry(item.area_json.key)
|
||||
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
await formEl.validate(async (valid) => {
|
||||
let areaValidate = true
|
||||
|
||||
for (let i = 0; i < areaFromRef.value?.length; i++) {
|
||||
const ref = areaFromRef.value[i]
|
||||
await ref.validate(async (valid) => {
|
||||
areaValidate = valid
|
||||
})
|
||||
if (!areaValidate) break
|
||||
}
|
||||
if (!areaValidate) return
|
||||
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
await formEl.validate(async (valid) => {
|
||||
const param: any = deepClone(formData)
|
||||
formData.province_name = formData.province_id ? provinceRef.value.selectedLabel : ''
|
||||
formData.city_name = formData.city_id ? cityRef.value.selectedLabel : ''
|
||||
formData.district_name = formData.district_id ? districtRef.value.selectedLabel : ''
|
||||
const address = [
|
||||
param.province_id ? provinceRef.value.selectedLabel : '',
|
||||
param.city_id ? cityRef.value.selectedLabel : '',
|
||||
param.district_id ? districtRef.value.selectedLabel : '',
|
||||
param.address
|
||||
]
|
||||
param.full_address = address.join('')
|
||||
param.trade_time_json = param.trade_time_json.map((range: any) => ({
|
||||
start_time: range.start_time ? timeTransition(range.start_time) : null,
|
||||
end_time: range.end_time ? timeTransition(range.end_time) : null
|
||||
}))
|
||||
const api = formData.store_id ? editDeliveryStore : addDeliveryStore
|
||||
api(param).then(() => {
|
||||
loading.value = false
|
||||
router.push({ path: '/shop/delivery_store' })
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const back = () => {
|
||||
router.push({ path: '/shop/delivery_store' })
|
||||
}
|
||||
|
||||
// 新窗口打开
|
||||
const newWindow = () => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/setting'
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.region-list {
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
z-index: 3;
|
||||
|
||||
.region-item {
|
||||
border: 1px solid transparent;
|
||||
border-bottom-color: var(--el-border-color-lighter);
|
||||
}
|
||||
}
|
||||
#container :deep(div){
|
||||
z-index: 2 !important;
|
||||
}
|
||||
</style>
|
||||
160
niucloud/addon/shop/admin/views/delivery_store/list.vue
Normal file
160
niucloud/addon/shop/admin/views/delivery_store/list.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="right">{{ pageName }}</span>
|
||||
<el-button type="primary" @click="addEvent">{{ t('添加提货点') }}</el-button>
|
||||
</div>
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="deliveryStoreTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('提货点名称')" prop="store_name">
|
||||
<el-input v-model.trim="deliveryStoreTable.searchParam.store_name" :placeholder="t('请输入提货点名称')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('提货类型')" prop="pick_up_type">
|
||||
<el-select v-model="deliveryStoreTable.searchParam.pick_up_type" :placeholder="t('请选择提货类型')" clearable>
|
||||
<el-option v-for="(item,key) in pickUpType" :key="key" :label="item" :value="key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadDeliveryStoreList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="deliveryStoreTable.data" size="large" v-loading="deliveryStoreTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !deliveryStoreTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column :label="t('提货点编号')" min-width="200" :show-overflow-tooltip="true">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" v-if="row.is_system">{{ t('系统') }}</el-tag>
|
||||
<span class="ml-[8px]">{{row.store_no}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_name" :label="t('提货点名称')" min-width="120" />
|
||||
<el-table-column prop="contact_name" :label="t('联系人姓名')" min-width="80" />
|
||||
<el-table-column prop="store_mobile" :label="t('联系人电话')" min-width="80" />
|
||||
<el-table-column prop="full_address" :label="t('提货地址')" min-width="120" />
|
||||
<el-table-column prop="trade_time" :label="t('营业时间')" min-width="120" />
|
||||
<el-table-column prop="pick_up_type_name" :label="t('提货类型')" min-width="120" />
|
||||
<el-table-column :label="t('开启状态')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag class="cursor-pointer" :type="row.status ? 'success' : 'danger'" @click="updateStatus(row)">{{ row.status ? '开启' : '关闭' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="120" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="deliverySetEvent(row)">配送服务商设置</el-button>
|
||||
<el-button type="primary" link @click="editEvent(row)">编辑</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row)" v-if="row.is_system == 0">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="deliveryStoreTable.page" v-model:page-size="deliveryStoreTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="deliveryStoreTable.total"
|
||||
@size-change="loadDeliveryStoreList()" @current-change="loadDeliveryStoreList" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { getDeliveryStoreList, getStorePickUpType, deleteDeliveryStore, editDeliveryStoreStatus } from '@/addon/shop/api/delivery'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const deliveryStoreTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
store_name: '',
|
||||
pick_up_type: '',
|
||||
create_time: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
const pickUpType = ref([])
|
||||
|
||||
const getStorePickUpTypeFn = () => {
|
||||
getStorePickUpType().then(res => {
|
||||
pickUpType.value = res.data
|
||||
})
|
||||
}
|
||||
getStorePickUpTypeFn()
|
||||
/**
|
||||
* 获取门店自提列表
|
||||
*/
|
||||
const loadDeliveryStoreList = (page: number = 1) => {
|
||||
deliveryStoreTable.loading = true
|
||||
deliveryStoreTable.page = page
|
||||
|
||||
getDeliveryStoreList({
|
||||
page: deliveryStoreTable.page,
|
||||
limit: deliveryStoreTable.limit,
|
||||
...deliveryStoreTable.searchParam
|
||||
}).then((res: any) => {
|
||||
deliveryStoreTable.loading = false
|
||||
deliveryStoreTable.data = res.data.data
|
||||
deliveryStoreTable.total = res.data.total
|
||||
}).catch(() => {
|
||||
deliveryStoreTable.loading = false
|
||||
})
|
||||
}
|
||||
loadDeliveryStoreList()
|
||||
|
||||
/**
|
||||
* 添加门店
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/delivery_store/edit')
|
||||
}
|
||||
// 配送设置
|
||||
const deliverySetEvent = (data: any) => {
|
||||
router.push('/shop/delivery_store/delivery_set?id=' + data.store_id)
|
||||
}
|
||||
// 编辑
|
||||
const editEvent = (row: any) => {
|
||||
router.push({ path: '/shop/delivery_store/edit', query: { store_id: row.store_id } })
|
||||
}
|
||||
// 删除
|
||||
const deleteEvent = (row: any) => {
|
||||
ElMessageBox.confirm(t('确定要删除该门店吗'), t('warning'), {
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteDeliveryStore(row.store_id).then(() => {
|
||||
loadDeliveryStoreList()
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
// 更新状态
|
||||
const updateStatus = (row: any) => {
|
||||
row.status = row.status ? 0 : 1
|
||||
editDeliveryStoreStatus({
|
||||
store_id: row.store_id,
|
||||
status: row.status
|
||||
}).then(() => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadDeliveryStoreList()
|
||||
}
|
||||
</script>
|
||||
@ -124,6 +124,18 @@
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t("goodsShowContent") }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
|
||||
@ -32,6 +32,17 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t("manyGoodsListCategorySet") }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
|
||||
@ -64,6 +64,17 @@
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
|
||||
@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('标题内容') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('标题风格')">
|
||||
<el-radio-group v-model="diyStore.editComponent.titleStyle.way">
|
||||
<el-radio :value="'text'">{{ t('文字') }}</el-radio>
|
||||
<el-radio :value="'img'">{{ t('图片') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('标题')" v-show="diyStore.editComponent.titleStyle.way == 'text'">
|
||||
<el-input v-model.trim="diyStore.editComponent.titleStyle.text" :placeholder="t('请输入标题')" clearable maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('image')" v-show="diyStore.editComponent.titleStyle.way == 'img'">
|
||||
<upload-image v-model="diyStore.editComponent.titleStyle.imgUrl" :limit="1" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('link')">
|
||||
<diy-link v-model="diyStore.editComponent.titleStyle.link" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('副标题内容') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('副标题')">
|
||||
<el-input v-model.trim="diyStore.editComponent.subTitleStyle.text" :placeholder="t('请输入副标题')" clearable maxlength="10" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('按钮内容') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('按钮名称')">
|
||||
<el-input v-model.trim="diyStore.editComponent.btnStyle.text" :placeholder="t('请输入按钮名称')" clearable maxlength="4" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('link')">
|
||||
<diy-link v-model="diyStore.editComponent.btnStyle.link" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t("selectSource") }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('商品标签')">
|
||||
<el-input v-model.trim="diyStore.editComponent.goodsStyle.labelText" :placeholder="t('请输入名称')" clearable maxlength="4" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('选择商品')">
|
||||
<el-radio-group v-model="diyStore.editComponent.goodsStyle.source" :title="t('选择商品')">
|
||||
<el-radio label="all">{{ t('全部') }}</el-radio>
|
||||
<el-radio label="custom">{{ t('手动选择') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNum')" v-if="diyStore.editComponent.goodsStyle.source == 'all'">
|
||||
<el-slider class="goods-list-slider" show-input v-model="diyStore.editComponent.goodsStyle.num" :min="1" max="20" size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('customGoods')" v-if="diyStore.editComponent.goodsStyle.source == 'custom'">
|
||||
<goods-select-popup ref="goodsSelectPopupRef" v-model="diyStore.editComponent.goodsStyle.goodsIds" :min="1" :max="99" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.editComponent.titleStyle.way == 'text'">
|
||||
<h3 class="mb-[10px]">{{ t('标题样式') }}</h3>
|
||||
<el-form label-width="100px" class="px-[10px]">
|
||||
<el-form-item :label="t('textFontSize')">
|
||||
<el-slider v-model="diyStore.editComponent.titleStyle.fontSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="12" :max="20" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textFontWeight')">
|
||||
<el-radio-group v-model="diyStore.editComponent.titleStyle.fontWeight">
|
||||
<el-radio :value="'normal'">{{ t('fontWeightNormal') }}</el-radio>
|
||||
<el-radio :value="'bold'">{{ t('fontWeightBold') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.titleStyle.textColor" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('副标题样式') }}</h3>
|
||||
<el-form label-width="100px" class="px-[10px]">
|
||||
<el-form-item :label="t('textFontSize')">
|
||||
<el-slider v-model="diyStore.editComponent.subTitleStyle.fontSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="12" :max="30" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.subTitleStyle.textColor" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('背景色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.subTitleStyle.bgColor" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('标题圆角')">
|
||||
<el-slider v-model="diyStore.editComponent.subTitleStyle.rounded" show-input size="small" class="ml-[10px] diy-nav-slider" :min="0" :max="30" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('按钮样式') }}</h3>
|
||||
<el-form label-width="100px" class="px-[10px]">
|
||||
<el-form-item :label="t('文字大小')">
|
||||
<el-slider v-model="diyStore.editComponent.btnStyle.fontSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="10" :max="15" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('文字颜色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.btnStyle.textColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('背景色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.btnStyle.startBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]" />
|
||||
<el-color-picker v-model="diyStore.editComponent.btnStyle.endBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('渐变方式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.btnStyle.gradientType">
|
||||
<el-radio :value="'linear'">{{ t('线性渐变') }}</el-radio>
|
||||
<el-radio :value="'radial'">{{ t('径向渐变') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('商品样式') }}</h3>
|
||||
<el-form label-width="100px" class="px-[10px]">
|
||||
<el-form-item :label="t('标签大小')">
|
||||
<el-slider v-model="diyStore.editComponent.goodsStyle.labelSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="10" :max="15" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('标签文字色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsStyle.labelColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('标签背景色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsStyle.labelBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('背景色')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsStyle.bgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('商品圆角')">
|
||||
<el-slider v-model="diyStore.editComponent.goodsStyle.rounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('图片圆角')">
|
||||
<el-slider v-model="diyStore.editComponent.goodsStyle.imgRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 组件样式 -->
|
||||
<slot name="style"></slot>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import goodsSelectPopup from '@/addon/shop/views/goods/components/goods-select-popup.vue'
|
||||
|
||||
const diyStore: any = useDiyStore()
|
||||
diyStore.editComponent.ignore = [] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
|
||||
if (diyStore.value[index].goodsStyle.source == 'custom' && !diyStore.value[index].goodsStyle.goodsIds.length) {
|
||||
res.code = false
|
||||
res.message = t('请选择商品')
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.goods-list-slider {
|
||||
.el-slider__input {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -59,6 +59,17 @@
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
|
||||
@ -15,6 +15,17 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<el-form label-width="120px" class="px-[10px]">
|
||||
|
||||
@ -32,6 +32,17 @@
|
||||
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
|
||||
|
||||
@ -45,6 +45,17 @@
|
||||
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('图片展示模式') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('模式')">
|
||||
<el-radio-group v-model="diyStore.editComponent.mode">
|
||||
<el-radio label="aspectFill">{{ t('短边完整,长边裁剪') }}</el-radio>
|
||||
<el-radio label="aspectFit">{{ t('长边适配,等比缩放') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t("selectSource") }}</h3>
|
||||
|
||||
@ -479,71 +479,7 @@ const previewEvent = (data: any) => {
|
||||
}
|
||||
|
||||
const activeclick = (data: any) => {
|
||||
if (data.list[0].join_type == 'impulse_buy') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop_impulse_buy/list',
|
||||
query: {
|
||||
active_id: data.list[0].join_id
|
||||
}
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'discount') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop/marketing/discount/list',
|
||||
query: {
|
||||
active_id: data.list[0].join_id
|
||||
}
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'gift_card') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop_giftcard/giftcard/list',
|
||||
query: {
|
||||
active_id: data.list[0].join_id
|
||||
}
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'active_exchange') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop/marketing/exchange/goods_list',
|
||||
query: {
|
||||
active_id: data.list[0].join_id
|
||||
}
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'active_newcomer_discount') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop/marketing/newcomer/config'
|
||||
// query: {
|
||||
// active_id: data.list[0].join_id
|
||||
// }
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'manjian') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/shop/marketing/manjian/list',
|
||||
query: {
|
||||
active_id: data.list[0].join_id
|
||||
}
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
} else if (data.list[0].join_type == 'seckill') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/seckill/active/list',
|
||||
// query: {
|
||||
// active_id: data.list[0].join_id
|
||||
// }
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
}else if (data.list[0].join_type == 'pintuan') {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/pintuan/active/list',
|
||||
// query: {
|
||||
// active_id: data.list[0].join_id
|
||||
// }
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
}
|
||||
window.open(data.jump_url, '_blank')
|
||||
}
|
||||
|
||||
// 监听排序
|
||||
@ -783,7 +719,7 @@ loadGoodsList(getTablePageStorage(goodsTable.searchParam).page)
|
||||
* 添加商品
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/goods/real_edit')
|
||||
router.push('/shop/goods/real_add')
|
||||
// let url = router.resolve({
|
||||
// path: '/shop/goods/real_edit',
|
||||
// });
|
||||
@ -865,6 +801,10 @@ const copyEvent = (data: any) => {
|
||||
loadGoodsList(getTablePageStorage(goodsTable.searchParam).page)
|
||||
}
|
||||
repeat.value = false
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '商品复制成功,可以在仓库中商品查询'
|
||||
})
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
})
|
||||
|
||||
@ -3,7 +3,7 @@ import { t } from '@/lang'
|
||||
import { TabsPaneContext, ElMessage } from 'element-plus'
|
||||
import Sortable from 'sortablejs'
|
||||
import { range, cloneDeep } from 'lodash-es'
|
||||
import { debounce, deepClone } from '@/utils/common'
|
||||
import { debounce, deepClone, getImageDimensions } from '@/utils/common'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import Test from '@/utils/test'
|
||||
import {
|
||||
@ -125,7 +125,9 @@ export function useGoodsEdit(params: any = {}) {
|
||||
|
||||
// 切换商品类型
|
||||
const changeGoodsType = (data: any) => {
|
||||
router.push(data.path)
|
||||
// 添加商品是切换类型不应该是edit
|
||||
let url = '/shop/goods/'+data.type + '_add'
|
||||
router.push(url)
|
||||
}
|
||||
|
||||
// 商品类型
|
||||
@ -1358,13 +1360,18 @@ export function useGoodsEdit(params: any = {}) {
|
||||
|
||||
// 保存数据
|
||||
const save = (callback: any = null) => {
|
||||
verify(() => {
|
||||
verify(async() => {
|
||||
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
const api = formData.goods_id ? editApi : addApi
|
||||
const data = cloneDeep(formData)
|
||||
const coverImage = data.goods_image.split(',')[0]
|
||||
|
||||
const info = await getImageDimensions(coverImage)
|
||||
data.goods_image_width = info ? info.width : 800
|
||||
data.goods_image_height = info ? info.height : 800
|
||||
|
||||
if (data.spec_type == 'multi') {
|
||||
data.stock = 0
|
||||
|
||||
@ -199,6 +199,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ElMessage, ElNotification } from 'element-plus'
|
||||
import {
|
||||
getShopCountList,
|
||||
getShopTodayCountList,
|
||||
@ -207,6 +208,7 @@ import {
|
||||
getShopOrderStat,
|
||||
getShopGoodsStat
|
||||
} from '@/addon/shop/api/shop'
|
||||
import { checkJobStatus } from '@/app/api/sys'
|
||||
import * as echarts from 'echarts'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
@ -370,6 +372,27 @@ const nowTime = () => {
|
||||
time.value = year + '-' + month + '-' + day + ' ' + hh + ':' + mm + ':' + ss
|
||||
}
|
||||
nowTime()
|
||||
|
||||
/**
|
||||
* 校验消息队列
|
||||
*/
|
||||
let notification = null
|
||||
const checkJob = () => {
|
||||
checkJobStatus().then(res => {
|
||||
if (!res.data) {
|
||||
notification = ElNotification({
|
||||
title: '温馨提示',
|
||||
dangerouslyUseHTMLString: true,
|
||||
duration: 0,
|
||||
position: 'bottom-right',
|
||||
message: '您的【队列】运行异常,会导致商城订单相关任务无法正常使用,请尽快启动队列<br><a class="text-[var(--el-color-primary)]" href="https://doc.press.niucloud.com/php/saas-framework/use/other/scheduled-task-config.html" target="_blank">>>> 点击查看处理方法 <<<</a>',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
checkJob()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@ -30,16 +30,13 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="有效期" min-width="210">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.receive_type == 1">
|
||||
<span v-if="row.valid_type == 1"> 领取之日起{{ row.length || '' }} 天内有效</span>
|
||||
<span v-else> 使用截止时间至{{ row.valid_end_time || ''}} </span>
|
||||
</template>
|
||||
<span v-else>--</span>
|
||||
<span v-if="row.valid_type == 1"> 领取之日起{{ row.length || '' }} 天内有效</span>
|
||||
<span v-else> 使用截止时间至{{ row.valid_end_time || ''}} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="赠券数" min-width="130">
|
||||
<template #default="{ row }">
|
||||
<el-input-number
|
||||
<el-input-number v-if="row.limit_count"
|
||||
v-model="formData.coupon_list['id_' + row.id]"
|
||||
:min="1"
|
||||
:precision="0"
|
||||
@ -47,6 +44,14 @@
|
||||
controls-position="right"
|
||||
class="!w-[100px]"
|
||||
/>
|
||||
<el-input-number v-else
|
||||
v-model="formData.coupon_list['id_' + row.id]"
|
||||
:min="1"
|
||||
:max="999999"
|
||||
:precision="0"
|
||||
controls-position="right"
|
||||
class="!w-[100px]"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" fixed="right">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" :title="showType == 'add' ? t('delivery') : t('修改物流信息')" :width="showType =='add' ?'700px' :'1000px'" class="diy-dialog-wrap" :destroy-on-close="true" :close-on-click-modal="false">
|
||||
<el-dialog v-model="showDialog" :title="showType == 'add' ? t('delivery') : t('修改物流信息')" :width="showType =='add' ? '700px' :'1000px'" class="diy-dialog-wrap" :destroy-on-close="true" :close-on-click-modal="false" @close="handleClose">
|
||||
<div v-loading="loading">
|
||||
|
||||
<el-alert type="warning" :closable="false" class="!mb-[10px]" v-if="isTradeManaged">
|
||||
@ -35,15 +35,67 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="formData.delivery_type == 'local_delivery'">
|
||||
<el-form-item :label="t('deliveryWay')">
|
||||
<el-radio-group v-model="formData.delivery_way" @change="deliveryWayChange">
|
||||
<el-radio label="store_delivery">{{ t('storeDeliveryWay') }}</el-radio>
|
||||
<el-radio label="third_party_delivery">{{ t('thirdPartyDeliveryWay') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div v-if="formData.delivery_way == 'store_delivery'">
|
||||
<el-form-item :label="t('deliveryStore')" prop="store_id">
|
||||
<el-select v-model="formData.store_id" :placeholder="t('deliveryStorePlaceholder')" clearable class="input-width">
|
||||
<el-option v-for="(item) in deliveryStoreData" :key="item.store_id" :label="item.store_name" :value="item.store_id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliverName')" prop="local_deliver_id">
|
||||
<el-select v-model="formData.local_deliver_id" :placeholder="t('deliverNamePlaceholder')" clearable class="input-width" @change="deliverNameChange">
|
||||
<el-option v-for="(item) in deliverData" :key="item.deliver_id" :label="item.deliver_name" :value="item.deliver_id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliverMobile')" prop="deliver_mobile">
|
||||
<el-input v-model.trim="formData.deliver_mobile" clearable :disabled="true" :placeholder="t('deliverMobilePlaceholder')" class="input-width" maxlength="30" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="formData.delivery_way == 'third_party_delivery'">
|
||||
<el-form-item :label="t('deliveryStore')" prop="store_id">
|
||||
<div>
|
||||
<el-select v-model="formData.store_id" :placeholder="t('deliveryStorePlaceholder')" clearable class="input-width" @change="deliveryStoreChange">
|
||||
<el-option v-for="(item) in deliveryStoreData" :key="item.store_id" :label="item.store_name" :value="item.store_id" />
|
||||
</el-select>
|
||||
<span class="ml-[10px] cursor-pointer text-primary" @click="toAddress" v-if="curThirdDelivery?.open_status == 2">去开通</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('thirdDeliveryName')" prop="local_delivery_type">
|
||||
<div class="flex items-center">
|
||||
<el-select v-model="formData.local_delivery_type" :placeholder="t('thirdDeliveryNamePlaceholder')" clearable class="input-width" @change="thirdDeliveryChange">
|
||||
<el-option v-for="(item,index) in thirdDeliveryData" :key="index" :label="item.name" :value="item.key" />
|
||||
</el-select>
|
||||
<div class="ml-[10px]">
|
||||
<span class="cursor-pointer text-primary mr-[10px]" @click="getInUseLocalDeliveryListFn(formData.store_id)">{{ t('refresh') }}</span>
|
||||
<span class="cursor-pointer text-primary" @click="toThirdDelivery">{{ t('去配置') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsWeight')" prop="goods_weight">
|
||||
<el-input v-model.trim="formData.goods_weight" clearable placeholder="0.000" class="input-width" maxlength="6" @blur="thirdDeliveryChange">
|
||||
<template #append>kg</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('配送费用')" >
|
||||
<div class="input-width">{{ deliveryFee }}元</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</el-form>
|
||||
<el-table :data="goodsDataArr" size="large" @selection-change="handleSelectionChange" max-height="400px">
|
||||
<el-table :data="goodsDataArr" size="large" @selection-change="handleSelectionChange" ref="tableRef" max-height="400px">
|
||||
<el-table-column type="selection" width="55" :selectable="selectable" />
|
||||
<el-table-column prop="goods_name" :label="t('goodsName')" min-width="200" >
|
||||
<template #default="{ row }">
|
||||
<div class="flex cursor-pointer">
|
||||
<div class="flex items-center min-w-[50px] mr-[10px]">
|
||||
<img class="w-[50px] h-[50px]" v-if="row.goods_image" :src="img(row.goods_image)" alt="">
|
||||
<img class="w-[50px] h-[50px]" v-else src="" alt="">
|
||||
<img class="w-[50px] h-[50px]" v-else src="" alt="">
|
||||
</div>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="multi-hidden text-[14px]">{{row.goods_name}}</span>
|
||||
@ -56,12 +108,22 @@
|
||||
<el-table-column prop="num" :label="t('num')" min-width="80" />
|
||||
<el-table-column prop="status_name" :label="t('refundStatusName')" min-width="80" />
|
||||
<el-table-column prop="delivery_status_name" :label="t('deliveryStatusName')" min-width="80" />
|
||||
<el-table-column prop="express_company_name" :label="t('物流公司')" min-width="80" v-if="showType == 'edit'">
|
||||
<el-table-column :label="t('deliveryPlatform')" min-width="80" v-if="showType == 'edit' && formData.delivery_type == 'local_delivery'">
|
||||
<template #default="{ row }">
|
||||
<span>{{row.delivery_info?.delivery_service_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="local_delivery_status_name" :label="t('deliveryStatus')" min-width="80" v-if="showType == 'edit' && formData.delivery_type == 'local_delivery'">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.delivery_info?.local_delivery_status_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="express_company_name" :label="t('物流公司')" min-width="80" v-if="showType == 'edit' && formData.delivery_type == 'express'">
|
||||
<template #default="{ row }">
|
||||
<span class="text-[#999]">{{ row.delivery_info?.express_company_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="express_number" :label="t('物流单号')" min-width="80" v-if="showType == 'edit'">
|
||||
<el-table-column prop="express_number" :label="t('物流单号')" min-width="80" v-if="showType == 'edit' && formData.delivery_type == 'express'">
|
||||
<template #default="{ row }">
|
||||
<span class="text-[#999]">{{ row.delivery_info?.express_number }}</span>
|
||||
</template>
|
||||
@ -70,7 +132,7 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button @click="handleClose">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
@ -78,21 +140,19 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { ref, reactive, computed, nextTick } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { img } from '@/utils/common'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
import { getCompanyList } from '@/addon/shop/api/delivery'
|
||||
import { getOrderDeliveryType, orderDelivery } from '@/addon/shop/api/order'
|
||||
import { getCompanyList, getShopDeliverList, getInUseLocalDeliveryList, getDeliveryStoreListAll } from '@/addon/shop/api/delivery'
|
||||
import { getOrderDeliveryType, orderDelivery, getSelectOrderGoodsWeight, getDeliveryFee } from '@/addon/shop/api/order'
|
||||
import { getIsTradeManaged } from '@/app/api/weapp'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import {
|
||||
getElectronicSheetConfig,
|
||||
getElectronicSheetList,
|
||||
printElectronicSheet
|
||||
} from '@/addon/shop/api/electronic_sheet'
|
||||
import { loadCLodop,getLodop } from '@/utils/lodop'
|
||||
import { getElectronicSheetConfig, getElectronicSheetList, printElectronicSheet } from '@/addon/shop/api/electronic_sheet'
|
||||
import { loadCLodop, getLodop } from '@/utils/lodop'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
interface companyDataType{
|
||||
@ -139,6 +199,57 @@ const companyChange = (value: any) => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员
|
||||
*/
|
||||
const deliverNameChange = (value: any) => {
|
||||
if (value) {
|
||||
deliverData.value.forEach((item: any) => {
|
||||
if (item.deliver_id == value) {
|
||||
formData.deliver_mobile = item.deliver_mobile
|
||||
}
|
||||
})
|
||||
} else {
|
||||
formData.deliver_mobile = ''
|
||||
formData.local_deliver_id = ''
|
||||
}
|
||||
}
|
||||
|
||||
const deliverData = ref([])
|
||||
getShopDeliverList({}).then((res: any) => {
|
||||
deliverData.value = res.data
|
||||
})
|
||||
|
||||
/**
|
||||
* 三方配送列表
|
||||
*/
|
||||
const thirdDeliveryData = ref([])
|
||||
const getInUseLocalDeliveryListFn = (value: any) => {
|
||||
getInUseLocalDeliveryList({store_id: value}).then((res: any) => {
|
||||
thirdDeliveryData.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提货点列表
|
||||
*/
|
||||
const deliveryStoreData = ref([])
|
||||
getDeliveryStoreListAll({
|
||||
pick_up_type: 'local_delivery',
|
||||
}).then((res: any) => {
|
||||
deliveryStoreData.value = res.data
|
||||
})
|
||||
|
||||
const deliveryStoreChange = (value: any) => {
|
||||
if (formData.delivery_way == 'third_party_delivery' && value) {
|
||||
formData.local_delivery_type = ''
|
||||
deliveryFee.value = 0
|
||||
getInUseLocalDeliveryListFn(value)
|
||||
} else {
|
||||
thirdDeliveryData.value = []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
@ -147,17 +258,30 @@ const initialFormData = {
|
||||
order_id: 0,
|
||||
delivery_type: '',
|
||||
delivery_way: 'manual_write',
|
||||
local_delivery_type: 'merchant',
|
||||
goods_weight: 1,
|
||||
local_deliver_id: '',
|
||||
deliver_mobile: '',
|
||||
express_company_id: '',
|
||||
express_number: '',
|
||||
electronic_sheet_id: '',
|
||||
order_goods_ids: [],
|
||||
delivery_ids: []
|
||||
delivery_ids: [],
|
||||
store_id: ''
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 正则表达式
|
||||
const regExp: any = {
|
||||
required: /[\S]+/,
|
||||
number: /^\d{0,10}$/,
|
||||
digit: /^\d{0,10}(.?\d{0,2})$/,
|
||||
special: /^\d{0,10}(.?\d{0,3})$/
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
@ -172,6 +296,18 @@ const formRules = computed(() => {
|
||||
],
|
||||
electronic_sheet_id: [
|
||||
{ required: true, validator: electronicSheetIdPass, trigger: 'blur' }
|
||||
],
|
||||
local_deliver_id: [
|
||||
{ required: true, validator: localDeliverIdPass, trigger: 'blur' }
|
||||
],
|
||||
store_id: [
|
||||
{ required: true, validator: storeIdPass, trigger: 'blur' }
|
||||
],
|
||||
local_delivery_type: [
|
||||
{ required: true, validator: thirdDeliveryTypePass, trigger: ['blur', 'change'] }
|
||||
],
|
||||
goods_weight: [
|
||||
{ required: true, validator: goodsWeightPass, trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
})
|
||||
@ -200,8 +336,50 @@ const electronicSheetIdPass = (rule: any, value: any, callback: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const localDeliverIdPass = (rule: any, value: any, callback: any) => {
|
||||
if (formData.delivery_type == 'local_delivery' && formData.delivery_way == 'store_delivery' && value == '') {
|
||||
callback(new Error(t('deliverNamePlaceholder')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const storeIdPass = (rule: any, value: any, callback: any) => {
|
||||
if (formData.delivery_type == 'local_delivery' && value == '') {
|
||||
callback(new Error(t('deliveryStorePlaceholder')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const thirdDeliveryTypePass = (rule: any, value: any, callback: any) => {
|
||||
if (formData.delivery_type == 'local_delivery' && formData.delivery_way == 'third_party_delivery' && (value == '' || value == undefined)) {
|
||||
callback(new Error(t('thirdDeliveryNamePlaceholder')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const goodsWeightPass = (rule: any, value: any, callback: any) => {
|
||||
if (formData.delivery_type == 'local_delivery' && formData.delivery_way == 'third_party_delivery' && value == '') {
|
||||
callback(new Error(t('goodsWeightPlaceholder')))
|
||||
} else if (isNaN(value) || !regExp.special.test(value)) {
|
||||
callback(new Error(t('weightTips')))
|
||||
} else if (value <= 0) {
|
||||
callback(new Error(t('weightNotZeroTips')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const selectable = (row:any, index:number) => {
|
||||
if ((row.status == 2 || row.delivery_status != 'wait_delivery' || row.status == 3 || row.is_gift == 1 )&& (showType.value =='add' || !showType.value)) {
|
||||
if ((row.status == 2 || row.delivery_status != 'wait_delivery' || row.status == 3 || row.is_gift == 1) && (showType.value == 'add' || !showType.value)) {
|
||||
return false
|
||||
}
|
||||
if (row.delivery_info && row.delivery_info.delivery_service == 'dada' && (row.delivery_info.local_delivery_status == '-2' || row.delivery_info.local_delivery_status == '-1' || row.delivery_info.local_delivery_status == '8')) {
|
||||
return false
|
||||
}
|
||||
if (formData.delivery_type == 'local_delivery') {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -226,6 +404,20 @@ const deliveryChange = () => {
|
||||
})
|
||||
}
|
||||
goodsDataArr.value = cloneDeep(arr)
|
||||
if (formData.delivery_type && formData.delivery_type == 'express') {
|
||||
formData.delivery_way = 'manual_write'
|
||||
} else if (formData.delivery_type && formData.delivery_type == 'local_delivery') {
|
||||
formData.delivery_way = 'store_delivery'
|
||||
}
|
||||
}
|
||||
|
||||
const deliveryWayChange = () => {
|
||||
curThirdDelivery.value = {}
|
||||
if (formData.delivery_way && formData.delivery_way == 'store_delivery') {
|
||||
formData.local_delivery_type = 'merchant'
|
||||
} else {
|
||||
formData.local_delivery_type = ''
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelectionChange = (val:any) => {
|
||||
@ -233,11 +425,35 @@ const handleSelectionChange = (val:any) => {
|
||||
formData.delivery_ids = cloneDeep([])
|
||||
for (const v in val) {
|
||||
formData.order_goods_ids.push(val[v].order_goods_id)
|
||||
if(showType.value == 'edit'){
|
||||
if (showType.value == 'edit') {
|
||||
formData.delivery_ids.push(val[v].delivery_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getSelectOrderGoodsWeightFn = () => {
|
||||
getSelectOrderGoodsWeight({
|
||||
order_goods_ids: formData.order_goods_ids
|
||||
}).then((res: any) => {
|
||||
formData.goods_weight = res.data
|
||||
})
|
||||
}
|
||||
|
||||
// 计算配送费用
|
||||
const deliveryFee = ref<any>(0)
|
||||
const getDeliveryFeeFn = () => {
|
||||
getDeliveryFee(formData).then((res: any) => {
|
||||
deliveryFee.value = res.data
|
||||
})
|
||||
}
|
||||
const curThirdDelivery = ref<any>(null)
|
||||
const thirdDeliveryChange = (value: any) => {
|
||||
if (formData.delivery_way == 'third_party_delivery' && value) {
|
||||
curThirdDelivery.value = thirdDeliveryData.value?.find((item: any) => item.key == value)
|
||||
getDeliveryFeeFn()
|
||||
} else {
|
||||
deliveryFee.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
const emit = defineEmits(['complete'])
|
||||
@ -276,6 +492,7 @@ const confirm = async (formEl: FormInstance | undefined) => {
|
||||
})
|
||||
}
|
||||
const showType = ref('')
|
||||
const tableRef = ref()
|
||||
const setFormData = async (row: any = null,type:any) => {
|
||||
loading.value = true
|
||||
showType.value = type
|
||||
@ -283,6 +500,9 @@ const setFormData = async (row: any = null,type:any) => {
|
||||
formData.order_id = row.order_id
|
||||
formData.delivery_type = ''
|
||||
formData.delivery_way = 'manual_write'
|
||||
formData.local_delivery_type = 'merchant'
|
||||
formData.store_id = row.take_store_id
|
||||
formData.local_deliver_id = row.order_goods[0]?.delivery_info?.local_deliver_id
|
||||
goodsData.value = row.order_goods
|
||||
goodsDataArr.value = row.order_goods
|
||||
isHasVirtual.value = false
|
||||
@ -306,6 +526,25 @@ const setFormData = async (row: any = null,type:any) => {
|
||||
if (isHasVirtual.value) {
|
||||
Object.assign(deliveryType.value, { virtual: t('virtualDelivery') })
|
||||
}
|
||||
if (formData.delivery_type == 'local_delivery') {
|
||||
nextTick(() => {
|
||||
if (tableRef.value) {
|
||||
if (row.status == 2) {
|
||||
goodsDataArr.value.forEach((item: any, index: any) => {
|
||||
tableRef.value.toggleRowSelection(item, true)
|
||||
})
|
||||
} else if (row.status == 3) {
|
||||
goodsDataArr.value.forEach((item: any, index: any) => {
|
||||
if (item.delivery_info.local_delivery_status == '-2' || item.delivery_info.local_delivery_status == '-1' || item.delivery_info.local_delivery_status == '8') {
|
||||
tableRef.value.toggleRowSelection(item, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
getSelectOrderGoodsWeightFn()
|
||||
getInUseLocalDeliveryListFn(formData.store_id)
|
||||
})
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
@ -313,6 +552,10 @@ const setFormData = async (row: any = null,type:any) => {
|
||||
const initFormData = () => {
|
||||
formData.order_id = 0
|
||||
formData.delivery_type = ''
|
||||
formData.delivery_way = 'manual_write'
|
||||
formData.local_delivery_type = 'merchant'
|
||||
formData.store_id = ''
|
||||
formData.local_deliver_id = ''
|
||||
formData.express_company_id = ''
|
||||
formData.electronic_sheet_id = ''
|
||||
formData.express_number = ''
|
||||
@ -352,6 +595,28 @@ const printElectronicSheetFn = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
showDialog.value = false
|
||||
initFormData()
|
||||
}
|
||||
// 去开通
|
||||
const toThirdDelivery = () => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/delivery/local_delivery_service'
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
const toAddress = () => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/delivery_store/delivery_set',
|
||||
query: {
|
||||
id: formData.store_id
|
||||
}
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDialog,
|
||||
setFormData
|
||||
|
||||
@ -484,7 +484,7 @@ const deliveryRefuseEvent = () => {
|
||||
|
||||
const transferEvent = () => {
|
||||
const routeUrl = router.resolve({
|
||||
path: '/member/refund/detail',
|
||||
path: '/finance/refund/detail',
|
||||
query: { refund_no: formData.value.refund_no }
|
||||
})
|
||||
window.open(routeUrl.href, '_blank')
|
||||
|
||||
@ -153,8 +153,11 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100">
|
||||
<template #default>
|
||||
<span class="text-[14px]">{{ item.delivery_type_name }}</span>
|
||||
<template #default="{ row }">
|
||||
<div>
|
||||
<div class="text-[14px]">{{ item.delivery_type_name }}</div>
|
||||
<div class="text-[14px] cursor-pointer text-primary" @click="toDelivery(item)">{{ row.delivery_info?.local_delivery_status_name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100">
|
||||
@ -677,6 +680,16 @@ const batchDeleteFn = () => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const toDelivery = (data: any) => {
|
||||
const url = router.resolve({
|
||||
path: '/shop/delivery/local/record',
|
||||
query: {
|
||||
trade_no: data.order_no
|
||||
}
|
||||
})
|
||||
window.open(url.href)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\delivery;
|
||||
|
||||
use addon\shop\app\service\admin\delivery\DeliverService;
|
||||
use addon\shop\app\dict\order\OrderDeliveryDict;
|
||||
use addon\shop\app\service\admin\delivery\DeliveryService;
|
||||
use core\base\BaseAdminController;
|
||||
|
||||
@ -42,7 +42,7 @@ class Delivery extends BaseAdminController
|
||||
/**
|
||||
* 配送页信息
|
||||
* @description 获取配送页信息
|
||||
* @return void
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getDelivery()
|
||||
{
|
||||
@ -52,7 +52,7 @@ class Delivery extends BaseAdminController
|
||||
/**
|
||||
* 配送页信息
|
||||
* @description 获取配送页信息配置
|
||||
* @return void
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getDeliveryList()
|
||||
{
|
||||
@ -60,70 +60,11 @@ class Delivery extends BaseAdminController
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送员列表
|
||||
* @description 查看配送员列表
|
||||
* 获取配送方式
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function lists()
|
||||
public function getDeliveryType()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "deliver_name", "" ],
|
||||
[ "deliver_mobile", "" ]
|
||||
]);
|
||||
return success(( new DeliverService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员详情
|
||||
* @description 查看配送员详情
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function info(int $id)
|
||||
{
|
||||
return success(( new DeliverService() )->getInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加配送员
|
||||
* @description 添加配送员
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "deliver_name", "" ],
|
||||
[ "deliver_mobile", "" ],
|
||||
]);
|
||||
$id = ( new DeliverService() )->add($data);
|
||||
return success('ADD_SUCCESS', [ 'id' => $id ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员编辑
|
||||
* @description 编辑配送员
|
||||
* @param $id 自提门店id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "deliver_name", "" ],
|
||||
[ "deliver_mobile", "" ],
|
||||
]);
|
||||
( new DeliverService() )->edit($id, $data);
|
||||
return success('EDIT_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员删除
|
||||
* @description 删除配送员
|
||||
* @param $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function del(int $id)
|
||||
{
|
||||
( new DeliverService() )->del($id);
|
||||
return success('DELETE_SUCCESS');
|
||||
return success(OrderDeliveryDict::getType());
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +85,12 @@ class ElectronicSheet extends BaseAdminController
|
||||
[ 'exp_type', 0 ],
|
||||
[ "print_style", "" ],
|
||||
[ "is_default", 0 ],
|
||||
// [ "kd100_customer_name", "" ],
|
||||
// [ "kd100_customer_pwd", "" ],
|
||||
// [ "kd100_send_site", "" ],
|
||||
// [ "kd100_send_staff", "" ],
|
||||
// [ "kd100_month_code", "" ],
|
||||
// [ "kd100_pay_type", 0 ],
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\ElectronicSheet.add');
|
||||
$id = ( new ElectronicSheetService() )->add($data);
|
||||
@ -113,6 +119,12 @@ class ElectronicSheet extends BaseAdminController
|
||||
[ 'exp_type', 0 ],
|
||||
[ "print_style", "" ],
|
||||
[ "is_default", 0 ],
|
||||
// [ "kd100_customer_name", "" ],
|
||||
// [ "kd100_customer_pwd", "" ],
|
||||
// [ "kd100_send_site", "" ],
|
||||
// [ "kd100_send_staff", "" ],
|
||||
// [ "kd100_month_code", "" ],
|
||||
// [ "kd100_pay_type", 0 ],
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\ElectronicSheet.edit');
|
||||
( new ElectronicSheetService() )->edit($id, $data);
|
||||
@ -156,7 +168,9 @@ class ElectronicSheet extends BaseAdminController
|
||||
[ "kdniao_api_key", "" ],
|
||||
[ 'server_port1', '8000' ],
|
||||
[ 'server_port2', '18000' ],
|
||||
[ 'https_port', '8443' ]
|
||||
[ 'https_port', '8443' ],
|
||||
[ "kd100_key", "" ],
|
||||
[ "kd100_secret", "" ],
|
||||
]);
|
||||
( new ElectronicSheetService() )->setConfig($data);
|
||||
return success();
|
||||
|
||||
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\delivery;
|
||||
|
||||
use core\base\BaseAdminController;
|
||||
use addon\shop\app\service\admin\delivery\StoreService;
|
||||
|
||||
|
||||
/**
|
||||
* 自提门店控制器
|
||||
* Class Store
|
||||
* @package addon\shop\app\adminapi\controller\delivery
|
||||
*/
|
||||
class Store extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 获取展示用信息
|
||||
* @description 获取添加/编辑展示用信息
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
return success(( new StoreService() )->getInitInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自提门店列表
|
||||
* @description 查看自提门店列表详情
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "store_name", "" ],
|
||||
[ "create_time", [ "", "" ] ]
|
||||
]);
|
||||
return success(( new StoreService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 自提门店详情
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function info(int $id)
|
||||
{
|
||||
return success(( new StoreService() )->getInfo($id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加自提门店
|
||||
* @description 添加自提门店
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "store_name", "" ],
|
||||
[ "store_desc", "" ],
|
||||
[ "store_logo", "" ],
|
||||
[ "store_mobile", 0 ],
|
||||
[ "province_name", "" ],
|
||||
[ "city_name", "" ],
|
||||
[ "district_name", "" ],
|
||||
[ "address", "" ],
|
||||
[ "full_address", "" ],
|
||||
[ "longitude", "" ],
|
||||
[ "latitude", "" ],
|
||||
[ "trade_time", "" ],
|
||||
[ "time_type", "" ],//类型
|
||||
[ "time_week", [] ],//周数组
|
||||
[ "time_interval", "" ],//间隔时间段 单位分钟
|
||||
[ "trade_time_json", [] ],//营业时间
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\Store.add');
|
||||
$id = ( new StoreService() )->add($data);
|
||||
return success('ADD_SUCCESS', [ 'id' => $id ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自提门店编辑
|
||||
* @description 编辑自提门店
|
||||
* @param $id 自提门店id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "store_name", "" ],
|
||||
[ "store_desc", "" ],
|
||||
[ "store_logo", "" ],
|
||||
[ "store_mobile", 0 ],
|
||||
[ "address", "" ],
|
||||
[ "full_address", "" ],
|
||||
[ "longitude", "" ],
|
||||
[ "latitude", "" ],
|
||||
[ "trade_time", "" ],
|
||||
[ "time_week", [] ],//周数组
|
||||
[ "time_interval", "" ],//间隔时间段 单位分钟
|
||||
[ "trade_time_json", "" ],//营业时间
|
||||
]);
|
||||
$address = $this->request->params([
|
||||
[ "province_name", "" ],
|
||||
[ "city_name", "" ],
|
||||
[ "district_name", "" ],
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\Store.edit');
|
||||
( new StoreService() )->edit($id, $data, $address);
|
||||
return success('EDIT_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 自提门店删除
|
||||
* @description 删除自提门店
|
||||
* @param $id 自提门店id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function del(int $id)
|
||||
{
|
||||
( new StoreService() )->del($id);
|
||||
return success('DELETE_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查看自提门店列表-全部
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ "store_name", "" ],
|
||||
[ "create_time", [ "", "" ] ]
|
||||
]);
|
||||
return success(( new StoreService() )->getList($data));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\delivery_store;
|
||||
|
||||
use addon\shop\app\service\admin\delivery_store\DeliveryServiceService;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 配送服务商控制器
|
||||
* Class DeliveryService
|
||||
* @package addon\shop\app\adminapi\controller\delivery_store
|
||||
*/
|
||||
class DeliveryService extends BaseAdminController
|
||||
{
|
||||
|
||||
/**
|
||||
* 获取配送服务商列表
|
||||
*/
|
||||
public function getDeliveryServiceList($id)
|
||||
{
|
||||
return success((new DeliveryServiceService())->deliveryServiceList($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送门店开通配送服务
|
||||
* @return Response
|
||||
*/
|
||||
public function deliveryServiceOpen($id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['delivery_type', ''],
|
||||
['business', ''],
|
||||
['extend_data', []]
|
||||
]);
|
||||
(new DeliveryServiceService())->deliveryServiceOpen($id, $data);
|
||||
return success('SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送门店品类修改
|
||||
* @return Response
|
||||
*/
|
||||
public function deliveryServiceEdit($id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['delivery_type', ''],
|
||||
['business', '']
|
||||
]);
|
||||
(new DeliveryServiceService())->deliveryServiceEdit($id, $data);
|
||||
return success('SUCCESS');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\delivery_store;
|
||||
|
||||
use addon\shop\app\service\admin\delivery_store\DeliveryStoreService;
|
||||
use app\upgrade\v158\Upgrade;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* 提货点控制器
|
||||
* Class DeliveryStore
|
||||
* @package addon\shop\app\adminapi\controller\delivery_store
|
||||
*/
|
||||
class DeliveryStore extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 获取展示用信息
|
||||
* @description 获取添加/编辑展示用信息
|
||||
* @return Response
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
return success(( new DeliveryStoreService() )->getInitInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提货点列表
|
||||
* @description 查看提货点列表详情
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['store_name', ''],
|
||||
['pick_up_type', ''],//提货类型
|
||||
['create_time', [] ]
|
||||
]);
|
||||
return success(( new DeliveryStoreService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货点详情
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function info(int $id)
|
||||
{
|
||||
return success(( new DeliveryStoreService() )->getInfo($id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加提货点
|
||||
* @description 添加提货点
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['pick_up_type', ''],//提货类型
|
||||
['store_name', ''],//门店名称
|
||||
['store_logo', ''],//门店logo
|
||||
['contact_name', ''],
|
||||
['store_mobile', ''],
|
||||
[ 'province_id',0 ],
|
||||
[ 'city_id',0 ],
|
||||
[ 'district_id',0 ],
|
||||
['address', ''],
|
||||
['full_address', ''],
|
||||
['longitude', ''],
|
||||
['latitude', ''],
|
||||
['trade_time', ''],
|
||||
['time_is_open', ''],
|
||||
['time_week', [] ],//周数组
|
||||
['time_interval', ''],//间隔时间段 单位分钟
|
||||
['trade_time_json', [] ],//营业时间
|
||||
[ 'area', [] ],//配送区域
|
||||
['status', 0 ]
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\Store.add');
|
||||
$id = ( new DeliveryStoreService() )->add($data);
|
||||
return success('ADD_SUCCESS', [ 'id' => $id ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货点编辑
|
||||
* @description 编辑提货点
|
||||
* @param int $id 提货点id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function edit(int $id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['pick_up_type', ''],//提货类型
|
||||
['store_name', ''],//门店名称
|
||||
['store_logo', ''],//门店logo
|
||||
['contact_name', ''],
|
||||
['store_mobile', ''],
|
||||
[ 'province_id',0 ],
|
||||
[ 'city_id',0 ],
|
||||
[ 'district_id',0 ],
|
||||
['address', ''],
|
||||
['full_address', ''],
|
||||
['longitude', ''],
|
||||
['latitude', ''],
|
||||
['trade_time', ''],
|
||||
['time_is_open', ''],
|
||||
['time_week', [] ],//周数组
|
||||
['time_interval', ''],//间隔时间段 单位分钟
|
||||
['trade_time_json', [] ],//营业时间
|
||||
[ 'area', [] ],//配送区域
|
||||
['status', 0 ]
|
||||
]);
|
||||
$this->validate($data, 'addon\shop\app\validate\delivery\Store.edit');
|
||||
( new DeliveryStoreService() )->edit($id, $data);
|
||||
return success('EDIT_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货点删除
|
||||
* @description 删除提货点
|
||||
* @param int $id 提货点id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function del(int $id)
|
||||
{
|
||||
( new DeliveryStoreService() )->del($id);
|
||||
return success('DELETE_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查看提货点列表-全部
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['keyword', ''],
|
||||
['pick_up_type', '' ]
|
||||
]);
|
||||
return success(( new DeliveryStoreService() )->getList($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 提货点提货类型
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getPickUpType()
|
||||
{
|
||||
return success(( new DeliveryStoreService() )->getPickUpType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改社区分类状态
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function modifyStatus()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ 'store_id', '' ],
|
||||
[ 'status', '' ],
|
||||
]);
|
||||
( new DeliveryStoreService() )->modifyStatus($data);
|
||||
return success('SUCCESS');
|
||||
}
|
||||
|
||||
}
|
||||
@ -85,6 +85,8 @@ class Goods extends BaseAdminController
|
||||
["sub_title", ""],
|
||||
["goods_type", ""],
|
||||
["goods_image", ""],
|
||||
["goods_image_width", ""],
|
||||
["goods_image_height", ""],
|
||||
["goods_video", ""],
|
||||
["goods_category", ''],
|
||||
["brand_id", 0],
|
||||
@ -154,6 +156,8 @@ class Goods extends BaseAdminController
|
||||
["sub_title", ""],
|
||||
["goods_type", ""],
|
||||
["goods_image", ""],
|
||||
["goods_image_width", ""],
|
||||
["goods_image_height", ""],
|
||||
["goods_video", ""],
|
||||
["goods_category", ''],
|
||||
["brand_id", 0],
|
||||
|
||||
@ -47,6 +47,8 @@ class VirtualGoods extends BaseAdminController
|
||||
[ "sub_title", "" ],
|
||||
[ "goods_type", "" ],
|
||||
[ "goods_image", "" ],
|
||||
["goods_image_width", ""],
|
||||
["goods_image_height", ""],
|
||||
[ "goods_video", "" ],
|
||||
[ "goods_category", '' ],
|
||||
[ "brand_id", 0 ],
|
||||
@ -113,6 +115,8 @@ class VirtualGoods extends BaseAdminController
|
||||
[ "sub_title", "" ],
|
||||
[ "goods_type", "" ],
|
||||
[ "goods_image", "" ],
|
||||
["goods_image_width", ""],
|
||||
["goods_image_height", ""],
|
||||
[ "goods_video", "" ],
|
||||
[ "goods_category", '' ],
|
||||
[ "brand_id", 0 ],
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\local_delivery\config;
|
||||
|
||||
use addon\shop\app\service\admin\local_delivery\config\ConfigService;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 配送配置
|
||||
* Class Config
|
||||
* @package addon\shop\app\adminapi\controller\local_delivery\config
|
||||
*/
|
||||
class Config extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 设置配置
|
||||
* @return Response
|
||||
*/
|
||||
public function setConfig(): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['is_show_polyline',0],//是否显示配送轨迹
|
||||
['is_local_delivery_store_select',0],//是否开启门店选择
|
||||
]);
|
||||
(new ConfigService())->setConfig($data);
|
||||
return success('SUCCESS');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* @return Response
|
||||
*/
|
||||
public function getConfig(): Response
|
||||
{
|
||||
return success((new ConfigService())->getConfig());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\local_delivery\config;
|
||||
|
||||
use addon\shop\app\service\admin\local_delivery\config\LocalService;
|
||||
use core\base\BaseAdminController;
|
||||
|
||||
|
||||
/**
|
||||
* 同城配送
|
||||
* @description 同城配送
|
||||
* Class Store
|
||||
* @package addon\shop\app\adminapi\controller\delivery
|
||||
*/
|
||||
class Local extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* @description 查看设置
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getLocal()
|
||||
{
|
||||
return success(data: (new LocalService())->getLocal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 设置配置
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function setLocal()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['fee_type', ''],
|
||||
['base_dist', 0],
|
||||
['base_price', 0],
|
||||
['grad_dist', 0],
|
||||
['grad_price', 0],
|
||||
['weight_start', 0],
|
||||
['weight_unit', 0],
|
||||
['weight_price', 0],
|
||||
|
||||
['time_is_open', 0],
|
||||
['time_type', 0],
|
||||
['time_week', ''],
|
||||
['time_interval', 30],
|
||||
['advance_day', 0],
|
||||
['most_day', 7],
|
||||
['start_time', 0],
|
||||
['end_time', 0],
|
||||
['delivery_time', ''],
|
||||
|
||||
['area_data', []],
|
||||
]);
|
||||
return success(data: (new LocalService())->setLocal($data));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\local_delivery\order;
|
||||
|
||||
use addon\shop\app\service\admin\local_delivery\order\LocalDeliveryOrderService;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 本地配送订单控制器
|
||||
* Class LocalDeliveryOrder
|
||||
* @package addon\shop\app\adminapi\controller\local_delivery\order
|
||||
*/
|
||||
class LocalDeliveryOrder extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 本地配送订单分页列表
|
||||
* @return Response
|
||||
*/
|
||||
public function pages(): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['delivery_no', ''],
|
||||
['trade_no', ''],
|
||||
['status', ''],
|
||||
['create_time', []],
|
||||
]);
|
||||
return success(( new LocalDeliveryOrderService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地配送订单详情
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function info(int $id): Response
|
||||
{
|
||||
return success(( new LocalDeliveryOrderService() )->getInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function closeOrder(int $id): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['cancel_reason_id', ''],
|
||||
['cancel_reason', '']
|
||||
]);
|
||||
$res = ( new LocalDeliveryOrderService() )->closeOrder($id, $data);
|
||||
if ($res) {
|
||||
return success('CANCEL_SUCCESS');
|
||||
} else {
|
||||
return fail('FAIL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成订单
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function finishOrder(int $id): Response
|
||||
{
|
||||
$res = ( new LocalDeliveryOrderService() )->finishOrder($id);
|
||||
if ($res) {
|
||||
return success('SUCCESS');
|
||||
} else {
|
||||
return fail('FAIL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步订单信息
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function syncOrder(int $id): Response
|
||||
{
|
||||
$res = ( new LocalDeliveryOrderService() )->syncOrder($id);
|
||||
if ($res) {
|
||||
return success('SUCCESS');
|
||||
} else {
|
||||
return fail('FAIL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单取消原因
|
||||
* @return Response
|
||||
*/
|
||||
public function getCancelReasonList(): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['service', '']
|
||||
]);
|
||||
return success(( new LocalDeliveryOrderService() )->getCancelReasonList($data['service']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单状态列表
|
||||
* @return Response
|
||||
*/
|
||||
public function getOrderStatusList(): Response
|
||||
{
|
||||
return success((new LocalDeliveryOrderService())->getOrderStatusList());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\local_delivery\service;
|
||||
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryDict;
|
||||
use addon\shop\app\service\admin\local_delivery\service\LocalDeliveryServiceService;
|
||||
use core\base\BaseAdminController;
|
||||
use core\exception\AdminException;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 配送服务商
|
||||
* Class LocalDeliveryService
|
||||
* @package addon\shop\app\adminapi\controller\local_delivery\service
|
||||
*/
|
||||
class LocalDeliveryService extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 获取配送服务商列表
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$res = (new LocalDeliveryServiceService())->getList();
|
||||
return success($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配置
|
||||
* @return Response
|
||||
*/
|
||||
public function setConfig($delivery_type)
|
||||
{
|
||||
//参数获取
|
||||
$delivery_type_list = LocalDeliveryDict::getType();
|
||||
if (!array_key_exists($delivery_type, $delivery_type_list)) throw new AdminException('LOCAL_DELIVERY_TYPE_NOT_EXIST');
|
||||
//数据验证
|
||||
$data = [
|
||||
['is_use', 0]
|
||||
];
|
||||
foreach ($delivery_type_list[$delivery_type]['params'] as $k_param => $v_param) {
|
||||
$data[] = [$k_param, ''];
|
||||
}
|
||||
$request_data = $this->request->params($data);
|
||||
(new LocalDeliveryServiceService())->setConfig($delivery_type, $request_data);
|
||||
return success('SUCCESS');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* @return Response
|
||||
*/
|
||||
public function getConfig($delivery_type)
|
||||
{
|
||||
return success((new LocalDeliveryServiceService())->getConfig($delivery_type,true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已启用配送服务商列表
|
||||
* @return Response
|
||||
*/
|
||||
public function getInUseList()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['store_id', 0],
|
||||
]);
|
||||
return success((new LocalDeliveryServiceService())->getInUseList($data));
|
||||
}
|
||||
}
|
||||
@ -122,6 +122,9 @@ class Order extends BaseAdminController
|
||||
['electronic_sheet_id', 0], // 电子面单
|
||||
['local_deliver_id', 0],//配送员
|
||||
['remark', ''],//配送员
|
||||
['local_delivery_type', ''],
|
||||
['goods_weight', 0],
|
||||
['store_id', ''],//提货点id
|
||||
]);
|
||||
return success("DELIVERY_SUCCESS", (new OrderDeliveryService())->delivery($data));
|
||||
}
|
||||
@ -324,6 +327,35 @@ class Order extends BaseAdminController
|
||||
return success(data: OrderBatchDeliveryDict::getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已选商品总重量
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getSelectOrderGoodsWeight()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ 'order_goods_ids', [] ], // 已选订单项id集合
|
||||
]);
|
||||
return success(data:( new OrderService() )->getSelectOrderGoodsWeight($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送费用计算
|
||||
*/
|
||||
public function getDeliveryFee()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['order_id', 0],
|
||||
['order_goods_ids', []],
|
||||
['delivery_type', ''],
|
||||
['delivery_way', ''],
|
||||
['local_delivery_type', ''],
|
||||
['goods_weight', 0],
|
||||
['store_id', 0],
|
||||
]);
|
||||
return success(data:( new OrderDeliveryService() )->getDeliveryFee($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 删除订单
|
||||
* @return Response
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\shop_delivery\deliver;
|
||||
|
||||
use addon\shop\app\service\admin\shop_delivery\deliver\DeliverService;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 配送员
|
||||
* @description 配送员
|
||||
* Class Deliver
|
||||
* @package addon\shop\app\adminapi\controller\shop_delivery\deliver
|
||||
*/
|
||||
class Deliver extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 获取配送员分页列表
|
||||
* @description 查看配送员列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function pages()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['deliver_name', ''],
|
||||
['deliver_mobile', '']
|
||||
]);
|
||||
return success(( new DeliverService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送员列表
|
||||
* @description 查看配送员列表
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['deliver_name', ''],
|
||||
['deliver_mobile', '']
|
||||
]);
|
||||
return success(( new DeliverService() )->getList($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员详情
|
||||
* @description 查看配送员详情
|
||||
* @param int $id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function info(int $id)
|
||||
{
|
||||
return success(( new DeliverService() )->getInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加配送员
|
||||
* @description 添加配送员
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['deliver_name', ''],
|
||||
['deliver_mobile', ''],
|
||||
]);
|
||||
$id = ( new DeliverService() )->add($data);
|
||||
return success('ADD_SUCCESS', [ 'id' => $id ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员编辑
|
||||
* @description 编辑配送员
|
||||
* @param int $id 自提门店id
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['deliver_name', ''],
|
||||
['deliver_mobile', ''],
|
||||
]);
|
||||
( new DeliverService() )->edit($id, $data);
|
||||
return success('EDIT_SUCCESS');
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送员删除
|
||||
* @description 删除配送员
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function del(int $id)
|
||||
{
|
||||
( new DeliverService() )->del($id);
|
||||
return success('DELETE_SUCCESS');
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\adminapi\controller\shop_delivery\order;
|
||||
|
||||
use addon\shop\app\service\admin\shop_delivery\order\ShopDeliveryOrderService;
|
||||
use core\base\BaseAdminController;
|
||||
use think\Response;
|
||||
|
||||
|
||||
/**
|
||||
* 商家配送订单控制器
|
||||
* Class ShopDeliveryOrder
|
||||
* @package addon\shop\app\adminapi\controller\shop_delivery\order
|
||||
*/
|
||||
class ShopDeliveryOrder extends BaseAdminController
|
||||
{
|
||||
/**
|
||||
* 商家配送订单分页列表
|
||||
* @return Response
|
||||
*/
|
||||
public function pages(): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['delivery_no', ''],
|
||||
['trade_no', ''],
|
||||
['status', ''],
|
||||
['create_time', []],
|
||||
]);
|
||||
return success(( new ShopDeliveryOrderService() )->getPage($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家配送订单详情
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function info(int $id): Response
|
||||
{
|
||||
return success(( new ShopDeliveryOrderService() )->getInfo($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function closeOrder(int $id): Response
|
||||
{
|
||||
$data = $this->request->params([
|
||||
['cancel_reason', '']
|
||||
]);
|
||||
$res = ( new ShopDeliveryOrderService() )->closeOrder($id, $data);
|
||||
if ($res) {
|
||||
return success('CANCEL_SUCCESS');
|
||||
} else {
|
||||
return fail('FAIL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成订单
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function finishOrder(int $id): Response
|
||||
{
|
||||
$res = ( new ShopDeliveryOrderService() )->finishOrder($id);
|
||||
if ($res) {
|
||||
return success('SUCCESS');
|
||||
} else {
|
||||
return fail('FAIL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单状态列表
|
||||
* @return Response
|
||||
*/
|
||||
public function getOrderStatusList(): Response
|
||||
{
|
||||
return success((new ShopDeliveryOrderService())->getOrderStatusList());
|
||||
}
|
||||
}
|
||||
@ -14,9 +14,6 @@ use app\adminapi\middleware\AdminCheckToken;
|
||||
use app\adminapi\middleware\AdminLog;
|
||||
use think\facade\Route;
|
||||
|
||||
// 第三方配送
|
||||
Route::any('delivery/third/callback/:type/:order_no', 'addon\shop\app\adminapi\controller\delivery\Local@thirdDeliveryCallback');
|
||||
|
||||
/**
|
||||
* 商城系统
|
||||
*/
|
||||
@ -65,51 +62,135 @@ Route::group('shop', function () {
|
||||
//运费模版 删除
|
||||
Route::delete('shipping/template/:template_id', 'addon\shop\app\adminapi\controller\delivery\ShippingTemplate@del');
|
||||
|
||||
//自提门店列表(分页)
|
||||
Route::get('delivery/store', 'addon\shop\app\adminapi\controller\delivery\Store@lists');
|
||||
/************************************************** 提货点 *****************************************************/
|
||||
//提货点列表(分页)
|
||||
Route::get('delivery/store', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@lists');
|
||||
|
||||
Route::get('delivery/store/init', 'addon\shop\app\adminapi\controller\delivery\Store@init');
|
||||
//提货点初始化数据
|
||||
Route::get('delivery/store/init', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@init');
|
||||
|
||||
//自提门店列表(不分页)
|
||||
Route::get('delivery/store/list', 'addon\shop\app\adminapi\controller\delivery\Store@getList');
|
||||
//提货点列表(不分页)
|
||||
Route::get('delivery/store/list', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@getList');
|
||||
|
||||
//自提门店详情
|
||||
Route::get('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery\Store@info');
|
||||
//提货点详情
|
||||
Route::get('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@info');
|
||||
|
||||
//添加自提门店
|
||||
Route::post('delivery/store', 'addon\shop\app\adminapi\controller\delivery\Store@add');
|
||||
//添加提货点
|
||||
Route::post('delivery/store', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@add');
|
||||
|
||||
//编辑自提门店
|
||||
Route::put('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery\Store@edit');
|
||||
//编辑提货点
|
||||
Route::put('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@edit');
|
||||
|
||||
//删除自提门店
|
||||
Route::delete('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery\Store@del');
|
||||
//删除提货点
|
||||
Route::delete('delivery/store/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@del');
|
||||
|
||||
//提货点提货类型
|
||||
Route::get('delivery/store/pick_up_type', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@getPickUpType');
|
||||
|
||||
//修改提货点状态
|
||||
Route::put('delivery/store/modify_status', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryStore@modifyStatus');
|
||||
|
||||
/************************************************** 配送服务商 *****************************************************/
|
||||
//获取配送服务商列表
|
||||
Route::get('delivery_store/delivery_service_list/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryService@getDeliveryServiceList');
|
||||
|
||||
//配送门店开通配送服务
|
||||
Route::put('delivery_store/delivery_shop_open/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryService@deliveryServiceOpen');
|
||||
|
||||
//配送门店品类修改
|
||||
Route::put('delivery_store/delivery_shop_edit/:id', 'addon\shop\app\adminapi\controller\delivery_store\DeliveryService@deliveryServiceEdit');
|
||||
|
||||
/************************************************** 配送设置 *****************************************************/
|
||||
//物流配置
|
||||
Route::get('delivery/deliveryList', 'addon\shop\app\adminapi\controller\delivery\Delivery@getDeliveryList');
|
||||
Route::put('delivery/setConfig', 'addon\shop\app\adminapi\controller\delivery\Delivery@setDeliveryConfig');
|
||||
|
||||
//配送员列表
|
||||
Route::get('delivery/staff', 'addon\shop\app\adminapi\controller\delivery\Delivery@lists');
|
||||
//获取配送方式
|
||||
Route::get('delivery/delivery_type', 'addon\shop\app\adminapi\controller\delivery\Delivery@getDeliveryType');
|
||||
|
||||
//配送员详情
|
||||
Route::get('delivery/staff/:id', 'addon\shop\app\adminapi\controller\delivery\Delivery@info');
|
||||
|
||||
//添加配送员
|
||||
Route::post('delivery/staff', 'addon\shop\app\adminapi\controller\delivery\Delivery@add');
|
||||
|
||||
//编辑配送员
|
||||
Route::put('delivery/staff/:id', 'addon\shop\app\adminapi\controller\delivery\Delivery@edit');
|
||||
|
||||
//删除配送员
|
||||
Route::delete('delivery/staff/:id', 'addon\shop\app\adminapi\controller\delivery\Delivery@del');
|
||||
/************************************************** 同城配送 *******************************************************/
|
||||
|
||||
// 获取同城配送设置
|
||||
Route::get('local', 'addon\shop\app\adminapi\controller\delivery\Local@getLocal');
|
||||
Route::get('local_delivery/config', 'addon\shop\app\adminapi\controller\local_delivery\config\Local@getLocal');
|
||||
|
||||
// 设置同城配送
|
||||
Route::put('local', 'addon\shop\app\adminapi\controller\delivery\Local@setLocal');
|
||||
Route::get('third/init', 'addon\shop\app\adminapi\controller\delivery\Local@getThirdPartyInit');
|
||||
Route::put('local_delivery/config', 'addon\shop\app\adminapi\controller\local_delivery\config\Local@setLocal');
|
||||
|
||||
// 获取同城配送基础配置
|
||||
Route::get('local_delivery/base_config', 'addon\shop\app\adminapi\controller\local_delivery\config\Config@getConfig');
|
||||
|
||||
// 设置同城配送基础配置
|
||||
Route::put('local_delivery/base_config', 'addon\shop\app\adminapi\controller\local_delivery\config\Config@setConfig');
|
||||
|
||||
//获取已启用配送服务商列表
|
||||
Route::get('local_delivery/list', 'addon\shop\app\adminapi\controller\local_delivery\service\LocalDeliveryService@getInUseList');
|
||||
|
||||
//同城配送服务商列表
|
||||
Route::get('local_delivery/service', 'addon\shop\app\adminapi\controller\local_delivery\service\LocalDeliveryService@lists');
|
||||
|
||||
//同城配送服务商配置
|
||||
Route::get('local_delivery/service/:delivery_type', 'addon\shop\app\adminapi\controller\local_delivery\service\LocalDeliveryService@getConfig');
|
||||
|
||||
//同城配送服务商配置修改
|
||||
Route::put('local_delivery/service/:delivery_type', 'addon\shop\app\adminapi\controller\local_delivery\service\LocalDeliveryService@setConfig');
|
||||
|
||||
// 同城配送订单
|
||||
Route::get('local_delivery/order', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@pages');
|
||||
|
||||
// 同城配送订单详情
|
||||
Route::get('local_delivery/order/:id', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@info');
|
||||
|
||||
// 同城配送订单同步
|
||||
Route::put('local_delivery/order/sync/:id', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@syncOrder');
|
||||
|
||||
// 同城配送订单取消原因
|
||||
Route::get('local_delivery/order/cancel_reason', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@getCancelReasonList');
|
||||
|
||||
// 同城配送订单取消
|
||||
Route::put('local_delivery/order/cancel/:id', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@closeOrder');
|
||||
|
||||
// 同城配送订单完成
|
||||
Route::put('local_delivery/order/finish/:id', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@finishOrder');
|
||||
|
||||
// 同城配送订单状态列表
|
||||
Route::get('local_delivery/order/status', 'addon\shop\app\adminapi\controller\local_delivery\order\LocalDeliveryOrder@getOrderStatusList');
|
||||
|
||||
/************************************************** 商家配送 *******************************************************/
|
||||
|
||||
//配送员分页列表
|
||||
Route::get('shop_delivery/staff', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@pages');
|
||||
|
||||
//配送员列表
|
||||
Route::get('shop_delivery/staff/list', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@lists');
|
||||
|
||||
//配送员详情
|
||||
Route::get('shop_delivery/staff/:id', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@info');
|
||||
|
||||
//添加配送员
|
||||
Route::post('shop_delivery/staff', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@add');
|
||||
|
||||
//编辑配送员
|
||||
Route::put('shop_delivery/staff/:id', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@edit');
|
||||
|
||||
//删除配送员
|
||||
Route::delete('shop_delivery/staff/:id', 'addon\shop\app\adminapi\controller\shop_delivery\deliver\Deliver@del');
|
||||
|
||||
// 商家配送订单
|
||||
Route::get('shop_delivery/order', 'addon\shop\app\adminapi\controller\shop_delivery\order\ShopDeliveryOrder@pages');
|
||||
|
||||
// 商家配送订单详情
|
||||
Route::get('shop_delivery/order/:id', 'addon\shop\app\adminapi\controller\shop_delivery\order\ShopDeliveryOrder@info');
|
||||
|
||||
// 商家配送订单取消
|
||||
Route::put('shop_delivery/order/cancel/:id', 'addon\shop\app\adminapi\controller\shop_delivery\order\ShopDeliveryOrder@closeOrder');
|
||||
|
||||
// 商家配送订单完成
|
||||
Route::put('shop_delivery/order/finish/:id', 'addon\shop\app\adminapi\controller\shop_delivery\order\ShopDeliveryOrder@finishOrder');
|
||||
|
||||
// 商家配送订单状态列表
|
||||
Route::get('shop_delivery/order/status', 'addon\shop\app\adminapi\controller\shop_delivery\order\ShopDeliveryOrder@getOrderStatusList');
|
||||
|
||||
// Route::get('third/init', 'addon\shop\app\adminapi\controller\delivery\Local@getThirdPartyInit');
|
||||
|
||||
/************************************************** 接口管理 *******************************************************/
|
||||
|
||||
@ -414,6 +495,12 @@ Route::group('shop', function () {
|
||||
//获取订单配送方式
|
||||
Route::get('order/delivery_type', 'addon\shop\app\adminapi\controller\order\Order@getDeliveryType');
|
||||
|
||||
//获取已选订单项总重量
|
||||
Route::get('order/select/weight', 'addon\shop\app\adminapi\controller\order\Order@getSelectOrderGoodsWeight');
|
||||
|
||||
//同城配送费用计算
|
||||
Route::get('order/delivery/fee', 'addon\shop\app\adminapi\controller\order\Order@getDeliveryFee');
|
||||
|
||||
//商家留言
|
||||
Route::put('order/shop_remark', 'addon\shop\app\adminapi\controller\order\Order@setShopRemark');
|
||||
|
||||
|
||||
47
niucloud/addon/shop/app/api/controller/delivery/Order.php
Normal file
47
niucloud/addon/shop/app/api/controller/delivery/Order.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\api\controller\delivery;
|
||||
|
||||
use addon\shop\app\service\api\delivery\OrderService;
|
||||
use addon\shop\app\service\core\local_delivery\CoreLocalDeliveryOrderNotifyService;
|
||||
use core\base\BaseApiController;
|
||||
use think\Response;
|
||||
|
||||
class Order extends BaseApiController
|
||||
{
|
||||
/**
|
||||
* 订单状态回调
|
||||
* @param $type
|
||||
* @param $order_no
|
||||
* @param $action
|
||||
* @return Response
|
||||
*/
|
||||
public function notify($type, $order_no, $action)
|
||||
{
|
||||
$params = $this->request->all();
|
||||
$params['type'] = $type;
|
||||
$params['order_no'] = $order_no;
|
||||
return (new CoreLocalDeliveryOrderNotifyService())->notify($type, $order_no, $action, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送轨迹
|
||||
* @return Response
|
||||
*/
|
||||
public function getTrackOfLocalDeliveryOrder()
|
||||
{
|
||||
$data = $this->request->params([
|
||||
[ 'trade_no', '' ],
|
||||
]);
|
||||
return success(( new OrderService() )->getTrackOfLocalDeliveryOrder($data));
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,7 @@ class OrderCreate extends BaseApiController
|
||||
// ['invoice', []],//发票
|
||||
['extend_data', []],// 扩展数据
|
||||
['impulse_buy_goods', []], // 顺买商品信息
|
||||
['position', []],//用户位置信息
|
||||
]);
|
||||
|
||||
return success('SUCCESS', ( new OrderCreateService() )->calculate($data));
|
||||
|
||||
@ -14,7 +14,8 @@ use app\api\middleware\ApiCheckToken;
|
||||
use app\api\middleware\ApiLog;
|
||||
use think\facade\Route;
|
||||
|
||||
|
||||
// 第三方配送
|
||||
Route::any('delivery/notify/:type/:order_no/:action', 'addon\shop\app\api\controller\delivery\Order@notify');
|
||||
/**
|
||||
* 商城系统
|
||||
*/
|
||||
@ -204,6 +205,9 @@ Route::group('shop', function () {
|
||||
Route::get('order_create/store', 'addon\shop\app\api\controller\order\OrderCreate@getStore');
|
||||
Route::get('order_create/local', 'addon\shop\app\api\controller\order\OrderCreate@getLocalDeliveryConfig');
|
||||
|
||||
// 获取同城配送轨迹
|
||||
Route::get('delivery/track_of_local', 'addon\shop\app\api\controller\delivery\Order@getTrackOfLocalDeliveryOrder');
|
||||
|
||||
//获取订单确认数据
|
||||
Route::get('confirm', 'addon\shop\app\api\controller\order\OrderCreate@confirm');
|
||||
|
||||
|
||||
@ -14,6 +14,9 @@ namespace addon\shop\app\dict\delivery;
|
||||
class ElectronicSheetDict
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取邮费支付方式类型
|
||||
* @param $type
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\delivery_store;
|
||||
|
||||
/**
|
||||
* 提货点枚举类
|
||||
* Class LocalDeliveryDict
|
||||
* @package app\dict\sys
|
||||
*/
|
||||
class DeliveryStoreDict
|
||||
{
|
||||
|
||||
//同城配送
|
||||
const LOCAL_DELIVERY = 'local_delivery';
|
||||
//门店自提
|
||||
const STORE = 'store';
|
||||
|
||||
/**
|
||||
* 获取提货类型
|
||||
* @param string $type
|
||||
* @return array|string
|
||||
*/
|
||||
public static function getPickUpType($type = '')
|
||||
{
|
||||
$pick_up_type = [
|
||||
self::LOCAL_DELIVERY => get_lang('dict_shop_delivery_store_pick_up_type.local_delivery'),
|
||||
self::STORE => get_lang('dict_shop_delivery_store_pick_up_type.store'),
|
||||
];
|
||||
if (!empty($type)) {
|
||||
return $pick_up_type[$type] ?? '';
|
||||
}
|
||||
return $pick_up_type;
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,6 +25,7 @@ return [
|
||||
"fontWeight" => 'normal',
|
||||
"isShow" => true
|
||||
],
|
||||
"mode" => "aspectFill",
|
||||
"priceStyle" => [
|
||||
"color" => "#FF4142",
|
||||
"control" => true,
|
||||
@ -126,6 +127,7 @@ return [
|
||||
'value' => [
|
||||
'style' => 'style-2',
|
||||
'num' => 6,
|
||||
"mode" => "aspectFill",
|
||||
"sortWay" => "default", // 排序方式,default:综合,sale_num:销量,price:价格
|
||||
"headStyle" => "style-1",
|
||||
"aroundRadius" => 25,
|
||||
@ -237,8 +239,8 @@ return [
|
||||
"componentStartBgColor" => '', // 组件背景颜色(开始)
|
||||
"componentEndBgColor" => '', // 组件背景颜色(结束)
|
||||
"componentGradientAngle" => 'to bottom', // 渐变角度,上下(to bottom)、左右(to right)
|
||||
"topRounded" => 0, // 组件上圆角
|
||||
"bottomRounded" => 0, // 组件下圆角
|
||||
"topRounded" => 12, // 组件上圆角
|
||||
"bottomRounded" => 12, // 组件下圆角
|
||||
"elementBgColor" => '', // 元素背景颜色
|
||||
"topElementRounded" => 0,// 元素上圆角
|
||||
"bottomElementRounded" => 0, // 元素下圆角
|
||||
@ -308,6 +310,7 @@ return [
|
||||
'sort' => 10018,
|
||||
'value' => [
|
||||
'style' => 'style-2',
|
||||
"mode" => "aspectFill",
|
||||
'source' => 'all',
|
||||
'num' => 10,
|
||||
'goods_category' => '',
|
||||
@ -365,6 +368,7 @@ return [
|
||||
"priceStyle" => [
|
||||
"mainColor" => "#333333",
|
||||
],
|
||||
"mode" => "aspectFill",
|
||||
'source' => 'all',
|
||||
"goods_ids" => [],
|
||||
'list' => [
|
||||
@ -465,6 +469,7 @@ return [
|
||||
'uses' => 0,
|
||||
'sort' => 10019,
|
||||
'value' => [
|
||||
"mode" => "aspectFill",
|
||||
"titleStyle" => [
|
||||
'title' => '风格1',
|
||||
'value' => 'style-1'
|
||||
@ -553,6 +558,7 @@ return [
|
||||
'uses' => 1,
|
||||
'sort' => 10020,
|
||||
'value' => [
|
||||
"mode" => "aspectFill",
|
||||
"style" => [
|
||||
'title' => '风格1',
|
||||
'value' => 'style-1'
|
||||
@ -611,6 +617,7 @@ return [
|
||||
'uses' => 0,
|
||||
'sort' => 10021,
|
||||
'value' => [
|
||||
"mode" => "aspectFill",
|
||||
"list" => [
|
||||
[
|
||||
'bgUrl' => 'addon/shop/rank/rank_bg_01.jpg', // 榜单背景图
|
||||
@ -682,7 +689,81 @@ return [
|
||||
"both" => 10 // 左右边距
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'ShopGoodsHot' => [
|
||||
'title' => '爆款商品',
|
||||
'icon' => 'iconfont iconjifenshangpinpc',
|
||||
'path' => 'edit-shop-goods-hot',
|
||||
'support_page' => [],
|
||||
'uses' => 0,
|
||||
'sort' => 10022,
|
||||
'value' => [
|
||||
"mode" => "aspectFill",
|
||||
'titleStyle' => [
|
||||
'text' => '大牌直降',
|
||||
'textColor' => '#FFFFFF',
|
||||
"fontWeight" => 'bold',
|
||||
"fontSize" => 18,
|
||||
'imgUrl' => '',
|
||||
'way' => 'text', // 展示方式,text:文本,img:图片
|
||||
"link" => [
|
||||
"name" => ""
|
||||
]
|
||||
],
|
||||
'subTitleStyle' => [
|
||||
'text' => '7月10日-29日',
|
||||
'textColor' => '#ffffff',
|
||||
'bgColor' => '#ff737a',
|
||||
"rounded" => 6,
|
||||
"fontSize" => 12
|
||||
],
|
||||
'btnStyle' => [
|
||||
"text" => '立即抢购',
|
||||
'textColor' => '#ee695c',
|
||||
"startBgColor" => "",
|
||||
"endBgColor" => "",
|
||||
"gradientType" => "radial",
|
||||
"fontSize" => 12,
|
||||
"link" => [
|
||||
"name" => ""
|
||||
]
|
||||
],
|
||||
'goodsStyle' => [
|
||||
'bgColor' => '#ffffff',
|
||||
'labelText' => '大牌直降',
|
||||
'labelSize' => 10,
|
||||
'labelColor' => '#ffffff',
|
||||
'labelBgColor' => '#FF0000',
|
||||
"rounded" => 8,
|
||||
"imgRounded" => 7,
|
||||
'source' => 'all', // 商品来源方式
|
||||
'num' => 10,
|
||||
"goodsIds" => []
|
||||
]
|
||||
],
|
||||
// 组件属性
|
||||
'template' => [
|
||||
"textColor" => "#303133", // 文字颜色
|
||||
'pageStartBgColor' => '#FF0000', // 底部背景颜色(开始)
|
||||
'pageEndBgColor' => '', // 底部背景颜色(结束)
|
||||
'pageGradientAngle' => 'to bottom', // 渐变角度,从上到下(to bottom)、从左到右(to right)
|
||||
'componentBgUrl' => '', // 组件背景图片
|
||||
'componentBgAlpha' => 2, // 组件背景图片的透明度,0~10
|
||||
"componentStartBgColor" => '', // 组件背景颜色(开始)
|
||||
"componentEndBgColor" => '', // 组件背景颜色(结束)
|
||||
"componentGradientAngle" => 'to bottom', // 渐变角度,上下(to bottom)、左右(to right)
|
||||
"topRounded" => 0, // 组件上圆角
|
||||
"bottomRounded" => 0, // 组件下圆角
|
||||
"elementBgColor" => '', // 元素背景颜色
|
||||
"topElementRounded" => 0,// 元素上圆角
|
||||
"bottomElementRounded" => 0, // 元素下圆角
|
||||
"margin" => [
|
||||
"top" => 12, // 上边距
|
||||
"bottom" => 12, // 下边距
|
||||
"both" => 10 // 左右边距
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
'SHOP_GOODS_DETAIL_COMPONENT' => [
|
||||
|
||||
@ -967,6 +967,7 @@ return [
|
||||
"id" => "2ezdal8ps1og",
|
||||
"componentName" => "ShopGoodsRecommend",
|
||||
"componentTitle" => "商品推荐",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
"priceStyle" => [
|
||||
"mainColor" => "#333333"
|
||||
@ -1441,6 +1442,7 @@ return [
|
||||
"id" => "2hjc1q7f7q80",
|
||||
"componentName" => "ShopNewcomer",
|
||||
"componentTitle" => "新人专享",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
"style" => [
|
||||
"title" => "风格1",
|
||||
@ -1496,6 +1498,7 @@ return [
|
||||
"uses" => 0,
|
||||
"id" => "2mxsu6pbqpu0",
|
||||
"componentName" => "SingleRecommend",
|
||||
"mode" => "aspectFill",
|
||||
"componentTitle" => "精选推荐",
|
||||
"ignore" => [],
|
||||
"titleStyle" => [
|
||||
@ -1631,6 +1634,7 @@ return [
|
||||
"id" => "37adfqtqe080",
|
||||
"componentName" => "ManyGoodsList",
|
||||
"componentTitle" => "多商品组",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [
|
||||
"componentBgUrl"
|
||||
],
|
||||
@ -2788,6 +2792,7 @@ return [
|
||||
"id" => "17uao387qdds",
|
||||
"componentName" => "GoodsList",
|
||||
"componentTitle" => "商品列表",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
"style" => "style-3",
|
||||
"source" => "all",
|
||||
@ -2939,6 +2944,7 @@ return [
|
||||
"id" => "2u96wyrm79u0",
|
||||
"componentName" => "GoodsList",
|
||||
"componentTitle" => "商品列表",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
"style" => "style-1",
|
||||
"source" => "all",
|
||||
@ -3059,6 +3065,7 @@ return [
|
||||
"id" => "4y7mw7j2uko0",
|
||||
"componentName" => "GoodsList",
|
||||
"componentTitle" => "商品列表",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
"style" => "style-2",
|
||||
"source" => "all",
|
||||
@ -3126,6 +3133,7 @@ return [
|
||||
"id" => "65lv65b38ig0",
|
||||
"componentName" => "ManyGoodsList",
|
||||
"componentTitle" => "多商品组",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => ['componentBgUrl'],
|
||||
"style" => "style-2",
|
||||
"num" => 6,
|
||||
@ -3767,6 +3775,7 @@ return [
|
||||
"id" => "50pj7dmvbvo0",
|
||||
"componentName" => "GoodsList",
|
||||
"componentTitle" => "商品列表",
|
||||
"mode" => "aspectFill",
|
||||
"ignore" => [],
|
||||
'style' => 'style-1',
|
||||
"source" => "all",
|
||||
@ -5182,6 +5191,7 @@ return [
|
||||
"id" => "76wf7oom00o0",
|
||||
"componentName" => "ShopExchangeGoods",
|
||||
"componentTitle" => "积分商品",
|
||||
"mode" => "aspectFill",
|
||||
"path" => "edit-shop-exchange-goods",
|
||||
"uses" => 0,
|
||||
"ignore" => [],
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery;
|
||||
|
||||
/**
|
||||
* 同城配送枚举类
|
||||
* Class LocalDeliveryDict
|
||||
* @package addon\shop\app\dict\local_delivery
|
||||
*/
|
||||
class LocalDeliveryDict
|
||||
{
|
||||
|
||||
//商家配送
|
||||
const MERCHANT = 'merchant';
|
||||
|
||||
public static function getType($type = '')
|
||||
{
|
||||
$list = [
|
||||
self::MERCHANT => [
|
||||
'name' => '商家配送',
|
||||
'key' => self::MERCHANT,
|
||||
//配置参数
|
||||
'params' => [],
|
||||
'component' => '',
|
||||
'business_list' => '',
|
||||
'extend_data' => [],
|
||||
//商家配送标识
|
||||
'is_merchant' => 1
|
||||
],
|
||||
];
|
||||
|
||||
$extend = event('LocalDeliveryType');
|
||||
$type_list = array_merge($list, ...$extend);
|
||||
if ($type == '') return $type_list;
|
||||
return $type_list[$type]['name'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
//门店开通状态
|
||||
const OPEN_PASS = 1;//通过
|
||||
const OPEN_REFUND = 2;//未通过
|
||||
|
||||
//门店编辑状态
|
||||
const EDIT_PASS = 1;//编辑审核通过
|
||||
const EDIT_REFUND = 2;//编辑审核驳回
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery;
|
||||
|
||||
/**
|
||||
* 配送订单操作前置状态枚举类
|
||||
* Class LocalDeliveryDict
|
||||
* @package app\dict\sys
|
||||
*/
|
||||
class LocalDeliveryPreStatusDict
|
||||
{
|
||||
|
||||
public static function getStatus(string $service = '')
|
||||
{
|
||||
$list = [];
|
||||
|
||||
$extend = array_filter(event('DeliveryOrderPreStatus', ['service' => $service]));
|
||||
return array_merge($list, ...$extend);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery;
|
||||
|
||||
|
||||
/**
|
||||
*同城配送相关枚举类
|
||||
*/
|
||||
class LocalDeliveryStatusDict
|
||||
{
|
||||
|
||||
const WAIT_RELEASE = -100; // 预约待发布
|
||||
// 订单状态常量定义
|
||||
const ORDER_ACCEPTED = 0; // 商家已接单
|
||||
const PENDING_ACCEPTANCE = 1; // 待接单
|
||||
const PENDING_PICKUP = 2; // 待取货
|
||||
const RIDER_ARRIVED = 3; // 骑士到店
|
||||
const IN_DELIVERY = 4; // 配送中
|
||||
const COMPLETED = 5; // 已完成
|
||||
const DISPATCH_ORDER = 6; // 指派单(已追加待接单)
|
||||
const RETURN_IN_PROGRESS = 7; // 妥投异常之物品返回中
|
||||
const RETURN_COMPLETED = 8; // 妥投异常之物品返回完成
|
||||
const RETURN_RIDER_ARRIVED = 9; // 售后取件单送达门店
|
||||
const CREATE_ORDER_FAILED = -1; // 创建运单失败
|
||||
const CANCELED = -2; // 已取消
|
||||
|
||||
/**
|
||||
* 获取所有订单状态映射
|
||||
* @return array|mixed|string
|
||||
*/
|
||||
public static function getStatus(string $status = '')
|
||||
{
|
||||
$data = [
|
||||
self::WAIT_RELEASE => get_lang('dict_shop_local_delivery_status.wait_release'), //预约待发布,
|
||||
self::ORDER_ACCEPTED => get_lang('dict_shop_local_delivery_status.order_accepted'), //商家已接单,
|
||||
self::PENDING_ACCEPTANCE => get_lang('dict_shop_local_delivery_status.pending_acceptance'), //待接单,
|
||||
self::PENDING_PICKUP => get_lang('dict_shop_local_delivery_status.pending_pickup'), //待取货,
|
||||
self::RIDER_ARRIVED => get_lang('dict_shop_local_delivery_status.rider_arrived'), //骑士到店,
|
||||
self::IN_DELIVERY => get_lang('dict_shop_local_delivery_status.in_delivery'), //配送中,
|
||||
self::COMPLETED => get_lang('dict_shop_local_delivery_status.completed'), //已完成,
|
||||
self::DISPATCH_ORDER => get_lang('dict_shop_local_delivery_status.dispatch_order'), //指派单,
|
||||
self::RETURN_IN_PROGRESS => get_lang('dict_shop_local_delivery_status.return_in_progress'), //妥投异常之物品返回中,
|
||||
self::RETURN_COMPLETED => get_lang('dict_shop_local_delivery_status.return_completed'), //妥投异常之物品返回完成,
|
||||
self::RETURN_RIDER_ARRIVED => get_lang('dict_shop_local_delivery_status.return_rider_arrived'), //售后取件单送达门店,
|
||||
self::CREATE_ORDER_FAILED => get_lang('dict_shop_local_delivery_status.create_order_failed'), //创建运单失败,
|
||||
self::CANCELED => get_lang('dict_shop_local_delivery_status.canceled'), //已取消,
|
||||
];
|
||||
if ($status == '' && $status !== 0) {
|
||||
return $data;
|
||||
}
|
||||
return $data[$status] ?? '';
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery;
|
||||
|
||||
|
||||
/**
|
||||
*订单取消原因相关枚举类
|
||||
*/
|
||||
class OrderCancelReasonDict
|
||||
{
|
||||
/**
|
||||
* 获取订单取消原因枚举列表
|
||||
* @return array|mixed|string
|
||||
*/
|
||||
public static function getType($type = '', string $service = '')
|
||||
{
|
||||
$data = array_filter(event('OrderCancelReason', ['service' => $service]))[0];
|
||||
if ($type == '') {
|
||||
return $data;
|
||||
}
|
||||
return $data[$type] ?? '';
|
||||
}
|
||||
|
||||
}
|
||||
121
niucloud/addon/shop/app/dict/local_delivery/OrderLogDict.php
Normal file
121
niucloud/addon/shop/app/dict/local_delivery/OrderLogDict.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery;
|
||||
|
||||
|
||||
/**
|
||||
* 订单日志枚举类
|
||||
*/
|
||||
class OrderLogDict
|
||||
{
|
||||
|
||||
const STORE = 'store';
|
||||
const RIDER = 'rider';
|
||||
const MEMBER = 'member';
|
||||
const SYSTEM = 'system';
|
||||
|
||||
|
||||
/**
|
||||
* 获取操作人类型
|
||||
* @param string $type
|
||||
* @return array|array[]|string
|
||||
*/
|
||||
public static function getMainType(string $type = '')
|
||||
{
|
||||
$data = [
|
||||
self::STORE => get_lang('dict_shop_local_delivery_order_log.store'),//商家
|
||||
self::RIDER => get_lang('dict_shop_local_delivery_order_log.rider'),//骑手
|
||||
self::MEMBER => get_lang('dict_shop_local_delivery_order_log.member'),//会员
|
||||
self::SYSTEM => get_lang('dict_shop_local_delivery_order_log.system'),//系统
|
||||
];
|
||||
if (!$type) {
|
||||
return $data;
|
||||
}
|
||||
return $data[$type] ?? '';
|
||||
}
|
||||
|
||||
const ORDER_ACCEPTED = 'order_accepted';//商家已接单
|
||||
const ORDER_CALL = 'order_call';//商家呼叫配送
|
||||
const DISPATCH_ORDER = 'dispatch_order';//商家指派骑手
|
||||
const RIDER_ACCEPTED = 'rider_accepted';//骑手已接单
|
||||
const RIDER_ARRIVED = 'rider_arrived';//骑手已到店
|
||||
const RIDER_PICKED_UP = 'rider_picked_up';//骑手已取货
|
||||
const ORDER_DELIVERED = 'order_delivered';//订单已送达
|
||||
const ORDER_CANCELED = 'order_canceled';//订单已取消
|
||||
const RETURN_APPLIED = 'return_applied';//物品返回申请
|
||||
const RETURN_COMPLETED = 'return_completed';//物品返回完成
|
||||
|
||||
/**
|
||||
* 获取操作
|
||||
* @return array
|
||||
*/
|
||||
public static function getOperate($status)
|
||||
{
|
||||
switch ($status) {
|
||||
case LocalDeliveryStatusDict::ORDER_ACCEPTED:
|
||||
return [
|
||||
'operate' => self::ORDER_ACCEPTED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.order_accepted')
|
||||
];// 商家已接单
|
||||
case LocalDeliveryStatusDict::PENDING_ACCEPTANCE:
|
||||
return [
|
||||
'operate' => self::ORDER_CALL,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.order_call')
|
||||
];// 商家呼叫配送
|
||||
case LocalDeliveryStatusDict::DISPATCH_ORDER:
|
||||
return [
|
||||
'operate' => self::DISPATCH_ORDER,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.dispatch_order')
|
||||
];// 商家指派骑手
|
||||
case LocalDeliveryStatusDict::PENDING_PICKUP:
|
||||
return [
|
||||
'operate' => self::RIDER_ACCEPTED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.rider_accepted')
|
||||
];// 骑手已接单
|
||||
case LocalDeliveryStatusDict::RIDER_ARRIVED:
|
||||
return [
|
||||
'operate' => self::RIDER_ARRIVED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.rider_arrived')
|
||||
];// 骑手已到店
|
||||
case LocalDeliveryStatusDict::IN_DELIVERY:
|
||||
return [
|
||||
'operate' => self::RIDER_PICKED_UP,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.rider_picked_up')
|
||||
];// 骑手已取货
|
||||
case LocalDeliveryStatusDict::COMPLETED:
|
||||
return [
|
||||
'operate' => self::ORDER_DELIVERED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.order_delivered')
|
||||
];// 订单已送达
|
||||
case LocalDeliveryStatusDict::CANCELED:
|
||||
return [
|
||||
'operate' => self::ORDER_CANCELED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.order_canceled')
|
||||
];// 订单已取消
|
||||
case LocalDeliveryStatusDict::RETURN_IN_PROGRESS:
|
||||
return [
|
||||
'operate' => self::RETURN_APPLIED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.return_applied')
|
||||
];// 物品返回申请
|
||||
case LocalDeliveryStatusDict::RETURN_COMPLETED:
|
||||
return [
|
||||
'operate' => self::RETURN_COMPLETED,
|
||||
'operate_desc' => get_lang('dict_shop_local_delivery_order_log.return_completed')
|
||||
];// 物品返回完成
|
||||
}
|
||||
return [
|
||||
'operate' => '',
|
||||
'operate_desc' => ''
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery\dada;
|
||||
|
||||
/**
|
||||
* 达达秒送枚举类
|
||||
* Class DadaDeliveryDict
|
||||
* @package addon\shop\app\dict\local_delivery\dada
|
||||
*/
|
||||
class DadaDeliveryDict
|
||||
{
|
||||
|
||||
//达达秒送
|
||||
const DADA = 'dada';
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\local_delivery\dada;
|
||||
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryStatusDict;
|
||||
|
||||
/**
|
||||
*同城三方配送相关枚举类
|
||||
*/
|
||||
class DadaDeliveryStatusDict
|
||||
{
|
||||
// 订单状态常量定义
|
||||
|
||||
const WAIT_RELEASE = 0; // 预约待发布
|
||||
const PENDING_ACCEPTANCE = 1; // 待接单
|
||||
const PENDING_PICKUP = 2; // 待取货
|
||||
const RIDER_ARRIVED = 100; // 骑士到店
|
||||
const IN_DELIVERY = 3; // 配送中
|
||||
const COMPLETED = 4; // 已完成
|
||||
const DISPATCH_ORDER = 8; // 指派单(已追加待接单)
|
||||
const RETURN_IN_PROGRESS = 9; // 妥投异常之物品返回中
|
||||
const RETURN_COMPLETED = 10; // 妥投异常之物品返回完成
|
||||
const RETURN_RIDER_ARRIVED = 6; // 售后取件单送达门店
|
||||
const CREATE_ORDER_FAILED = 1000; // 创建运单失败
|
||||
const CANCELED = 5; // 已取消
|
||||
|
||||
/**
|
||||
* 转换配送状态
|
||||
* @param $status
|
||||
* @return int
|
||||
*/
|
||||
public static function convertStatus($status)
|
||||
{
|
||||
switch ($status) {
|
||||
case self::WAIT_RELEASE:
|
||||
return LocalDeliveryStatusDict::WAIT_RELEASE;// 待接单
|
||||
case self::PENDING_ACCEPTANCE:
|
||||
return LocalDeliveryStatusDict::PENDING_ACCEPTANCE;// 待接单
|
||||
case self::PENDING_PICKUP:
|
||||
return LocalDeliveryStatusDict::PENDING_PICKUP;// 待取货
|
||||
case self::RIDER_ARRIVED:
|
||||
return LocalDeliveryStatusDict::RIDER_ARRIVED;// 骑士到店
|
||||
case self::IN_DELIVERY:
|
||||
return LocalDeliveryStatusDict::IN_DELIVERY;// 配送中
|
||||
case self::COMPLETED:
|
||||
return LocalDeliveryStatusDict::COMPLETED;// 已完成
|
||||
case self::CANCELED:
|
||||
return LocalDeliveryStatusDict::CANCELED;// 已取消
|
||||
case self::DISPATCH_ORDER:
|
||||
return LocalDeliveryStatusDict::DISPATCH_ORDER;// 指派单(已追加待接单)
|
||||
case self::RETURN_IN_PROGRESS:
|
||||
return LocalDeliveryStatusDict::RETURN_IN_PROGRESS;// 妥投异常之物品返回中
|
||||
case self::RETURN_COMPLETED:
|
||||
return LocalDeliveryStatusDict::RETURN_COMPLETED;// 妥投异常之物品返回完成
|
||||
case self::RETURN_RIDER_ARRIVED:
|
||||
return LocalDeliveryStatusDict::RETURN_RIDER_ARRIVED;// 售后取件单送达门店
|
||||
case self::CREATE_ORDER_FAILED:
|
||||
return LocalDeliveryStatusDict::CREATE_ORDER_FAILED;// 创建运单失败
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
{"1":"食品小吃","2":"饮料","3":"鲜花绿植","5":"其他","8":"文印票务","9":"便利店","13":"水果生鲜","19":"同城电商","20":"医药","21":"蛋糕","24":"酒品","25":"小商品市场","26":"服装","27":"汽修零配","28":"数码家电","29":"小龙虾/烧烤","31":"超市","51":"火锅","53":"个护美妆","55":"母婴","57":"家居家纺","59":"手机","61":"家装","63":"成人用品","65":"校园","66":"高端市场"}
|
||||
@ -111,5 +111,24 @@ return [
|
||||
//是否累增
|
||||
'is_change_get' => 1,
|
||||
]
|
||||
],
|
||||
//成长值
|
||||
MemberAccountTypeDict::GROWTH => [
|
||||
'shop_buy_goods' => [
|
||||
//名称
|
||||
'name' => '购买产品',
|
||||
//是否增加
|
||||
'inc' => 1,
|
||||
//是否减少
|
||||
'dec' => 0,
|
||||
],
|
||||
'shop_buy_order' => [
|
||||
//名称
|
||||
'name' => '完成下单',
|
||||
//是否增加
|
||||
'inc' => 1,
|
||||
//是否减少
|
||||
'dec' => 0,
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\shop_delivery;
|
||||
|
||||
/**
|
||||
* 商家配送配送枚举类
|
||||
* Class LocalDeliveryDict
|
||||
* @package app\dict\sys
|
||||
*/
|
||||
class ShopDeliveryDict
|
||||
{
|
||||
//商家配送
|
||||
const MERCHANT = 'merchant';
|
||||
|
||||
public static function getType()
|
||||
{
|
||||
$system = [
|
||||
self::MERCHANT => [
|
||||
'name' => '商家配送',
|
||||
'key' => self::MERCHANT,
|
||||
//配置参数
|
||||
'params' => [],
|
||||
'component' => '',
|
||||
'business_list' => '',
|
||||
'extend_data' => [],
|
||||
//商家配送标识
|
||||
'is_merchant' => 1
|
||||
],
|
||||
];
|
||||
return $system;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\dict\shop_delivery;
|
||||
|
||||
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryStatusDict;
|
||||
|
||||
/**
|
||||
*同城三方配送相关枚举类
|
||||
*/
|
||||
class ShopDeliveryStatusDict
|
||||
{
|
||||
// 订单状态常量定义
|
||||
const IN_DELIVERY = 4; // 配送中
|
||||
const COMPLETED = 5; // 已完成
|
||||
const CANCELED = -2; // 已取消
|
||||
|
||||
/**
|
||||
* 获取商家配送订单状态映射
|
||||
* @return array
|
||||
*/
|
||||
public static function getStatus()
|
||||
{
|
||||
return [
|
||||
self::IN_DELIVERY => get_lang('dict_shop_local_delivery_status.in_delivery'), //配送中,
|
||||
self::COMPLETED => get_lang('dict_shop_local_delivery_status.completed'), //已完成,
|
||||
self::CANCELED => get_lang('dict_shop_local_delivery_status.canceled'), //已取消,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转换配送状态
|
||||
* @param $status
|
||||
* @return int
|
||||
*/
|
||||
public static function convertStatus($status)
|
||||
{
|
||||
switch ($status) {
|
||||
case self::IN_DELIVERY:
|
||||
return LocalDeliveryStatusDict::IN_DELIVERY;// 配送中
|
||||
case self::COMPLETED:
|
||||
return LocalDeliveryStatusDict::COMPLETED;//已完成
|
||||
case self::CANCELED:
|
||||
return LocalDeliveryStatusDict::CANCELED;//已取消
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -188,6 +188,21 @@ return [
|
||||
|
||||
//获取商品配送费用
|
||||
'ThirdAddonOrderDelivery' => ['addon\shop\app\listener\third_addon\order\OrderDeliveryServiceListener'],
|
||||
|
||||
/***************************************************** 同城配送 start *****************************************************/
|
||||
//配送方式
|
||||
'LocalDeliveryType' => ['addon\shop\app\listener\local_delivery\dada\local_delivery_type\LocalDeliveryTypeListener'],
|
||||
//订单取消原因
|
||||
'OrderCancelReason' => ['addon\shop\app\listener\local_delivery\dada\order\OrderCancelReasonListener'],
|
||||
//配送订单操作前置状态
|
||||
'DeliveryOrderPreStatus' => [
|
||||
'addon\shop\app\listener\local_delivery\dada\order\OrderPreStatusListener',
|
||||
'addon\shop\app\listener\shop_delivery\OrderPreStatusListener'
|
||||
],
|
||||
//获取同城配送轨迹
|
||||
'GetLocalDeliveryTrack' => ['addon\shop\app\listener\local_delivery\dada\order\GetLocalDeliveryTrack'],
|
||||
|
||||
/***************************************************** 同城配送 end *****************************************************/
|
||||
],
|
||||
'subscribe' => [
|
||||
],
|
||||
|
||||
27
niucloud/addon/shop/app/job/delivery/DeliveryShopEditJob.php
Normal file
27
niucloud/addon/shop/app/job/delivery/DeliveryShopEditJob.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\job\delivery;
|
||||
|
||||
use addon\shop\app\service\core\delivery_store\CoreDeliveryServiceService;
|
||||
use core\base\BaseJob;
|
||||
|
||||
/**
|
||||
* 门店批量修改
|
||||
*/
|
||||
class DeliveryShopEditJob extends BaseJob
|
||||
{
|
||||
public function doJob($id)
|
||||
{
|
||||
(new CoreDeliveryServiceService())->batchDeliveryShopEdit($id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -13,10 +13,7 @@ return [
|
||||
'SHOP_GOODS_LABEL_NAME_REPEAT'=>'标签名称重复',
|
||||
'SHOP_GOODS_LABEL_IN_USE'=>'该标签正在使用中',
|
||||
'NOT_SUPPORT_DELIVERY_TYPE' => '不支持选择的配送方式',
|
||||
'NOT_SUPPORT_DELIVERY_ADDRESS' => '所选的收货地址不支持配送',
|
||||
'NOT_SELECT_ADDRESS' => '需要先选择收货地址',
|
||||
'NOT_SELECT_STORE' => '请选择自提点',
|
||||
'NOT_NEED_DELIVERY_START_PRICE' => '未达到起送费用',
|
||||
'EXIST_ORDER_NOT_DELETE_GOODS' => '存在未完成的订单,无法删除商品',
|
||||
'EXIST_ORDER_NOT_EDIT_GOODS' => '存在未完成的订单,无法编辑商品',
|
||||
'COUPON_STOCK_INSUFFICIENT' => '优惠券已领完',
|
||||
@ -29,6 +26,7 @@ return [
|
||||
'COUPON_RECEIVE_SUCCESS' => '领取成功',
|
||||
'MEMBER_ALREADY_COLLECT' => '已收藏,不可重复收藏',
|
||||
'CANCEL_COLLECT_SUCCESS' => '取消收藏成功',
|
||||
'CANCEL_SUCCESS' => '取消成功',
|
||||
|
||||
'SHOP_COUPON_IS_USED_OR_EXIST' => '优惠券不存在或已使用',
|
||||
'SHOP_COUPON_VALID_END_TIME_NOT_ALLOW_LT_START_TIME' => '优惠券的有效期结束时间不能小于当前时间',
|
||||
@ -50,7 +48,6 @@ return [
|
||||
'SHOP_VIRTUAL_ORDERS_EDIT_TAKER' => '虚拟商品订单不可以修改配送地址',
|
||||
'EXPRESS_FIELD_EMPTY' => '地址信息有误',
|
||||
'GOODS_NOT_DELIVERY_TYPE' => '当前商品不支持该配送方式',
|
||||
'DELIVERY_TYPE_NOT_OPEN' => '商家未开启该配送方式',
|
||||
|
||||
'SHOP_THE_ITEM_IS_BEING_REFUNDED_OR_HAS_BEEN_REFUNDED' => '当前商品项存在退款',
|
||||
|
||||
@ -193,4 +190,36 @@ return [
|
||||
'DISCOUNT_IS_ENABLED_NOT_EMPTY' => 'is_enabled必传',
|
||||
/********************************************* 限时折扣end ****************************************************/
|
||||
|
||||
/************************************************************ 配送相关 *********************************************/
|
||||
'DELIVERY_SUCCESS' => '发货成功',
|
||||
'EXPRESS_COMPANY_NOT_EXIST' => '物流公司不存在',
|
||||
'NOT_SUPPORT_DELIVERY_ADDRESS' => '所选的收货地址不支持配送',
|
||||
'NOT_SELECT_ADDRESS' => '需要先选择收货地址',
|
||||
'NOT_SELECT_PICK_UP_STORE' => '请选择提货点',
|
||||
'NOT_SELECT_LOCAL_DELIVERY_STORE' => '请选择配送门店',
|
||||
'NOT_NEED_DELIVERY_START_PRICE' => '未达到起送费用',
|
||||
'LOCAL_DELIVERY_ORDER_EXIST' => '该订单已存在正在进行中的配送订单',
|
||||
'ELECTRONIC_SHEET_API_EMPTY' => '未配置电子面单接口',
|
||||
'ELECTRONIC_SHEET_TEMPLATE_FOUND' => '电子面单模板不存在',
|
||||
'LOCAL_DELIVERY_TYPE_NOT_EXIST' => '配送服务商类型不存在',
|
||||
'LOCAL_DELIVERY_OPEN_AT_LEAST_ONE_LOCAL_DELIVERY_STORE' => '同城配送已开启,至少需保留一个提货类型包含同城配送的提货点',
|
||||
'STORE_OPEN_AT_LEAST_ONE_PICK_UP_STORE' => '门店自提已开启,至少需保留一个提货类型包含门店自提的提货点',
|
||||
'LOCAL_DELIVERY_NOT_SET' => '同城配送未配置,请先完成配置',
|
||||
'NOT_SET_LOCAL_DELIVERY_STORE' => '未配置配送门店',
|
||||
'NOT_SET_PICK_UP_STORE' => '未配置提货点',
|
||||
'DELIVERY_ORDER_NOT_EXIT' => '配送订单不存在',
|
||||
'DELIVERY_SERVICE_NOT_SELECT' => '请选择配送平台',
|
||||
'DELIVERY_STORE_NOT_EXIST' => '提货点不存在',
|
||||
'DELIVERY_TYPE_NOT_OPEN' => '商家未开启该配送方式',
|
||||
'GOODS_NOT_SUPPORT_LOCAL_DELIVERY' => '该商品不支持同城配送',
|
||||
'GOODS_NOT_SUPPORT_EXPRESS' => '该商品不支持物流配送',
|
||||
'GOODS_NOT_SUPPORT_STORE' => '该商品不支持门店自提',
|
||||
'NOT_SUPPORT_DELIVERY_RANGE' => '不在配送范围内',
|
||||
'SHOP_NOT_SET_LOCAL_DELIVERY_STORE' => '商家未设置配送门店',
|
||||
'SHOP_NOT_SET_PICK_UP_STORE' => '商家未设置提货点',
|
||||
'STORE_NOT_SET_DELIVERY_RANGE' => '该门店未设置配送范围',
|
||||
'STORE_NOT_SUPPORT_LOCAL_DELIVERY' => '该门店不支持同城配送',
|
||||
'STORE_NOT_SUPPORT_PICK_UP' => '该门店不支持门店自提',
|
||||
'DELIVERY_WEAPP_SHIPPING_NOT_FOUND' => '小程序发货信息不存在',
|
||||
|
||||
];
|
||||
@ -37,6 +37,54 @@ return [
|
||||
'90' => '90分钟',
|
||||
'120' => '2小时',
|
||||
],
|
||||
'dict_shop_delivery_store_pick_up_type' => [
|
||||
'local_delivery' => '同城配送',
|
||||
'store' => '门店自提',
|
||||
],
|
||||
'dict_shop_local_delivery_status' => [
|
||||
'wait_release' => '预约待发布',
|
||||
'order_accepted' => '商家已接单',
|
||||
'pending_acceptance' => '待接单',
|
||||
'pending_pickup' => '待取货',
|
||||
'rider_arrived' => '骑士到店',
|
||||
'in_delivery' => '配送中',
|
||||
'completed' => '已完成',
|
||||
'dispatch_order' => '指派单',
|
||||
'return_in_progress' => '妥投异常之物品返回中',
|
||||
'return_completed' => '妥投异常之物品返回完成',
|
||||
'return_rider_arrived' => '售后取件单送达门店',
|
||||
'create_order_failed' => '创建运单失败',
|
||||
'canceled' => '已取消',
|
||||
],
|
||||
'dict_shop_local_delivery_order_log' => [
|
||||
'store' => '商家',
|
||||
'rider' => '骑手',
|
||||
'member' => '会员',
|
||||
'system' => '系统',
|
||||
|
||||
'order_accepted' => '商家已接单',
|
||||
'order_call' => '商家呼叫配送',
|
||||
'dispatch_order' => '商家指派骑手',
|
||||
'rider_accepted' => '骑手已接单',
|
||||
'rider_arrived' => '骑手已到店',
|
||||
'rider_picked_up' => '骑手已取货',
|
||||
'order_delivered' => '订单已送达',
|
||||
'order_canceled' => '订单已取消',
|
||||
'return_applied' => '物品返回申请',
|
||||
'return_completed' => '物品返回完成',
|
||||
],
|
||||
'dict_shop_local_delivery_order_cancel' => [
|
||||
'no_rider' => '没有配送员接单',
|
||||
'no_rider_pickup' => '配送员没来取货',
|
||||
'rider_bad_attitude' => '配送员态度太差',
|
||||
'customer_cancel' => '顾客取消订单',
|
||||
'order_write_error' => '订单填写错误',
|
||||
'rider_cancel' => '配送员让我取消此单',
|
||||
'rider_unwill' => '配送员不愿上门取货',
|
||||
'rider_unnecessary' => '我不需要配送了',
|
||||
'rider_cannot_complete' => '配送员以各种理由表示无法完成订单',
|
||||
'other_reason' => '其他',
|
||||
],
|
||||
|
||||
'dict_shop_coupon' => [
|
||||
'user' => '手动领取',
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\listener\local_delivery\dada\local_delivery_type;
|
||||
|
||||
/**
|
||||
* 配送服务商-达达秒送
|
||||
* @package addon\shop\app\listener\local_delivery\dada\local_delivery_type
|
||||
*/
|
||||
class LocalDeliveryTypeListener
|
||||
{
|
||||
|
||||
public function handle($params)
|
||||
{
|
||||
return [
|
||||
'dada' => [
|
||||
'name' => '达达秒送',
|
||||
'key' => 'dada',
|
||||
//配置参数
|
||||
'params' => [
|
||||
'app_key' => 'APP_KEY',
|
||||
'app_secret' => 'APP_SECRET',
|
||||
'source_id' => '商户SourceID',
|
||||
'shop_no' => '门店编号',
|
||||
],
|
||||
'encrypt_params' => ['app_key', 'app_secret', 'source_id', 'shop_no'],
|
||||
'component' => '/src/addon/shop/views/delivery/components/local-delivery-service-dada.vue',
|
||||
'business_list' => json_decode(file_get_contents(root_path() . '/addon/shop/app/dict/local_delivery/dada/json/shop_catetory_dict.json'), true),
|
||||
'extend_data' => [],
|
||||
//商家配送标识
|
||||
'is_merchant' => 0
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\listener\local_delivery\dada\order;
|
||||
|
||||
use addon\shop\app\dict\local_delivery\dada\DadaDeliveryDict;
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryStatusDict;
|
||||
use addon\shop\app\service\core\local_delivery\CoreLocalDeliveryService;
|
||||
use addon\shop\core\local_delivery\LocalDeliveryLoader;
|
||||
use app\model\member\Member;
|
||||
use core\exception\CommonException;
|
||||
|
||||
/**
|
||||
* 查询配送订单的起始点和终点
|
||||
* Class GetLocalDeliveryTrack
|
||||
* @package addon\shop\app\listener\local_delivery\dada\order
|
||||
*/
|
||||
class GetLocalDeliveryTrack
|
||||
{
|
||||
|
||||
public function handle($params)
|
||||
{
|
||||
$status = $params['status'];
|
||||
$member_id = $params['member_id'];
|
||||
$delivery_no = $params['delivery_no'];
|
||||
$delivery_service = $params['delivery_service'];
|
||||
|
||||
if ($delivery_service == DadaDeliveryDict::DADA) {
|
||||
$member_info = (new Member())->where([['member_id', '=', $member_id]])->findOrEmpty()->toArray();
|
||||
if (empty($member_info)) throw new CommonException('MEMBER_NOT_EXIST');
|
||||
$headimg = empty($member_info['headimg']) ? 'static/resource/images/default_headimg.png' : $member_info['headimg'];
|
||||
|
||||
if (in_array($status, [LocalDeliveryStatusDict::PENDING_PICKUP, LocalDeliveryStatusDict::IN_DELIVERY])) {
|
||||
$config = (new CoreLocalDeliveryService())->getConfig($delivery_service);
|
||||
$loader = new LocalDeliveryLoader($delivery_service, $config);
|
||||
$data = [
|
||||
'delivery_no' => $delivery_no,
|
||||
];
|
||||
$response_data = $loader->getTransporterPosition($data);
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case LocalDeliveryStatusDict::ORDER_ACCEPTED:
|
||||
case LocalDeliveryStatusDict::PENDING_ACCEPTANCE:
|
||||
return [
|
||||
[
|
||||
'points_type' => 'shop',
|
||||
'latitude' => $params['delivery_start_lat'],
|
||||
'longitude' => $params['delivery_start_lng'],
|
||||
'icon_path' => 'addon/shop/local_delivery/in_stock.png',
|
||||
'callout' => [
|
||||
'content' => '备货中',
|
||||
],
|
||||
],
|
||||
[
|
||||
'points_type' => 'member',
|
||||
'latitude' => $params['delivery_end_lat'],
|
||||
'longitude' => $params['delivery_end_lng'],
|
||||
'icon_path' => $headimg,
|
||||
'callout' => [
|
||||
'content' => '',
|
||||
],
|
||||
]
|
||||
];
|
||||
case LocalDeliveryStatusDict::PENDING_PICKUP:
|
||||
if (!empty($response_data['rider_latitude']) && !empty($response_data['rider_longitude'])) {
|
||||
return [
|
||||
[
|
||||
'points_type' => 'rider',
|
||||
'latitude' => $response_data['rider_latitude'],
|
||||
'longitude' => $response_data['rider_longitude'],
|
||||
'icon_path' => 'addon/shop/local_delivery/in_delivery.png',
|
||||
'callout' => [
|
||||
'content' => '骑手正赶往商家',
|
||||
],
|
||||
],
|
||||
[
|
||||
'points_type' => 'shop',
|
||||
'latitude' => $params['delivery_start_lat'],
|
||||
'longitude' => $params['delivery_start_lng'],
|
||||
'icon_path' => 'addon/shop/local_delivery/in_stock.png',
|
||||
'callout' => [
|
||||
'content' => '',
|
||||
],
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
[
|
||||
'points_type' => 'shop',
|
||||
'latitude' => $params['delivery_start_lat'],
|
||||
'longitude' => $params['delivery_start_lng'],
|
||||
'icon_path' => 'addon/shop/local_delivery/in_stock.png',
|
||||
'callout' => [
|
||||
'content' => '骑手正赶往商家',
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
case LocalDeliveryStatusDict::RIDER_ARRIVED:
|
||||
return [
|
||||
[
|
||||
'points_type' => 'rider_arrived',
|
||||
'latitude' => $params['delivery_start_lat'],
|
||||
'longitude' => $params['delivery_start_lng'],
|
||||
'icon_path' => 'addon/shop/local_delivery/picking_up.png',
|
||||
'callout' => [
|
||||
'content' => '骑手到店取餐中',
|
||||
],
|
||||
],
|
||||
[
|
||||
'points_type' => 'member',
|
||||
'latitude' => $params['delivery_end_lat'],
|
||||
'longitude' => $params['delivery_end_lng'],
|
||||
'icon_path' => $headimg,
|
||||
'callout' => [
|
||||
'content' => '',
|
||||
],
|
||||
]
|
||||
];
|
||||
case LocalDeliveryStatusDict::IN_DELIVERY:
|
||||
return [
|
||||
[
|
||||
'points_type' => 'rider',
|
||||
'latitude' => $response_data['rider_latitude'] ?? $params['delivery_start_lat'],
|
||||
'longitude' => $response_data['rider_longitude'] ?? $params['delivery_start_lng'],
|
||||
'icon_path' => 'addon/shop/local_delivery/in_delivery.png',
|
||||
'callout' => [
|
||||
'content' => '骑手正在送餐',
|
||||
],
|
||||
],
|
||||
[
|
||||
'points_type' => 'member',
|
||||
'latitude' => $params['delivery_end_lat'],
|
||||
'longitude' => $params['delivery_end_lng'],
|
||||
'icon_path' => $headimg,
|
||||
'callout' => [
|
||||
'content' => '',
|
||||
],
|
||||
]
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\listener\local_delivery\dada\order;
|
||||
|
||||
|
||||
use addon\shop\app\dict\local_delivery\dada\DadaDeliveryDict;
|
||||
|
||||
/**
|
||||
* 支付方式
|
||||
* @package addon\mall\app\listener\diy
|
||||
*/
|
||||
class OrderCancelReasonListener
|
||||
{
|
||||
|
||||
public function handle($params)
|
||||
{
|
||||
// dada 订单取消原因
|
||||
if (!empty($params['service']) && $params['service'] == DadaDeliveryDict::DADA) {
|
||||
return [
|
||||
1 => get_lang('dict_shop_local_delivery_order_cancel.no_rider'), //没有配送员接单,
|
||||
2 => get_lang('dict_shop_local_delivery_order_cancel.no_rider_pickup'), //配送员没来取货,
|
||||
3 => get_lang('dict_shop_local_delivery_order_cancel.rider_bad_attitude'), //配送员态度太差,
|
||||
4 => get_lang('dict_shop_local_delivery_order_cancel.customer_cancel'), //顾客取消订单,
|
||||
5 => get_lang('dict_shop_local_delivery_order_cancel.order_write_error'), //订单填写错误,
|
||||
34 => get_lang('dict_shop_local_delivery_order_cancel.rider_cancel'), //配送员让我取消此单,
|
||||
35 => get_lang('dict_shop_local_delivery_order_cancel.rider_unwill'), //配送员不愿上门取货,
|
||||
36 => get_lang('dict_shop_local_delivery_order_cancel.rider_unnecessary'), //我不需要配送了,
|
||||
37 => get_lang('dict_shop_local_delivery_order_cancel.rider_cannot_complete'), //配送员以各种理由表示无法完成订单,
|
||||
10000 => get_lang('dict_shop_local_delivery_order_cancel.other_reason'), //其他,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\listener\local_delivery\dada\order;
|
||||
|
||||
use addon\shop\app\dict\local_delivery\dada\DadaDeliveryDict;
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryStatusDict;
|
||||
|
||||
/**
|
||||
* 配送订单操作前置状态
|
||||
* @package addon\b2b2c_dada\app\listener\order
|
||||
*/
|
||||
class OrderPreStatusListener
|
||||
{
|
||||
|
||||
public function handle($params)
|
||||
{
|
||||
if (!empty($params['service']) && $params['service'] == DadaDeliveryDict::DADA) {
|
||||
return [
|
||||
'cancel' => [
|
||||
LocalDeliveryStatusDict::WAIT_RELEASE,
|
||||
LocalDeliveryStatusDict::PENDING_ACCEPTANCE,
|
||||
LocalDeliveryStatusDict::PENDING_PICKUP,
|
||||
LocalDeliveryStatusDict::RIDER_ARRIVED,
|
||||
], //取消订单
|
||||
'sync' => [
|
||||
LocalDeliveryStatusDict::ORDER_ACCEPTED,
|
||||
LocalDeliveryStatusDict::PENDING_ACCEPTANCE,
|
||||
LocalDeliveryStatusDict::PENDING_PICKUP,
|
||||
LocalDeliveryStatusDict::RIDER_ARRIVED,
|
||||
LocalDeliveryStatusDict::IN_DELIVERY,
|
||||
LocalDeliveryStatusDict::COMPLETED,
|
||||
LocalDeliveryStatusDict::DISPATCH_ORDER,
|
||||
LocalDeliveryStatusDict::RETURN_IN_PROGRESS,
|
||||
LocalDeliveryStatusDict::RETURN_COMPLETED,
|
||||
LocalDeliveryStatusDict::RETURN_RIDER_ARRIVED,
|
||||
LocalDeliveryStatusDict::CREATE_ORDER_FAILED,
|
||||
LocalDeliveryStatusDict::CANCELED,
|
||||
], //同步订单
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,19 +18,20 @@ class OrderDelivery extends BaseNoticeTemplate
|
||||
if ($this->key == $params['key']) {
|
||||
$order = (new CoreOrderService())->getInfo($params['data']['order_id']);
|
||||
if (!empty($order)) {
|
||||
$order_data = $params['data'];
|
||||
$wap_domain = get_wap_domain();
|
||||
return $this->toReturn(
|
||||
[
|
||||
'__wechat_page' => $wap_domain . '/addon/shop/pages/order/detail?order_id=' . $order['order_id'],//模板消息链接
|
||||
'__weapp_page' => 'addon/shop/pages/order/detail?order_id=' . $order['order_id'],//小程序链接
|
||||
'body' => str_sub($order['body']),
|
||||
'order_no' => $order['order_no'],
|
||||
'delivery_time' => $order['delivery_time'],
|
||||
'order_money' => $order['order_money'],
|
||||
'url' => $wap_domain . '/addon/shop/pages/order/detail?order_id=' . $order['order_id']
|
||||
'__wechat_page' => $wap_domain . '/addon/shop/pages/order/detail?order_id=' . $order_data['order_id'],//模板消息链接
|
||||
'__weapp_page' => 'addon/shop/pages/order/detail?order_id=' . $order_data['order_id'],//小程序链接
|
||||
'body' => str_sub($order_data['body']),
|
||||
'order_no' => $order_data['order_no'],
|
||||
'delivery_time' => $order_data['delivery_time'],
|
||||
'order_money' => $order_data['order_money'],
|
||||
'url' => $wap_domain . '/addon/shop/pages/order/detail?order_id=' . $order_data['order_id']
|
||||
],
|
||||
[
|
||||
'member_id' => $order['member_id']
|
||||
'member_id' => $order_data['member_id']
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@ -32,13 +32,17 @@ class AfterShopOrderClose
|
||||
$order_discount_where = array(
|
||||
['order_id', '=', $order_data['order_id']]
|
||||
);
|
||||
|
||||
$order_discount = (new OrderDiscounts())->where($order_discount_where)->select();
|
||||
|
||||
if (!$order_discount->isEmpty()) {
|
||||
$recover_list = [];
|
||||
foreach ($order_discount as $v) {
|
||||
$item_discount_type = $v['discount_type'];
|
||||
$recover_list[$item_discount_type][] = $v['discount_type_id'];
|
||||
|
||||
}
|
||||
|
||||
foreach ($recover_list as $item_discount_type => $discount_type_ids) {
|
||||
switch ($item_discount_type) {
|
||||
case 'coupon'://优惠券
|
||||
@ -52,6 +56,7 @@ class AfterShopOrderClose
|
||||
['is_gift', '=', 0],
|
||||
);
|
||||
$order_goods_data = (new OrderGoods())->where($order_goods_where)->select()->toArray();
|
||||
|
||||
//返还商品库存
|
||||
$core_goods_stock_service = new CoreGoodsStockService();
|
||||
$inc_data = [];
|
||||
|
||||
@ -36,7 +36,7 @@ class AfterShopOrderDelivery
|
||||
|
||||
//消息发送
|
||||
if ($order_data[ 'status' ] == OrderDict::WAIT_TAKE) {
|
||||
( new NoticeService() )->send('shop_order_delivery', [ 'order_id' => $order_data[ 'order_id' ] ]);
|
||||
( new NoticeService() )->send('shop_order_delivery', $order_data);
|
||||
}
|
||||
|
||||
//写入定时收货任务
|
||||
|
||||
@ -53,8 +53,8 @@ class AfterShopOrderFinish
|
||||
}
|
||||
|
||||
// 订单完成发放积分成长值
|
||||
CoreMemberService::sendGrowth($order_data[ 'member_id' ], 'shop_buy_goods', $order_data);
|
||||
CoreMemberService::sendGrowth($order_data[ 'member_id' ], 'shop_buy_order');
|
||||
CoreMemberService::sendGrowth($order_data[ 'member_id' ], 'shop_buy_goods', array_merge($order_data, [ 'from_type' => 'shop_buy_goods', 'related_id' => $order_data[ 'order_id' ] ]));
|
||||
CoreMemberService::sendGrowth($order_data[ 'member_id' ], 'shop_buy_order',['from_type'=>'shop_buy_order','related_id'=>$order_data[ 'order_id' ] ]);
|
||||
CoreMemberService::sendPoint($order_data[ 'member_id' ], 'shop_buy_goods', array_merge($order_data, [ 'from_type' => 'consume_reward', 'related_id' => $order_data[ 'order_id' ] ]));
|
||||
|
||||
// 微信小程序 发送 确认收货提醒消息
|
||||
|
||||
@ -14,7 +14,9 @@ namespace addon\shop\app\listener\order_export;
|
||||
use addon\shop\app\dict\order\InvoiceDict;
|
||||
use addon\shop\app\model\order\Order;
|
||||
use addon\shop\app\model\order\OrderGoods;
|
||||
use app\dict\pay\PayDict;
|
||||
use think\db\Query;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 订单导出数据源查询
|
||||
@ -31,15 +33,35 @@ class ShopOrderExportDataListener
|
||||
$model = new Order();
|
||||
$orderGoodsModel = new OrderGoods();
|
||||
$pay_where = [];
|
||||
if ($param[ 'where' ][ 'pay_type' ]) {
|
||||
$pay_where[] = [ 'pay.type', '=', $param[ 'where' ][ 'pay_type' ] ];
|
||||
|
||||
if ($param[ 'where' ]['pay_type']) {
|
||||
if ($param[ 'where' ]['pay_type'] == PayDict::FRIENDSPAY) {
|
||||
$pay_where = [
|
||||
['pay.main_id', '<>', Db::raw("pay.from_main_id")],
|
||||
['pay.from_main_id', '>', 0],
|
||||
['pay.status', '=', PayDict::STATUS_FINISH]
|
||||
];
|
||||
} else {
|
||||
$pay_where[] = ['pay.type', '=', $param[ 'where' ]['pay_type']];
|
||||
}
|
||||
}
|
||||
$member_where = [];
|
||||
if ($param['where']['keyword'] != '') {
|
||||
$member_where = [
|
||||
['member.member_no|member.nickname|member.username|member.mobile', 'like', "%" . $param[ 'where' ]['keyword'] . "%"],
|
||||
];
|
||||
}
|
||||
//查询导出订单项数据
|
||||
$order_ids = $model->where([ [ 'order.order_id', '>', 0 ] ])->withSearch([ 'search_type', 'order_from', 'join_status', 'create_time', 'join_pay_time' ], $param[ 'where' ])
|
||||
$order_ids = $model->where([ [ 'order.order_id', '>', 0 ] ])
|
||||
->withSearch([ 'search_type', 'order_from', 'join_status', 'create_time', 'join_pay_time' ], $param[ 'where' ])
|
||||
->withJoin([
|
||||
'pay' => function(Query $query) use ($pay_where) {
|
||||
$query->where($pay_where);
|
||||
} ], 'left')
|
||||
},
|
||||
'member' => function (Query $query) use ($member_where) {
|
||||
$query->where($member_where);
|
||||
},
|
||||
], 'left')
|
||||
->field('order_id')->order('order.create_time desc')->column('order_id');
|
||||
|
||||
$order_goods_field = 'extend,order_goods_id,order_id,member_id,goods_id,sku_id,delivery_id,goods_name,sku_name,goods_image,sku_image,price,num,goods_money,is_enable_refund,goods_type,delivery_status,status';
|
||||
@ -56,7 +78,6 @@ class ShopOrderExportDataListener
|
||||
$data = $search_model->select()->toArray();
|
||||
}
|
||||
|
||||
$is_first = true;
|
||||
$encountered = array();
|
||||
foreach ($data as $key => $val) {
|
||||
|
||||
|
||||
@ -13,7 +13,9 @@ namespace addon\shop\app\listener\order_export;
|
||||
|
||||
use addon\shop\app\model\order\Order;
|
||||
use addon\shop\app\model\order\OrderGoods;
|
||||
use app\dict\pay\PayDict;
|
||||
use think\db\Query;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 订单项导出数据源查询
|
||||
@ -31,16 +33,36 @@ class ShopOrderGoodsExportDataListener
|
||||
$orderGoodsModel = new OrderGoods();
|
||||
$order = 'order.create_time desc';
|
||||
$pay_where = [];
|
||||
if($param['where'][ 'pay_type' ]){
|
||||
$pay_where[] = ['pay.type', '=', $param['where'][ 'pay_type' ] ];
|
||||
|
||||
if ($param[ 'where' ]['pay_type']) {
|
||||
if ($param[ 'where' ]['pay_type'] == PayDict::FRIENDSPAY) {
|
||||
$pay_where = [
|
||||
['pay.main_id', '<>', Db::raw("pay.from_main_id")],
|
||||
['pay.from_main_id', '>', 0],
|
||||
['pay.status', '=', PayDict::STATUS_FINISH]
|
||||
];
|
||||
} else {
|
||||
$pay_where[] = ['pay.type', '=', $param[ 'where' ]['pay_type']];
|
||||
}
|
||||
}
|
||||
$member_where = [];
|
||||
if ($param['where']['keyword'] != '') {
|
||||
$member_where = [
|
||||
['member.member_no|member.nickname|member.username|member.mobile', 'like', "%" . $param[ 'where' ]['keyword'] . "%"],
|
||||
];
|
||||
}
|
||||
//查询导出订单项数据
|
||||
$order_ids = $model->where([[ 'order.order_id', '>', 0 ]])->withSearch([ 'search_type', 'order_from', 'join_status', 'create_time', 'join_pay_time' ], $param['where'])
|
||||
$order_ids = $model->where([ [ 'order.order_id', '>', 0 ] ])
|
||||
->withSearch([ 'search_type', 'order_from', 'join_status', 'create_time', 'join_pay_time' ], $param[ 'where' ])
|
||||
->withJoin([
|
||||
'pay' => function(Query $query) use($pay_where){
|
||||
'pay' => function(Query $query) use ($pay_where) {
|
||||
$query->where($pay_where);
|
||||
}], 'left')
|
||||
->field('order_id')->order($order)->column('order_id');
|
||||
},
|
||||
'member' => function (Query $query) use ($member_where) {
|
||||
$query->where($member_where);
|
||||
},
|
||||
], 'left')
|
||||
->field('order_id')->order('order.create_time desc')->column('order_id');
|
||||
|
||||
$order_goods_field = 'order_goods_id,order_id,member_id,delivery_id,goods_name,sku_name,price,num,goods_money,discount_money,order_refund_no,order_goods_money,goods_type,delivery_status,status';
|
||||
$order_field = 'order_id,order_no,order_from,taker_name,taker_mobile,taker_full_address,create_time,pay_time,delivery_money,delivery_type,delivery_time,finish_time,member_remark,shop_remark,out_trade_no,status';
|
||||
|
||||
@ -60,8 +60,9 @@ class AfterShopOrderClose
|
||||
'total_point_num' => Db::raw('total_point_num-' . $order_data['point']),
|
||||
'total_price_num' => Db::raw('total_price_num-' . $v['goods_money']),
|
||||
'total_order_num' => Db::raw('total_order_num-1'),
|
||||
'goods_id' => $v['goods_id'],
|
||||
'sku_id' => $v['sku_id'],
|
||||
'update_time'=>time(),
|
||||
// 'goods_id' => $v['goods_id'],
|
||||
// 'sku_id' => $v['sku_id'],
|
||||
'id' => $order_data['relate_id'],
|
||||
];
|
||||
|
||||
|
||||
@ -58,8 +58,9 @@ class AfterShopOrderCreate
|
||||
'total_point_num' => Db::raw('total_point_num+' . $order_data['point']),
|
||||
'total_price_num' => Db::raw('total_price_num+' . $v['goods_money']),
|
||||
'total_order_num' => Db::raw('total_order_num+1'),
|
||||
'goods_id' => $v['goods_id'],
|
||||
'sku_id' => $v['sku_id'],
|
||||
'update_time' => time(),
|
||||
// 'goods_id' => $v['goods_id'],
|
||||
// 'sku_id' => $v['sku_id'],
|
||||
'id' => $order_data['relate_id'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -114,7 +114,8 @@ class ShopPoster
|
||||
])->findOrEmpty()->toArray();
|
||||
|
||||
if (!empty($newcomer_goods_info) && $newcomer_goods_info[ 'active' ][ 'active_status' ] == ActiveDict::ACTIVE) {
|
||||
$url_data[] = [ 'key' => 'type', 'value' => 'newcomer_discount' ];
|
||||
// $url_data[] = [ 'key' => 'type', 'value' => 'newcomer_discount' ];
|
||||
$url_data[] = [ 'key' => 'type', 'value' => 'nd' ];
|
||||
$newcomer_price = json_decode($newcomer_goods_info[ 'active_goods_value' ], true)[ 'newcomer_price' ];
|
||||
if ($newcomer_price > 0) $show_price_data[] = $newcomer_price;
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ class AfterShopOrderRefundFinish
|
||||
if ($order[ 'status' ] == OrderDict::WAIT_DELIVERY) {
|
||||
//校验一下订单项是否全部发货
|
||||
( new CoreOrderDeliveryService() )->checkFinish(
|
||||
[ 'order_id' => $refund_data[ 'order_id' ]]
|
||||
[ 'order_id' => $refund_data[ 'order_id' ] ]
|
||||
);
|
||||
}
|
||||
//校验一下是否全部退款
|
||||
@ -58,7 +58,8 @@ class AfterShopOrderRefundFinish
|
||||
'main_type' => $main_type,
|
||||
'main_id' => $main_id,
|
||||
'type' => OrderRefundDict::FINISH_ACTION,
|
||||
'content' => ''
|
||||
'content' => '',
|
||||
'create_time'=>time()+1
|
||||
]);
|
||||
//消息发送
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ class ShopOrderRefundExportDataListener
|
||||
$data = $search_model->select()->toArray();
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$data[$key]['nickname'] = $val['member']['nickname'];
|
||||
$data[$key]['nickname'] = $val['member']['nickname'] ?? "";
|
||||
}
|
||||
foreach ($data as $key => $val) {
|
||||
$data[$key]['order_refund_no'] = $val['order_refund_no']."\t";
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Niucloud-admin 企业快速开发的多应用管理平台
|
||||
// +----------------------------------------------------------------------
|
||||
// | 官方网址:https://www.niucloud.com
|
||||
// +----------------------------------------------------------------------
|
||||
// | niucloud团队 版权所有 开源版本可自由商用
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Niucloud Team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace addon\shop\app\listener\shop_delivery;
|
||||
|
||||
use addon\shop\app\dict\local_delivery\LocalDeliveryStatusDict;
|
||||
use addon\shop\app\dict\shop_delivery\ShopDeliveryDict;
|
||||
|
||||
/**
|
||||
* 配送订单操作前置状态
|
||||
* @package addon\shop\app\listener\shop_delivery
|
||||
*/
|
||||
class OrderPreStatusListener
|
||||
{
|
||||
|
||||
public function handle($params)
|
||||
{
|
||||
if (!empty($params['service']) && $params['service'] == ShopDeliveryDict::MERCHANT) {
|
||||
return [
|
||||
'finish' => [
|
||||
LocalDeliveryStatusDict::IN_DELIVERY
|
||||
], //完成订单
|
||||
'cancel' => [
|
||||
LocalDeliveryStatusDict::IN_DELIVERY
|
||||
], //取消订单
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,11 +31,6 @@ class OrderAmountServiceListener
|
||||
// 'name' => '配送费',
|
||||
// 'key' => 'delivery_money',
|
||||
// 'amount' => 20
|
||||
// ],
|
||||
// [
|
||||
// 'name' => '服务费',
|
||||
// 'key' => 'service_money',
|
||||
// 'amount' => 10
|
||||
// ]
|
||||
// ];
|
||||
$this->getDeliveryMoney($data);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user