add shop
1273
niucloud/addon/shop/Addon.php
Normal file
282
niucloud/addon/shop/admin/api/delivery.ts
Normal file
@ -0,0 +1,282 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/********************************* 物流公司 ***************************************/
|
||||
/**
|
||||
* 获取物流公司分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCompanyPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/delivery/company`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流公司列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCompanyList(params: Record<string, any>) {
|
||||
return request.get(`shop/delivery/company/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物流公司详情
|
||||
* @param company_id 物流公司company_id
|
||||
* @returns
|
||||
*/
|
||||
export function getCompanyInfo(company_id: number) {
|
||||
return request.get(`shop/delivery/company/${ company_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加物流公司
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addCompany(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/company', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑物流公司
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editCompany(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/company/${ params.company_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除物流公司
|
||||
* @param company_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteCompany(company_id: number) {
|
||||
return request.delete(`shop/delivery/company/${ company_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/********************************* 运费模版 ***************************************/
|
||||
/**
|
||||
* 获取运费模版分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShippingTemplatePageList(params: Record<string, any>) {
|
||||
return request.get(`shop/shipping/template`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运费模版列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShippingTemplateList(params: Record<string, any>) {
|
||||
return request.get(`shop/shipping/template/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物运费模版详情
|
||||
* @param template_id 运费模版template_id
|
||||
* @returns
|
||||
*/
|
||||
export function getShippingTemplateInfo(template_id: number) {
|
||||
return request.get(`shop/shipping/template/${ template_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加运费模版
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addShippingTemplate(params: Record<string, any>) {
|
||||
return request.post('shop/shipping/template', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑运费模版
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editShippingTemplate(params: Record<string, any>) {
|
||||
return request.put(`shop/shipping/template/${ params.template_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除运费模版
|
||||
* @param template_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteShippingTemplate(template_id: number) {
|
||||
return request.delete(`shop/shipping/template/${ template_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/********************************* 自提门店 ***************************************/
|
||||
/**
|
||||
* 获取自提门店列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getStoreList(params: Record<string, any>) {
|
||||
return request.get(`shop/delivery/store`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自提门店详情
|
||||
* @param store_id 自提门店store_id
|
||||
* @returns
|
||||
*/
|
||||
export function getStoreInfo(store_id: number) {
|
||||
return request.get(`shop/delivery/store/${ store_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取初始化页面信息
|
||||
* @returns
|
||||
*/
|
||||
export function getStoreInit() {
|
||||
return request.get(`shop/delivery/store/init`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加自提门店
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addStore(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/store', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑自提门店
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editStore(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/store/${ params.store_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除自提门店
|
||||
* @param store_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteStore(store_id: number) {
|
||||
return request.delete(`shop/delivery/store/${ store_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/********************************* 物流查询 ***************************************/
|
||||
/**
|
||||
* 设置 物流查询配置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setDeliverySearch(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/search', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 物流查询配置
|
||||
* @returns
|
||||
*/
|
||||
export function getDeliverySearch() {
|
||||
return request.get('shop/delivery/search')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 物流管理配置
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliveryList() {
|
||||
return request.get('shop/delivery/deliveryList')
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流管理设置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
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 })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送员信息
|
||||
* @param staff_id
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDeliverInfo(staff_id: number) {
|
||||
return request.get(`shop/delivery/staff/${ staff_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加配送员
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addShopDeliver(params: Record<string, any>) {
|
||||
return request.post('shop/delivery/staff', params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑配送员
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editShopDeliver(params: Record<string, any>) {
|
||||
return request.put(`shop/delivery/staff/${ params.deliver_id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配送员
|
||||
* @param staff_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteShopDeliver(staff_id: number) {
|
||||
return request.delete(`shop/delivery/staff/${ staff_id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同城配送设置
|
||||
* @returns
|
||||
*/
|
||||
export function getLocal() {
|
||||
return request.get('shop/local');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置同城配送
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setLocal(params: Record<string, any>) {
|
||||
return request.put('shop/local', params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 三方配送
|
||||
* @returns
|
||||
*/
|
||||
export function getThird() {
|
||||
return request.get('shop/third/init')
|
||||
}
|
||||
116
niucloud/addon/shop/admin/api/electronic_sheet.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取电子面单分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getElectronicSheetPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/electronic_sheet`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子面单列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getElectronicSheetList(params: Record<string, any>) {
|
||||
return request.get(`shop/electronic_sheet/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子面单详情
|
||||
* @param id 电子面单id
|
||||
* @returns
|
||||
*/
|
||||
export function getElectronicSheetInfo(id: number) {
|
||||
return request.get(`shop/electronic_sheet/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加电子面单
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addElectronicSheet(params: Record<string, any>) {
|
||||
return request.post('shop/electronic_sheet', params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑电子面单
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editElectronicSheet(params: Record<string, any>) {
|
||||
return request.put(`shop/electronic_sheet/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除电子面单
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteElectronicSheet(id: number) {
|
||||
return request.delete(`shop/electronic_sheet/${ id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认电子面单模板
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setDefaultElectronicSheet(params: Record<string, any>) {
|
||||
return request.put(`shop/electronic_sheet/setDefault/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置电子面单 设置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setElectronicSheetConfig(params: Record<string, any>) {
|
||||
return request.post('shop/electronic_sheet/config', params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子面单配置
|
||||
* @returns
|
||||
*/
|
||||
export function getElectronicSheetConfig() {
|
||||
return request.get(`shop/electronic_sheet/config`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取邮费支付方式类型
|
||||
* @returns
|
||||
*/
|
||||
export function getElectronicSheetPayType() {
|
||||
return request.get(`shop/electronic_sheet/paytype`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印电子面单
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function printElectronicSheet(params: Record<string, any>) {
|
||||
return request.post('shop/electronic_sheet/print', params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
862
niucloud/addon/shop/admin/api/goods.ts
Normal file
@ -0,0 +1,862 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品详情
|
||||
* @param goods_id 商品goods_id
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsInfo(goods_id: number) {
|
||||
return request.get(`shop/goods/${ goods_id }`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取商品详情模板
|
||||
* @param goods_id 商品goods_id
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsInfoTemplate(params: any) {
|
||||
return request.get(`diy/list`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加实物商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addGoods(params: Record<string, any>) {
|
||||
return request.post('shop/goods', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑实物商品
|
||||
* @param params
|
||||
*/
|
||||
export function editGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/${ params.goods_id }`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品添加/编辑初始化数据
|
||||
* @param params
|
||||
*/
|
||||
export function getGoodsInit(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/init`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加虚拟商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addVirtualGoods(params: Record<string, any>) {
|
||||
return request.post('shop/goods/virtual', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑虚拟商品
|
||||
* @param params
|
||||
*/
|
||||
export function editVirtualGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/virtual/${ params.goods_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取虚拟商品添加/编辑初始化数据
|
||||
* @param params
|
||||
*/
|
||||
export function getVirtualGoodsInit(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/virtual/init`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function deleteGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/delete`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取回收站商品分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getRecycleGoodsPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/recycle`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function recycleGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/recycle`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品排序号
|
||||
* @param params
|
||||
*/
|
||||
export function editGoodsSort(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品上下架状态
|
||||
* @param params
|
||||
*/
|
||||
export function editGoodsStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/status`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制商品
|
||||
* @param params
|
||||
*/
|
||||
export function copyGoods(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/copy/${ params.goods_id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品选择分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSelectPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/select`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品SKU规格列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSkuList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/sku`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品SKU规格不分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSkuNoPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/selectgoodssku`, { params })
|
||||
}
|
||||
|
||||
/** 查询商品参与营销活动的数量
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveGoodsCount(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/active/count`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品SKU规格库存
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editGoodsListStock(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/sku/stock`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品SKU规格价格
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editGoodsListPrice(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/sku/price`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品SKU规格会员价格
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editGoodsListMemberPrice(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/sku/member_price`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品类型
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsType() {
|
||||
return request.get(`shop/goods/type`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/label`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/label/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签详情
|
||||
* @param label_id 商品标签label_id
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelInfo(label_id: number) {
|
||||
return request.get(`shop/goods/label/${ label_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品标签
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addLabel(params: Record<string, any>) {
|
||||
return request.post('shop/goods/label', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品标签
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editLabel(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/label/${ params.label_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品标签状态
|
||||
* @param params
|
||||
*/
|
||||
export function modifyLabelStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/label/status`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品标签
|
||||
* @param label_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteLabel(label_id: number) {
|
||||
return request.delete(`shop/goods/label/${ label_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品标签排序号
|
||||
* @param params
|
||||
*/
|
||||
export function modifyLabelSort(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/label/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签分组分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelGroupPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/label/group`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签分组列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelGroupList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/label/group/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品标签分组详情
|
||||
* @param label_id 商品标签分组label_id
|
||||
* @returns
|
||||
*/
|
||||
export function getLabelGroupInfo(label_id: number) {
|
||||
return request.get(`shop/goods/label/group/${ label_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品标签分组
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addLabelGroup(params: Record<string, any>) {
|
||||
return request.post('shop/goods/label/group', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品标签分组
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editLabelGroup(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/label/group/${ params.group_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品标签分组
|
||||
* @param group_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteLabelGroup(group_id: number) {
|
||||
return request.delete(`shop/goods/label/group/${ group_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品标签分组排序号
|
||||
* @param params
|
||||
*/
|
||||
export function modifyLabelGroupSort(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/label/group/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制标签
|
||||
* @param params
|
||||
*/
|
||||
export function copyLabel(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/label/copy/${ params.label_id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品品牌分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getBrandPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/brand`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品品牌列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getBrandList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/brand/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品品牌详情
|
||||
* @param brand_id 商品品牌brand_id
|
||||
* @returns
|
||||
*/
|
||||
export function getBrandInfo(brand_id: number) {
|
||||
return request.get(`shop/goods/brand/${ brand_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品品牌
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addBrand(params: Record<string, any>) {
|
||||
return request.post('shop/goods/brand', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品品牌
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editBrand(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/brand/${ params.brand_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品品牌排序号
|
||||
* @param params
|
||||
*/
|
||||
export function modifyBrandSort(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/brand/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品品牌
|
||||
* @param brand_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteBrand(brand_id: number) {
|
||||
return request.delete(`shop/goods/brand/${ brand_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品服务分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getServePageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/service`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品服务列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getServeList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/service/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品服务详情
|
||||
* @param service_id 商品服务service_id
|
||||
* @returns
|
||||
*/
|
||||
export function getServeInfo(service_id: number) {
|
||||
return request.get(`shop/goods/service/${ service_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品服务
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addServe(params: Record<string, any>) {
|
||||
return request.post('shop/goods/service', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品服务
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editServe(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/service/${ params.service_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品服务
|
||||
* @param service_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteServe(service_id: number) {
|
||||
return request.delete(`shop/goods/service/${ service_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类树结构
|
||||
* @returns
|
||||
*/
|
||||
export function getCategoryTree() {
|
||||
return request.get(`shop/goods/tree`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCategoryList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/category`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类详情
|
||||
* @param category_id 商品分类category_id
|
||||
* @returns
|
||||
*/
|
||||
export function getCategoryInfo(category_id: number) {
|
||||
return request.get(`shop/goods/category/${ category_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品分类
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addCategory(params: Record<string, any>) {
|
||||
return request.post('shop/goods/category', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品分类
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editCategory(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/category/${ params.category_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品分类
|
||||
* @param category_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteCategory(category_id: number) {
|
||||
return request.delete(`shop/goods/category/${ category_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽编辑商品分类
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function updateCategory(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/category/update`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商品分类配置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setCategoryConfig(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/category/config`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类配置
|
||||
* @returns
|
||||
*/
|
||||
export function getCategoryConfig() {
|
||||
return request.get(`shop/goods/category/config`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类树结构供弹框调用
|
||||
* @returns
|
||||
*/
|
||||
export function getCategoryTreeComponents() {
|
||||
return request.get(`shop/goods/category/components`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取供应商列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getSupplierList(params: Record<string, any>) {
|
||||
return request.get(`shop_supplier/supplier/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品评价列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getEvaluateList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/evaluate`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品评价
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addEvaluate(params: Record<string, any>) {
|
||||
return request.post('shop/goods/evaluate', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品评价
|
||||
* @param evaluate_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteEvaluate(evaluate_id: number) {
|
||||
return request.delete(`shop/goods/evaluate/${ evaluate_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 通过
|
||||
* @param evaluate_id
|
||||
* @returns
|
||||
*/
|
||||
export function adoptEvaluate(evaluate_id: number) {
|
||||
return request.put(`shop/goods/evaluate/adopt/${ evaluate_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 拒绝
|
||||
* @param evaluate_id
|
||||
* @returns
|
||||
*/
|
||||
export function refuseEvaluate(evaluate_id: number) {
|
||||
return request.put(`shop/goods/evaluate/refuse/${ evaluate_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 回复
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function replyEvaluate(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/evaluate/reply/${ params.evaluate_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 置顶
|
||||
* @param evaluate_id
|
||||
* @returns
|
||||
*/
|
||||
export function toppingEvaluate(evaluate_id: number) {
|
||||
return request.put(`shop/goods/evaluate/topping/${ evaluate_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 取消置顶
|
||||
* @param evaluate_id
|
||||
* @returns
|
||||
*/
|
||||
export function cancelToppingEvaluate(evaluate_id: number) {
|
||||
return request.put(`shop/goods/evaluate/cancel_topping/${ evaluate_id }`, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品评价状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getEvaluateStatus() {
|
||||
return request.get(`shop/goods/evaluate/status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除商品评价
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDelEvaluate(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/evaluate/batch/del`,params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 批量通过
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchAdoptEvaluate(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/evaluate/batch/adopt`,params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品评价 批量拒绝
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchRefuseEvaluate(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/evaluate/batch/refuse`,params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品参数分页列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getAttrPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/attr`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品参数列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getAttrList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/attr/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品参数详情
|
||||
* @param attr_id 商品参数attr_id
|
||||
* @returns
|
||||
*/
|
||||
export function getAttrInfo(attr_id: number) {
|
||||
return request.get(`shop/goods/attr/${ attr_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品参数
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addAttr(params: Record<string, any>) {
|
||||
return request.post('shop/goods/attr', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品参数
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editAttr(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/attr/${ params.attr_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商品参数
|
||||
* @param attr_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteAttr(attr_id: number) {
|
||||
return request.delete(`shop/goods/attr/${ attr_id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品参数排序号
|
||||
* @param params
|
||||
*/
|
||||
export function modifyAttrSort(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/attr/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品参数名称
|
||||
* @param params
|
||||
*/
|
||||
export function modifyAttrName(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/attr/attr_name`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品参数值
|
||||
* @param params
|
||||
*/
|
||||
export function modifyAttrValue(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/attr/attr_value`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取批量设置字典列表
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsBatchSetDict() {
|
||||
return request.get(`shop/goods/batchSet/dict`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品批量设置
|
||||
* @param params
|
||||
*/
|
||||
export function goodsBatchSet(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/batchSet`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品搜索配置
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsConfigSearch() {
|
||||
return request.get(`shop/goods/config/search`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品搜索配置
|
||||
* @returns
|
||||
*/
|
||||
export function setGoodsConfigSearch(param: any) {
|
||||
return request.post('shop/goods/config/search', param, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取商品唯一编码配置
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsConfigUnique() {
|
||||
return request.get(`shop/goods/config/unique`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商品唯一编码配置
|
||||
* @returns
|
||||
*/
|
||||
export function setGoodsConfigUnique(param: any) {
|
||||
return request.post('shop/goods/config/unique', param, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品唯一编码
|
||||
|
||||
* @returns
|
||||
*/
|
||||
export function goodsVerify(param: any) {
|
||||
return request.post('shop/goods/verify/skuno', param)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品排序配置
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsConfigSort() {
|
||||
return request.get(`shop/goods/config/sort`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置商品排序配置
|
||||
* @returns
|
||||
*/
|
||||
export function setGoodsConfigSort(param: any) {
|
||||
return request.post('shop/goods/config/sort', param, { showSuccessMessage: true })
|
||||
}
|
||||
// 上下架
|
||||
|
||||
export function editGoodssingleStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/single/status`, params, { showSuccessMessage: true })
|
||||
}
|
||||
692
niucloud/addon/shop/admin/api/marketing.ts
Normal file
@ -0,0 +1,692 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 营销中心
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getMarketingIndex(params: Record<string, any>) {
|
||||
return request.get(`shop/marketing`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsCategoryList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon/init`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加优惠券
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addCoupon(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/coupon`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券状态列表
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponStatusList() {
|
||||
return request.get(`shop/goods/coupon/status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponSelectList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon/select`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getSelectedCouponList(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon/selected`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券领取记录
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponRecords(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon/records`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券详情
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponInfo(id: number) {
|
||||
return request.get(`shop/goods/coupon/detail/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 优惠券状态变更
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editCouponStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/coupon/setstatus/${ params.status }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑优惠券
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editCoupon(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/coupon/edit/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除优惠券
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function deleteCoupon(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/coupon/delete`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭优惠券
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function closeCoupon(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/coupon/invalid`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送优惠券
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function sendCoupon(params: Record<string, any>) {
|
||||
return request.post(`shop/goods/coupon/send/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取优惠券发放记录
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getCouponSendRecords(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/coupon/send/pages/${ params.id }`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 优惠券init
|
||||
* @returns
|
||||
*/
|
||||
export function initCoupon() {
|
||||
return request.get(`shop/goods/coupon/send/init`)
|
||||
}
|
||||
|
||||
/************ 限时折扣 ****************/
|
||||
/**
|
||||
* 获取限时折扣列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/discount`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限时折扣状态列表
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountStatusList() {
|
||||
return request.get(`shop/active/status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定活动的折扣信息。
|
||||
*
|
||||
* @param active_id 获取基本信息
|
||||
* @returns
|
||||
*/
|
||||
export function getBasicInformation(active_id: number) {
|
||||
return request.get(`shop/active/discount/info/${ active_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取限时折扣详情 编辑
|
||||
* @param active_id
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountInfo(active_id: number) {
|
||||
return request.get(`shop/active/discount/${ active_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加限时折扣
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addActiveDiscount(params: Record<string, any>) {
|
||||
return request.post('shop/active/discount', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑限时折扣
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editActiveDiscount(params: Record<string, any>) {
|
||||
return request.put(`shop/active/discount/${ params.discount_id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭限时折扣
|
||||
* @param active_id
|
||||
* @returns
|
||||
*/
|
||||
export function closeActiveDiscount(active_id: number) {
|
||||
return request.put(`shop/active/discount/close/${ active_id }`, {}, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除限时折扣
|
||||
* @param active_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteActiveDiscount(active_id: number) {
|
||||
return request.delete(`shop/active/discount/${ active_id }`, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量关闭限时折扣
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchCloseActiveDiscount(params: Record<string, any>) {
|
||||
return request.post(`shop/active/discount/batchClose`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除限时折扣
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDeleteActiveDiscount(params: Record<string, any>) {
|
||||
return request.post(`shop/active/discount/batchDelete`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参与限时折扣商品列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountGoodsPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/discount/goods/${ params.active_id }`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参与限时折扣订单列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountOrderPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/discount/order/${ params.active_id }`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 限时折扣商品校验
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function goodscheck(params: Record<string, any>) {
|
||||
return request.post(`shop/active/discount/goods/check`, params, {})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参与限时折扣会员列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountMemberPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/discount/member/${ params.active_id }`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动专题
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveDiscountConfig() {
|
||||
return request.get(`shop/active/discount/config`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑活动专题
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editActiveDiscountConfig(params: Record<string, any>) {
|
||||
return request.put(`shop/active/discount/config`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/********** 积分商品 ***********/
|
||||
|
||||
/**
|
||||
* 获取积分商品列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveExchangePageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/exchange`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分商品分页列表(用于弹框选择)
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveExchangeSelectPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/active/exchange/select`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分商品详情
|
||||
* @param id id
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveExchangeInfo(id: number) {
|
||||
return request.get(`shop/active/exchange/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加积分商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addActiveExchange(params: Record<string, any>) {
|
||||
return request.post('shop/active/exchange', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑积分商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editActiveExchange(params: Record<string, any>) {
|
||||
return request.put(`shop/active/exchange/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑积分商品状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editActiveExchangeStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/active/exchange/status/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除积分商品
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteActiveExchange(id: number) {
|
||||
return request.delete(`shop/active/exchange/${ id }`, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除积分商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDeleteActiveExchange(params: Record<string, any>) {
|
||||
return request.post(`shop/active/exchange/batchDelete`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量下架积分商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDownActiveExchange(params: Record<string, any>) {
|
||||
return request.post(`shop/active/exchange/batchDown`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量上架积分商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchUpActiveExchange(params: Record<string, any>) {
|
||||
return request.post(`shop/active/exchange/batchUp`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取积分商品状态列表
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveExchangeStatus() {
|
||||
return request.get(`shop/active/exchange/status`)
|
||||
}
|
||||
|
||||
/************ 新人专享 ****************/
|
||||
|
||||
/**
|
||||
* 获取新人专享设置
|
||||
* @returns
|
||||
*/
|
||||
export function getActiveNewcomerConfig() {
|
||||
return request.get(`shop/active/newcomer/config`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑新人专享设置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editActiveNewcomerConfig(params: Record<string, any>) {
|
||||
return request.put(`shop/active/newcomer/config`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新人专享列表【首页组件-分页】
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getNewcomerGoodsList(params: Record<string, any>) {
|
||||
return request.get('shop/active/newcomer/goods/select', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 新人专享 - 已选商品列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getNewcomerSelectGoodsList(params: Record<string, any>) {
|
||||
return request.get('shop/active/newcomer/goods/selectgoodssku', { params })
|
||||
}
|
||||
|
||||
/************ 商品榜单 ****************/
|
||||
|
||||
/**
|
||||
* 设置排行榜配置
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function setRankConfig(params: Record<string, any>) {
|
||||
return request.post('shop/good/rank/config', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排行榜配置
|
||||
* @returns
|
||||
*/
|
||||
export function getRankConfig() {
|
||||
return request.get(`shop/good/rank/config`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排行榜列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getRankPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/good/rank`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排行榜选项列表
|
||||
* @returns
|
||||
*/
|
||||
export function optionData() {
|
||||
return request.get(`shop/good/rank/dict`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取排行榜详情
|
||||
* @param rank_id
|
||||
* @returns
|
||||
*/
|
||||
export function getRankInfo(rank_id: number) {
|
||||
return request.get(`shop/good/rank/${ rank_id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加排行榜
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addGoodRank(params: Record<string, any>) {
|
||||
return request.post('shop/good/rank', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑排行榜
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editGoodRank(params: Record<string, any>) {
|
||||
return request.put(`shop/good/rank/${ params.id }`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 排行榜状态
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editRankStatus(params: Record<string, any>) {
|
||||
return request.put(`shop/goods/rank/status`, params, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除排行榜
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteGoodRank(id: number) {
|
||||
return request.delete(`shop/good/rank/${ id }`, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除排行榜
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDelete(params: Record<string, any>) {
|
||||
return request.put(`shop/good/rank/batchDelete`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 排行榜修改排序
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function modifyGoodsRankSort(params: Record<string, any>) {
|
||||
return request.put(`shop/good/rank/sort`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品排行榜列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getSelectRankPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/good/rank/select`, { params })
|
||||
}
|
||||
|
||||
/************ 满减 ****************/
|
||||
|
||||
/**
|
||||
* 获取满减列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getManjianList(params: Record<string, any>) {
|
||||
return request.get(`shop/manjian`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取满减状态
|
||||
* @returns
|
||||
*/
|
||||
export function getManjianStatusList() {
|
||||
return request.get(`shop/manjian/status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加满减
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addManjian(params: Record<string, any>) {
|
||||
return request.post('shop/manjian', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑满减
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editManjian(params: Record<string, any>) {
|
||||
return request.put(`shop/manjian/${ params.id }`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取满减详情
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getManjianInfo(params: Record<string, any>) {
|
||||
return request.get(`shop/manjian/init`, { params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查商品
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function goodsCheck(params: Record<string, any>) {
|
||||
return request.post('shop/manjian/goods/check', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取满减详情会员列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getManjianMemberPageList(params: Record<string, any>) {
|
||||
return request.get(`shop/manjian/member/${ params.id }`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭满减
|
||||
* @param manjian_id
|
||||
* @returns
|
||||
*/
|
||||
export function closeManjian(manjian_id: number) {
|
||||
return request.put(`shop/manjian/close/${ manjian_id }`, {}, {
|
||||
showErrorMessage: true,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品选择列表,代客下单使用
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSelectByReplaceBuy(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/buy/goods/select`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选中商品选择列表,代客下单使用
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSelectedByReplaceBuy(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/buy/goods/selected`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品规格信息
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsSkuInfo(params: Record<string, any>) {
|
||||
return request.get(`shop/goods/buy/sku/select`, { params })
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除满减
|
||||
* @param manjian_id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteManjian(manjian_id: number) {
|
||||
return request.delete(`shop/manjian/${ manjian_id }`, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除满减
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchDeleteManjian(params: Record<string, any>) {
|
||||
return request.put(`shop/manjian/goods/batchDelete`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量关闭满减
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function batchCloseMajian(params: Record<string, any>) {
|
||||
return request.put(`shop/manjian/goods/batchClose`, params, { showSuccessMessage: true })
|
||||
}
|
||||
281
niucloud/addon/shop/admin/api/order.ts
Normal file
@ -0,0 +1,281 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取交易配置
|
||||
* @returns
|
||||
*/
|
||||
export function getConfig() {
|
||||
return request.get('shop/order/config')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑交易配置
|
||||
* @returns
|
||||
*/
|
||||
export function setConfig(param: any) {
|
||||
return request.post('shop/order/config', param, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @returns
|
||||
*/
|
||||
export function getOrderList(params: Record<string, any>) {
|
||||
return request.get('shop/order/list', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @returns
|
||||
*/
|
||||
export function getOrderDetail(order_id: number) {
|
||||
return request.get(`shop/order/detail/${ order_id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单状态
|
||||
* @return
|
||||
*/
|
||||
export function getOrderStatus() {
|
||||
return request.get(`shop/order/status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单类型
|
||||
* @return
|
||||
*/
|
||||
export function getOrderType() {
|
||||
return request.get(`shop/order/type`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单关闭
|
||||
* @return
|
||||
*/
|
||||
export function orderClose(order_id: number) {
|
||||
return request.put(`shop/order/close/${ order_id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单删除
|
||||
* @return
|
||||
*/
|
||||
export function orderDelete(params: Record<string, any>) {
|
||||
return request.post(`shop/order/delete`,params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订单配送方式
|
||||
* @return
|
||||
*/
|
||||
export function getOrderDeliveryType(params: Record<string, any>) {
|
||||
return request.get(`shop/order/delivery_type`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单发货
|
||||
* @return
|
||||
*/
|
||||
export function orderDelivery(params: Record<string, any>) {
|
||||
return request.put(`shop/order/delivery`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家留言
|
||||
* @return
|
||||
*/
|
||||
export function setShopRemark(params: Record<string, any>) {
|
||||
return request.put(`shop/order/shop_remark`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单完成
|
||||
* @return
|
||||
*/
|
||||
export function orderFinish(order_id: number) {
|
||||
return request.put(`shop/order/finish/${ order_id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流包裹信息(物流跟踪)
|
||||
* @return
|
||||
*/
|
||||
export function deliveryPackage(params: Record<string, any>) {
|
||||
return request.get(`shop/order/delivery/package`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流包裹列表
|
||||
* @return
|
||||
*/
|
||||
export function deliveryPackageList(params: Record<string, any>) {
|
||||
return request.get(`shop/order/delivery/package/list`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款售后列表
|
||||
* @param {Record<string, any>} params
|
||||
* @return
|
||||
*/
|
||||
export function orderRefund(params: Record<string, any>) {
|
||||
return request.get(`shop/order/refund`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款售后详情
|
||||
*/
|
||||
export function orderRefundDetail(refund_id: number) {
|
||||
return request.get(`shop/order/refund/${ refund_id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款审核
|
||||
* @return
|
||||
*/
|
||||
export function auditRefund(params: Record<string, any>) {
|
||||
return request.put(`shop/order/refund/audit/${ params.order_refund_no }`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 退款收货审核
|
||||
* @return
|
||||
*/
|
||||
export function refundDelivery(params: Record<string, any>) {
|
||||
return request.put(`shop/order/refund/delivery/${ params.order_refund_no }`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可退款金额
|
||||
*/
|
||||
export function getRefundMoney(params: Record<string, any>) {
|
||||
return request.get(`shop/order/refund/refund_money`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家主动退款
|
||||
*/
|
||||
export function shopActiveRefund(params: Record<string, any>) {
|
||||
return request.post(`shop/order/refund/active`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发票列表
|
||||
*/
|
||||
export function getInvoiceList(params: Record<string, any>) {
|
||||
return request.get(`shop/invoice`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发票列表
|
||||
*/
|
||||
export function getInvoiceDetail(id: number) {
|
||||
return request.get(`shop/invoice/${ id }`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开具发票
|
||||
*/
|
||||
export function setInvoice(id: number, params: Record<string, any>) {
|
||||
return request.put(`shop/invoice/${ id }`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 开发票
|
||||
*/
|
||||
export function createInvoice(params: Record<string, any>) {
|
||||
return request.post(`shop/invoice/add`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发票审核
|
||||
*/
|
||||
export function auditInvoice(params: Record<string, any>) {
|
||||
return request.post(`shop/invoice/audit`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付类型
|
||||
*/
|
||||
export function getOrderPayType() {
|
||||
return request.get(`shop/order/pay/type`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单来源
|
||||
*/
|
||||
export function getOrderFrom() {
|
||||
return request.get(`shop/order/from`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单调价
|
||||
* @return
|
||||
*/
|
||||
export function orderEditPrice(params: Record<string, any>) {
|
||||
return request.put(`shop/order/edit_price`, params, { showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单地址信息
|
||||
* @return
|
||||
*/
|
||||
export function getOrderEditAddress(params: Record<string, any>) {
|
||||
return request.get(`shop/order/edit_delivery`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自提点列表
|
||||
* @return
|
||||
*/
|
||||
export function getDeliveryList() {
|
||||
return request.get(`shop/delivery/store/list`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改地址
|
||||
* @return
|
||||
*/
|
||||
export function orderEditAddress(params: Record<string, any>) {
|
||||
return request.put(`shop/order/edit_delivery`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发货列表
|
||||
* @return
|
||||
*/
|
||||
export function getOrderBatchDeliveryList(params: Record<string, any>) {
|
||||
return request.get(`shop/order_batch_delivery`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发货导入
|
||||
* @return
|
||||
*/
|
||||
export function addBatchOrderDelivery(params: Record<string, any>) {
|
||||
return request.put(`shop/order_batch_delivery/add_batch_order_delivery`, params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取批量发货状态
|
||||
* @return
|
||||
*/
|
||||
export function getOrderBatchDeliveryState() {
|
||||
return request.get(`shop/order_batch_delivery/get_status`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取批量发货操作类型
|
||||
* @return
|
||||
*/
|
||||
export function getOrderBatchDeliveryType() {
|
||||
return request.get(`shop/order_batch_delivery/get_type`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭售后
|
||||
* @return
|
||||
*/
|
||||
export function closeRefund(order_refund_no: number) {
|
||||
return request.put(`shop/order/refund/close/${order_refund_no}`)
|
||||
}
|
||||
43
niucloud/addon/shop/admin/api/shop.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取统计总数
|
||||
*/
|
||||
export function getShopCountList() {
|
||||
return request.get(`shop/stat/total`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日统计总数
|
||||
*/
|
||||
export function getShopTodayCountList() {
|
||||
return request.get(`shop/stat/today`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨日统计总数
|
||||
*/
|
||||
export function getShopYesterdayCountList() {
|
||||
return request.get(`shop/stat/yesterday`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计图数据
|
||||
*/
|
||||
export function getShopStat() {
|
||||
return request.get(`shop/stat`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单统计
|
||||
*/
|
||||
export function getShopOrderStat() {
|
||||
return request.get(`shop/stat/order`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品统计
|
||||
*/
|
||||
export function getShopGoodsStat() {
|
||||
return request.get(`shop/stat/goods`)
|
||||
}
|
||||
62
niucloud/addon/shop/admin/api/shop_address.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取商家地址库列表
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getShopAddressList(params: Record<string, any>) {
|
||||
return request.get(`shop/shop_address`, { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家地址库详情
|
||||
* @param id 商家地址库id
|
||||
* @returns
|
||||
*/
|
||||
export function getShopAddressInfo(id: number) {
|
||||
return request.get(`shop/shop_address/${ id }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商家地址库
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function addShopAddress(params: Record<string, any>) {
|
||||
return request.post('shop/shop_address', params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商家地址库
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function editShopAddress(params: Record<string, any>) {
|
||||
return request.put(`shop/shop_address/${ params.id }`, params, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商家地址库
|
||||
* @param id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteShopAddress(id: number) {
|
||||
return request.delete(`shop/shop_address/${ id }`, { showErrorMessage: true, showSuccessMessage: true })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家默认发货地址
|
||||
* @returns
|
||||
*/
|
||||
export function getShopDefaultDeliveryAddressInfo() {
|
||||
return request.get('shop/shop_address/default/delivery');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商家收货地址
|
||||
* @returns
|
||||
*/
|
||||
export function getOrderRefundAddress() {
|
||||
return request.get('shop/order/refund/address');
|
||||
}
|
||||
32
niucloud/addon/shop/admin/api/stat.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取商品统计基本信息
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsStatisticsBasic(params: Record<string, any>) {
|
||||
return request.get('shop/goods/statistics/basic', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品排行图表统计信息
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsStatisticsTrend(params: Record<string, any>) {
|
||||
return request.get('shop/goods/statistics/trend', { params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品排行榜统计类型
|
||||
*/
|
||||
export function getGoodsStatisticsType() {
|
||||
return request.get(`shop/goods/statistics/type`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商品排行信息
|
||||
* @returns
|
||||
*/
|
||||
export function getGoodsStatisticsRank(params: Record<string, any>) {
|
||||
return request.get('shop/goods/statistics/rank', { params })
|
||||
}
|
||||
BIN
niucloud/addon/shop/admin/assets/brand_default.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
niucloud/addon/shop/admin/assets/category_default.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
niucloud/addon/shop/admin/assets/category_style2_new.png
Normal file
|
After Width: | Height: | Size: 621 KiB |
BIN
niucloud/addon/shop/admin/assets/category_style3_new.png
Normal file
|
After Width: | Height: | Size: 322 KiB |
BIN
niucloud/addon/shop/admin/assets/category_style4_new.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
niucloud/addon/shop/admin/assets/discount_banner.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
niucloud/addon/shop/admin/assets/discount_config.png
Normal file
|
After Width: | Height: | Size: 216 KiB |
BIN
niucloud/addon/shop/admin/assets/goods_default.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
niucloud/addon/shop/admin/assets/store_default.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
35
niucloud/addon/shop/admin/lang/zh-cn/address.edit.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"contactName": "联系人",
|
||||
"mobile": "联系方式",
|
||||
"provinceId": "省",
|
||||
"cityId": "市",
|
||||
"districtId": "区",
|
||||
"address": "详细地址",
|
||||
"fullAddress": "地址",
|
||||
"lat": "纬度",
|
||||
"lng": "经度",
|
||||
"isDeliveryAddress": "是否是发货地址",
|
||||
"isRefundAddress": "是否是退货地址",
|
||||
"isDefaultDelivery": "默认发货地址",
|
||||
"isDefaultRefund": "默认收货地址",
|
||||
"contactNamePlaceholder": "请输入联系人",
|
||||
"mobilePlaceholder": "请输入联系方式",
|
||||
"mobileTips": "请输入正确的手机号",
|
||||
"addressPlaceholder": "请输入详细地址",
|
||||
"fullAddressPlaceholder": "请输入地址",
|
||||
"latPlaceholder": "请输入纬度",
|
||||
"lngPlaceholder": "请输入经度",
|
||||
"isDeliveryAddressPlaceholder": "请输入是否是发货地址",
|
||||
"isRefundAddressPlaceholder": "请输入是否是退货地址",
|
||||
"isDefaultDeliveryPlaceholder": "请输入默认发货地址",
|
||||
"isDefaultRefundPlaceholder": "请输入默认收货地址",
|
||||
"addShopAddress": "添加商家地址库",
|
||||
"updateShopAddress": "编辑商家地址库",
|
||||
"shopAddressDeleteTips": "确定要删除该商家地址库吗?",
|
||||
"addressType": "地址类型",
|
||||
"deliveryAddress": "发货地址",
|
||||
"refundAddress": "收货地址",
|
||||
"defaultDeliveryAddress": "是否设为默认发货地址",
|
||||
"defaultRefundAddress": "是否设为默认收货地址",
|
||||
"addressTypeRequire": "至少需设置一项类型"
|
||||
}
|
||||
25
niucloud/addon/shop/admin/lang/zh-cn/address.list.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"id": "",
|
||||
"contactName": "联系人",
|
||||
"mobile": "联系方式",
|
||||
"mobilePlaceholder": "请输入联系方式",
|
||||
"provinceId": "省",
|
||||
"cityId": "市",
|
||||
"districtId": "区",
|
||||
"address": "详细地址",
|
||||
"fullAddress": "地址",
|
||||
"fullAddressPlaceholder": "请输入地址",
|
||||
"lat": "纬度",
|
||||
"lng": "经度",
|
||||
"isDeliveryAddress": "是否是发货地址",
|
||||
"isRefundAddress": "是否是退货地址",
|
||||
"isDefaultDelivery": "默认发货地址",
|
||||
"isDefaultRefund": "默认收货地址",
|
||||
"addShopAddress": "添加商家地址库",
|
||||
"updateShopAddress": "编辑商家地址库",
|
||||
"shopAddressDeleteTips": "确定要删除该数据吗?",
|
||||
"addressType": "地址类型",
|
||||
"deliveryAddress": "发货地址",
|
||||
"refundAddress": "收货地址",
|
||||
"default": "默认"
|
||||
}
|
||||
150
niucloud/addon/shop/admin/lang/zh-cn/common.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"goodsSelectPopupSelectGoodsButton": "选择商品",
|
||||
"rankSelectPopupSelectRankButton": "选择榜单",
|
||||
"goodsSelectPopupSelect": "已选",
|
||||
"goodsSelectPopupPiece": "个",
|
||||
"goodsSelectPopupSelectGoodsDialog": "商品选择",
|
||||
"goodsSelectPopupAllGoods": "全部商品",
|
||||
"defaultGoodsSelect": "默认",
|
||||
"goodsSelectPopupSelectedGoods": "已选商品",
|
||||
"goodsSelectPopupGoodsName": "商品名称",
|
||||
"goodsSelectPopupGoodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsSelectPopupGoodsStatusPlaceholder": "请选择商品状态",
|
||||
"goodsSelectPopupGoodsCategory": "商品分类",
|
||||
"goodsSelectPopupGoodsCategoryPlaceholder": "全部",
|
||||
"goodsSelectPopupGoodsType": "商品类型",
|
||||
"goodsSelectPopupGoodsTypePlaceholder": "请选择商品类型",
|
||||
"goodsSelectPopupGoodsInfo": "商品",
|
||||
"goodsSelectPopupGoodsPointUnit": "积分",
|
||||
"goodsSelectPopupGoodsPriceUnit": "元",
|
||||
"goodsSelectPopupPrice": "价格",
|
||||
"goodsSelectPopupStock": "库存",
|
||||
"goodsSelectPopupBeforeTip": "已选择",
|
||||
"goodsSelectPopupAfterTip": "个商品",
|
||||
"goodsSelectPopupClearGoods": "取消选择",
|
||||
"goodsSelectPopupGoodsMinTip": "所选商品数量不能少于",
|
||||
"goodsSelectPopupGoodsMaxTip": "所选商品数量不能超过",
|
||||
"goodsTextColor": "文字颜色",
|
||||
"textColor": "标题颜色",
|
||||
"subTextColor": "副标题颜色",
|
||||
"wayPlaceholder": "虚拟商品和实物商品只能选择其中一个类型,请重新选择",
|
||||
"goodsStyle": "商品样式",
|
||||
"goodsBgColor": "商品背景",
|
||||
"goodsNameColor": "商品名称",
|
||||
"goodsPriceColor": "销售价",
|
||||
"goodsBtnText": "文本",
|
||||
"goodsBtnTextPlaceholder": "请输入按钮文字",
|
||||
"goodsSaleColor": "商品销量",
|
||||
"goodsBtnColor": "按钮背景",
|
||||
"goodsNumColor": "已兑人数",
|
||||
"goodsBuyBtn": "购买按钮",
|
||||
"goodsShowContent": "显示内容",
|
||||
"goodsBtnResult": "按钮效果",
|
||||
"goodsBtnIsShow": "是否显示",
|
||||
"goodsCartIncident": "点击事件",
|
||||
"goodsAddCart": "加入购物车",
|
||||
"goodsBtnStyle": "样式",
|
||||
"goodsSaleNum": "商品销量",
|
||||
"goodsDetail": "商品详情",
|
||||
"goodsRounded": "圆角",
|
||||
"fenxiaoCommissionPriceColor": "分销佣金",
|
||||
"goodsCategoryPlaceholder": "请选择商品分类",
|
||||
"goodsPlaceholder": "请选择商品",
|
||||
"goodsIsBold": "是否加粗",
|
||||
"goodsLabel": "商品标签",
|
||||
"headStyle1": "样式1",
|
||||
"headStyle2": "样式2",
|
||||
"headStyle3": "样式3",
|
||||
"headStyle4": "样式4",
|
||||
"goodsData": "商品数据",
|
||||
"sortWay": "排序",
|
||||
"default": "综合",
|
||||
"sales": "销量",
|
||||
"price": "价格",
|
||||
"manyGoodsListAroundRadius": "图片圆角",
|
||||
"manyGoodsListCategoryName": "分类名称",
|
||||
"manyGoodsListSubTitle": "副标题",
|
||||
"manyGoodsLisAddItem": "添加一个多商品组",
|
||||
"couponData": "优惠券数据",
|
||||
"couponContent": "优惠券内容",
|
||||
"couponTitle": "标题",
|
||||
"couponTitlePlaceholder": "请输入标题",
|
||||
"couponSubTitle": "副标题",
|
||||
"couponSubTitlePlaceholder": "请输入副标题",
|
||||
"selectCoupon": "选择优惠券",
|
||||
"allSources": "全部",
|
||||
"couponNum": "优惠券数量",
|
||||
"couponPlaceholder": "请选择优惠券",
|
||||
"couponBtnText": "按钮文字",
|
||||
"couponBtnTextPlaceholder": "请输入按钮文字",
|
||||
"couponTitleStyle": "标题样式",
|
||||
"couponTitleColor": "标题颜色",
|
||||
"couponSubTitleColor": "副标题颜色",
|
||||
"couponItemStyle": "优惠券项样式",
|
||||
"couponMoney": "金额颜色",
|
||||
"manyGoodsListCategorySet": "分组设置",
|
||||
"manyGoodsListSourceDiy": "自定义",
|
||||
"manyGoodsListSourceCategory": "商品分类",
|
||||
"goodsSet": "商品设置",
|
||||
"goodsSearchSet": "搜索设置",
|
||||
"goodsSearchText": "搜索内容",
|
||||
"goodsSearchTextPlaceholder": "请输入搜索内容",
|
||||
"shopMemberInfoComponentUidTextColor": "编号颜色",
|
||||
"shopMemberInfoComponentAccountTextColor": "账户颜色",
|
||||
"shopMemberInfoComponentAccount": "账号信息",
|
||||
"shopGoodsRecommendComponentTag": "标签",
|
||||
"shopGoodsRecommendComponentTagColor": "标签颜色",
|
||||
"shopGoodsRecommendComponentTagPlaceholder": "请输入标签内容",
|
||||
"shopGoodsRecommendComponentButtonBorderColor": "按钮边框颜色",
|
||||
"carouselStyle": "轮播样式",
|
||||
"recommendIndicatorStyle": "指示器设置",
|
||||
"recommendIndicatorColor": "常规颜色",
|
||||
"recommendIndicatorActiveColor": "选中颜色",
|
||||
"activeCubeBlockContent": "板块内容",
|
||||
"bgImage": "背景图片",
|
||||
"rankingTitleIcon": "图标",
|
||||
"rankSelect": "榜单选择",
|
||||
"rankName": "榜单名称",
|
||||
"rankNamePlaceholder": "请输入榜单名称",
|
||||
"showGoodsNum": "榜单商品数量",
|
||||
"goodsSourceName": "商品来源",
|
||||
"ruleTypeName": "排序规则",
|
||||
"rankTypeName": "排行周期",
|
||||
"rankSelectPopupAfterTip": "个榜单",
|
||||
"rankSelectPopupGoodsMinTip": "所选榜单数量不能少于",
|
||||
"rankSelectPopupGoodsMaxTip": "所选榜单数量不能超过",
|
||||
"rankingTitleImage": "头部图片",
|
||||
"rankingSubTitle": "副标题",
|
||||
"rankingSubTitleTextColor": "副标题颜色",
|
||||
"rankTextColor": "名称颜色",
|
||||
"rankingSubTitleLink": "副标题链接",
|
||||
"listFrameColor": "背景颜色",
|
||||
"topRounded": "上圆角",
|
||||
"bottomRounded": "下圆角",
|
||||
"imageRounded": "图片圆角",
|
||||
"rankingStyle": "板块样式",
|
||||
"styleRecommend": "风格推荐",
|
||||
"countDownStyle": "倒计时样式",
|
||||
"newcomerNumberColor": "数字颜色",
|
||||
"newcomerNumberBg": "数字背景色",
|
||||
"newcomerOtherColor": "文字颜色",
|
||||
"goodsCategorySelectContentName": "分类名称",
|
||||
"goodsCategorySelectContentImage": "分类图片",
|
||||
"goodsCategorySelectContentPlaceholder": "请选择商品分类",
|
||||
"couponSelectContentTitle": "优惠券名称",
|
||||
"couponSelectContentTitlePlaceholder": "请输入优惠券名称",
|
||||
"couponSelectContentType": "类型",
|
||||
"couponSelectContentPrice": "面值",
|
||||
"couponSelectContentThreshold": "使用门槛",
|
||||
"couponSelectContentTips": "请选择优惠券",
|
||||
"pointExchangeSelectContentTitle": "商品名称",
|
||||
"pointExchangeSelectContentTitlePlaceholder": "请输入商品名称",
|
||||
"pointExchangeSelectContentGoodsInfo": "商品信息",
|
||||
"pointExchangeSelectContentPrice": "兑换价格",
|
||||
"pointExchangeSelectContentPointUnit": "积分",
|
||||
"pointExchangeSelectContentPriceUnit": "元",
|
||||
"pointExchangeSelectContentRedeemedAndSurplus": "已兑/剩余",
|
||||
"pointExchangeSelectContentTips": "请选择积分商品",
|
||||
"categoryName": "分类名称",
|
||||
"categoryImage": "分类图片"
|
||||
}
|
||||
20
niucloud/addon/shop/admin/lang/zh-cn/delivery.company.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"companyId": "",
|
||||
"companyIdPlaceholder": "请输入",
|
||||
"companyName": "名称",
|
||||
"companyNamePlaceholder": "请输入物流公司名称",
|
||||
"logo": "LOGO",
|
||||
"logoPlaceholder": "请输入物流公司logo",
|
||||
"url": "网址",
|
||||
"urlPlaceholder": "请输入物流公司网址",
|
||||
"expressNoPlaceholder": "请输入物流公司编号",
|
||||
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
|
||||
"expressNoKd100": "快递100物流跟踪编号",
|
||||
"expressNoKd100Placeholder": "请输入快递100物流跟踪编号",
|
||||
"addCompany": "添加物流公司",
|
||||
"updateCompany": "编辑物流公司",
|
||||
"electronicSheetSwitchName": "是否支持电子面单",
|
||||
"expressNoElectronicSheet": "快递鸟电子面单编号",
|
||||
"expressNo": "快递鸟物流跟踪编号",
|
||||
"companyDeleteTips": "确定要删除该数据吗?"
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
{
|
||||
"companyId": "",
|
||||
"companyIdPlaceholder": "请输入",
|
||||
"companyName": "名称",
|
||||
"companyNamePlaceholder": "请输入物流公司名称",
|
||||
"logo": "LOGO",
|
||||
"logoPlaceholder": "请输入物流公司logo",
|
||||
"url": "网址",
|
||||
"urlPlaceholder": "请输入物流公司网址",
|
||||
"expressNo": "快递鸟物流跟踪编号",
|
||||
"expressNoPlaceholder": "请输入快递鸟物流公司编号",
|
||||
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
|
||||
"expressNoKd100": "快递100物流跟踪编号",
|
||||
"expressNoKd100Placeholder": "请输入快递100物流跟踪编号",
|
||||
"addCompany": "添加物流公司",
|
||||
"updateCompany": "编辑物流公司",
|
||||
"expressNoElectronicSheet": "快递鸟电子面单编号",
|
||||
"expressNoElectronicSheetPlaceholder": "请输入快递鸟电子面单编号",
|
||||
"expressNoElectronicSheetTips": "电子面单编号作用于电子面单查询,请根据电子面单对应配置设置编号",
|
||||
"printStyle": "模板样式",
|
||||
"addPrintStyle": "添加模板样式",
|
||||
"expType": "业务类型",
|
||||
"addExpType": "添加业务类型",
|
||||
"expTypeName": "业务名称",
|
||||
"expTypeTextTips": "业务名称不能为空",
|
||||
"expTypeValueTips": "业务值不能为空",
|
||||
"expTypeTextRepeatTips": "业务名称不可以重复,请重新填写",
|
||||
"expTypeValueRepeatTips": "业务值不可以重复,请重新填写",
|
||||
"expTypeValueNullTips": "业务值不可以为零",
|
||||
"expTypeValue": "业务值",
|
||||
"electronicSheetSwitch": "是否支持电子面单",
|
||||
"printStyleName": "模板名称",
|
||||
"printStyleNameTips": "模板名称不能为空",
|
||||
"printStyleSizeTips": "模板尺寸不能为空",
|
||||
"printStyleNameRepeatTips": "模板名称不可以重复,请重新填写",
|
||||
"printStyleSizeRepeatTips": "模板尺寸不可以重复,请重新填写",
|
||||
"printStyleId": "模板尺寸",
|
||||
"expTypeTips": "快递鸟业务类型",
|
||||
"expTypeTips1": "不填默认为1",
|
||||
"printStyleTips": "快递鸟模版规格(常用)",
|
||||
"printStyleTips1": "主流快递单打印纸尺寸一般为:76*130,100*180(单位mm)",
|
||||
"printStyleTips2": "不填写则取物流公司的默认模板",
|
||||
"examine": "点击查看"
|
||||
}
|
||||
11
niucloud/addon/shop/admin/lang/zh-cn/delivery.config.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"store": "启动门店自提后,买家可选择自提点提货。",
|
||||
"express": "启用物流配送后,买家下单可以选择快递发货。",
|
||||
"local_delivery": "启用同城配送后,在配送范围内的买家可以选择同城配送。",
|
||||
"deliveryStaff": "配送员",
|
||||
"deliveryCompany": "物流公司",
|
||||
"deliveryTemplate": "运费模版",
|
||||
"deliverySearch": "物流跟踪",
|
||||
"deliveryStore": "自提点",
|
||||
"localConfig": "同城配送设置"
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"tabESTemplate": "电子面单模板",
|
||||
"tabESConfig": "设置",
|
||||
"templateName": "模板名称",
|
||||
"templateNamePlaceholder": "请输入模板名称",
|
||||
"expressCompany": "物流公司",
|
||||
"expressCompanyPlaceholder": "请选择物流公司",
|
||||
"status": "状态",
|
||||
"statusOn": "开启",
|
||||
"statusOff": "关闭",
|
||||
"addElectronicSheet": "添加电子面单",
|
||||
"payType": "邮费支付方式",
|
||||
"isDefault": "默认",
|
||||
"setDefault": "设为默认",
|
||||
"electronicSheetDeleteTips": "确定要删除该数据吗?",
|
||||
"electronicSheetSetDefaultTips": "确定要设置为默认模版吗?"
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
{
|
||||
"tabESTemplate": "电子面单模板",
|
||||
"tabESConfig": "设置",
|
||||
"apiSet": "接口设置",
|
||||
"interfaceType": "接口类型",
|
||||
"prompt": "提示",
|
||||
"promptTips1-1": "请到快递鸟官网申请",
|
||||
"kdn": "快递鸟",
|
||||
"kdnEBusinessIDLabel": "用户ID",
|
||||
"kdnEBusinessIDPlaceholder": "请输入快递鸟用户ID",
|
||||
"kdnEBusinessIDTips": "快递鸟用户ID,EBusinessID",
|
||||
"kdnAppKeyPlaceholder": "请输入快递鸟API key",
|
||||
"kdnAppKeyTips": "快递鸟分配的API key",
|
||||
"printerSet": "打印机设置",
|
||||
"serverPort1": "服务器端口1",
|
||||
"serverPort1Placeholder": "请输入服务器端口1",
|
||||
"serverPort2": "服务器端口2",
|
||||
"serverPort2Placeholder": "请输入服务器端口2",
|
||||
"httpsPort": "HTTPS端口",
|
||||
"httpsPortPlaceholder": "请输入HTTPS端口"
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"basicSettings": "基础设置",
|
||||
"otherSettings": "其他设置",
|
||||
"templateName": "模板名称",
|
||||
"templateNamePlaceholder": "请输入模板名称",
|
||||
"expressCompany": "物流公司",
|
||||
"expressCompanyPlaceholder": "请选择物流公司",
|
||||
"expType": "业务类型",
|
||||
"status": "状态",
|
||||
"customerName": "CustomerName",
|
||||
"customerNamePlaceholder": "请输入电子面单客户账号",
|
||||
"customerPwd": "CustomerPwd",
|
||||
"customerPwdTips": "电子面单密码,不同快递叫法不同,例如:密码、密钥、客户编号",
|
||||
"sendSite": "SendStaff",
|
||||
"sendSiteTips": "不同快递叫法不同,例如:网点编码、网点编号、网点名称",
|
||||
"sendStaff": "SendStaff",
|
||||
"sendStaffTips": "不同快递叫法不同,例如:收件快递员、取件员编号、网点名称",
|
||||
"monthCode": "MonthCode",
|
||||
"monthCodeTips": "不同快递叫法不同,例如:月结号、密钥、月结编码",
|
||||
"payType": "邮费支付方式",
|
||||
"isNotice": "快递员上门揽件",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"isNoticeTips": "是否通知快递员上门揽件,跨越速运,京东快运,电商标快,填舱标快,填舱电标等业务类型必填",
|
||||
"printStyle": "模板样式",
|
||||
"printStylePlaceholder": "请选择模板样式",
|
||||
"printStyleTips": "快递鸟模版规格(常用)",
|
||||
"printStyleTips1": "主流快递单打印纸尺寸一般为:76*130,100*180(单位mm)",
|
||||
"printStyleTips2": "不填写则取物流公司的默认模板",
|
||||
"isDefault": "是否默认",
|
||||
"examine": "点击查看",
|
||||
"customerNameTips": "快递鸟电子面单账号申请",
|
||||
"customerNameTips1": "电子面单账号对照表"
|
||||
}
|
||||
91
niucloud/addon/shop/admin/lang/zh-cn/delivery.local.json
Normal file
@ -0,0 +1,91 @@
|
||||
{
|
||||
"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": "请填写完整的三方配送配置"
|
||||
}
|
||||
21
niucloud/addon/shop/admin/lang/zh-cn/delivery.search.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"prompt": "提示",
|
||||
"promptTips1-1": "请到快递鸟官网申请",
|
||||
"promptTips1-2": "1、按单付费查询,相同单号查询多次计费一次(代码8001)",
|
||||
"promptTips1-3": "2、按次付费查询,相同单号查询多次计费多次(代码8002)",
|
||||
"promptTips2": "请到快递100官网申请",
|
||||
"interfaceType": "接口类型",
|
||||
"kdn": "快递鸟",
|
||||
"kd100": "快递100",
|
||||
"kdnEBusinessIDPlaceholder": "请输入快递鸟EBusinessID",
|
||||
"kdnEBusinessIDTips": "快递鸟电商ID",
|
||||
"kdnAppKeyPlaceholder": "请输入快递鸟AppKey",
|
||||
"kdnAppKeyTips": "快递鸟分配的电商加密私钥",
|
||||
"isPayEdition": "套餐类型",
|
||||
"PayPerUse": "按次付费",
|
||||
"PayPerOrder": "按单付费",
|
||||
"kd100AppKeyPlaceholder": "请输入快递100AppKey",
|
||||
"kd100AppKeyTips": "快递100应用密钥",
|
||||
"kd100CustomerPlaceholder": "请输入快递100Customer",
|
||||
"kd100CustomerTips": "快递100分配给的公司编号"
|
||||
}
|
||||
9
niucloud/addon/shop/admin/lang/zh-cn/delivery.staff.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"addDeliveryPersonnel": "添加配送员",
|
||||
"updateDeliver": "编辑配送员",
|
||||
"deliverName": "配送员名称",
|
||||
"deliverMobile": "配送员手机号",
|
||||
"deliverNamePlaceholder": "请输入配送员名称",
|
||||
"deliverMobilePlaceholder": "请输入配送员手机号",
|
||||
"deliverDeleteTips": "确定要删除该数据吗?"
|
||||
}
|
||||
18
niucloud/addon/shop/admin/lang/zh-cn/delivery.store.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"storeId": "",
|
||||
"storeName": "自提点信息",
|
||||
"storeNamePlaceholder": "请输入自提点名称",
|
||||
"storeLogo": "自提点logo",
|
||||
"storeMobile": "联系电话",
|
||||
"address": "详细地址",
|
||||
"fullAddress": "联系地址",
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"tradeTime": "营业时间",
|
||||
"createTime": "添加时间",
|
||||
"createTimePlaceholder": "请输入添加时间",
|
||||
"addStore": "添加自提点",
|
||||
"updateStore": "编辑自提点",
|
||||
"storeDeleteTips": "确定要删除该数据吗?",
|
||||
"storeInfo": "自提点信息"
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
{
|
||||
"storeName": "自提点名称",
|
||||
"storeDesc": "简介",
|
||||
"storeLogo": "自提点logo",
|
||||
"storeMobile": "手机号",
|
||||
"provinceId": "省id",
|
||||
"cityId": "市",
|
||||
"districtId": "县(区)",
|
||||
"address": "详细地址",
|
||||
"fullAddress": "完整地址",
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"tradeTime": "营业时间",
|
||||
"createTime": "下单时间",
|
||||
"updateTime": "更新时间",
|
||||
"storeNamePlaceholder": "请输入自提点名称",
|
||||
"storeDescPlaceholder": "请输入简介",
|
||||
"storeLogoPlaceholder": "请上传自提点logo",
|
||||
"storeMobilePlaceholder": "请输入手机号",
|
||||
"provinceIdPlaceholder": "请选择省id",
|
||||
"cityIdPlaceholder": "请选择市",
|
||||
"districtIdPlaceholder": "请选择县(区)",
|
||||
"addressPlaceholder": "请输入详细地址",
|
||||
"fullAddressPlaceholder": "请输入完整地址",
|
||||
"longitudePlaceholder": "请输入经度",
|
||||
"latitudePlaceholder": "请输入纬度",
|
||||
"tradeTimePlaceholder": "请输入营业时间",
|
||||
"tradeTimeTips": "例:上午9:00-12:00,下午2:00-6:00",
|
||||
"createTimePlaceholder": "请选择添加时间",
|
||||
"updateTimePlaceholder": "请输入更新时间",
|
||||
"addStore": "添加自提点",
|
||||
"updateStore": "编辑自提点",
|
||||
"storeDeleteTips": "确定要删除该自提点吗?",
|
||||
"storeAddress": "自提点地址",
|
||||
"storeAddressPlaceholder": "请选择自提点地址",
|
||||
"storeAddressDetail": "自提点详细地址",
|
||||
"storeAddressDetailPlaceholder": "请输入自提点详细地址",
|
||||
"storeTime": "自提时段",
|
||||
"storeDate": "自提日期",
|
||||
"addTimeRange": "添加时段",
|
||||
"storeTimeInterval": "细分时段",
|
||||
"monday": "周一",
|
||||
"tuesday": "周二",
|
||||
"wednesday": "周三",
|
||||
"thursday": "周四",
|
||||
"friday": "周五",
|
||||
"saturday": "周六",
|
||||
"sunday": "周日",
|
||||
"minute": "分钟",
|
||||
"hour": "小时",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"tradeTimePlaceholderTwo": "请选择自提时段",
|
||||
"selectBusinessDays": "请选择自提日期",
|
||||
"tradeTimePlaceholderThree": "请选择细分时段",
|
||||
"tradeTimePlaceholderFour": "结束时间不能小于或等于开始时间",
|
||||
"tradeTimePlaceholderFive": "后一个时间段的开始时间不能小于前一个时间段的结束时间",
|
||||
"storeDateTips": "所设时间段为可自提时间段,可通过“细分时段”对该自提时段进一步切分",
|
||||
"storeTimeIntervalTips": "对上方的“自提时段”进行切分,在手机端上将显示切换后的时段供用户选择"
|
||||
}
|
||||
12
niucloud/addon/shop/admin/lang/zh-cn/delivery.template.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"templateName": "运费模板名称",
|
||||
"templateNamePlaceholder": "请输入运费模板名称",
|
||||
"createTime": "创建时间",
|
||||
"addTemplate": "添加运费模板",
|
||||
"updateTemplate": "编辑运费模板",
|
||||
"templateDeleteTips": "确定要删除该模板吗?",
|
||||
"feeTypeName": "计费类型",
|
||||
"freeShipping": "指定区域包邮",
|
||||
"open": "启用",
|
||||
"close": "关闭"
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
{
|
||||
"templateName": "运费模板名称",
|
||||
"templateNamePlaceholder": "请输入运费模板名称",
|
||||
"createTime": "创建时间",
|
||||
"addTemplate": "添加运费模板",
|
||||
"updateTemplate": "编辑运费模板",
|
||||
"templateDeleteTips": "确定要删除该模板吗?",
|
||||
"feeTypeName": "计费类型",
|
||||
"isDefault": "默认模板",
|
||||
"num": "按件",
|
||||
"weight": "按重量",
|
||||
"volume": "按体积",
|
||||
"feeSetting": "费用设置",
|
||||
"selectArea": "选择地区",
|
||||
"firstNum": "首件(件)",
|
||||
"continueNum": "续件(件)",
|
||||
"firstWeight": "首件重量(kg)",
|
||||
"fee": "运费(元)",
|
||||
"continueFee": "续费(元)",
|
||||
"continueWeight": "续件重量(kg)",
|
||||
"firstVolume": "首件体积(m³)",
|
||||
"continueVolume": "续件体积(m³)",
|
||||
"deliveryArea": "配送区域",
|
||||
"addDeliveryArea": "添加单独配送区域",
|
||||
"freeShipping": "指定区域包邮",
|
||||
"freeShippingArea": "包邮区域",
|
||||
"addFreeShippingArea": "添加包邮区域",
|
||||
"freeShippingAreaTips": "两个条件满足其一便可以包邮",
|
||||
"noDelivery": "不配送区域",
|
||||
"addNoDelivery": "添加不配送区域",
|
||||
"freeShippingNum": "包邮件数",
|
||||
"freeShippingWeight": "包邮重量(kg)",
|
||||
"freeShippingVolume": "包邮体积(m³)",
|
||||
"freeShippingPrice": "包邮金额",
|
||||
"areaPlaceholder": "请选择地区",
|
||||
"noDeliveryPlaceholder": "请选择不配送的地区",
|
||||
"freeShippingPlaceholder": "请选择包邮的地区",
|
||||
"notUnderZero": "不能小于等于0"
|
||||
}
|
||||
10
niucloud/addon/shop/admin/lang/zh-cn/goods.attr.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"attrName": "参数模板名称",
|
||||
"attrNamePlaceholder": "请输入参数模板名称",
|
||||
"sortPlaceholder": "请输入排序号",
|
||||
"addShopGoodsAttr": "添加参数模板",
|
||||
"updateShopGoodsAttr": "编辑参数模板",
|
||||
"goodsAttrDeleteTips": "确定要删除该数据吗?",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"manage": "管理"
|
||||
}
|
||||
18
niucloud/addon/shop/admin/lang/zh-cn/goods.attr_edit.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"attrName": "参数模板名称",
|
||||
"attrNamePlaceholder": "请输入参数名称",
|
||||
"updateAttr": "编辑参数模板",
|
||||
"sort": "排序号",
|
||||
"sortPlaceholder": "请输入排序号",
|
||||
"addShopGoodsAttr": "添加商品参数",
|
||||
"attrValueType": "参数类型",
|
||||
"attrValueTypeRadio": "单选",
|
||||
"attrValueTypeCheckbox": "多选",
|
||||
"attrValueTypeText": "输入",
|
||||
"attrValueChild": "参数内容",
|
||||
"updateShopGoodsAttr": "编辑商品参数",
|
||||
"goodsAttrDeleteTips": "确定要删除该数据吗?",
|
||||
"attrValueName": "参数名称",
|
||||
"addAttrValue": "添加参数",
|
||||
"attrValueNamePlaceholder": "请输入参数名称"
|
||||
}
|
||||
19
niucloud/addon/shop/admin/lang/zh-cn/goods.brand_list.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"brandId": "品牌ID",
|
||||
"brandIdPlaceholder": "请输入品牌ID",
|
||||
"brandName": "品牌名称",
|
||||
"brandNamePlaceholder": "请输入品牌名称",
|
||||
"logo": "品牌logo",
|
||||
"logoPlaceholder": "请输入品牌logo",
|
||||
"desc": "品牌介绍",
|
||||
"descPlaceholder": "请输入品牌介绍",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序",
|
||||
"addBrand": "添加商品品牌",
|
||||
"updateBrand": "编辑商品品牌",
|
||||
"brandDeleteTips": "确定要删除该数据吗?",
|
||||
"textColor": "文字颜色",
|
||||
"bgColor": "背景颜色",
|
||||
"borderColor": "边框颜色",
|
||||
"colorTips": "若未设置颜色,则为默认色"
|
||||
}
|
||||
26
niucloud/addon/shop/admin/lang/zh-cn/goods.category.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"categoryId": "商品分类id",
|
||||
"categoryIdPlaceholder": "请输入商品分类id",
|
||||
"categoryName": "分类名称",
|
||||
"categoryNamePlaceholder": "请输入分类名称",
|
||||
"image": "分类图片",
|
||||
"imagePlaceholder": "请输入分类图片",
|
||||
"pid": "上级分类",
|
||||
"pidPlaceholder": "请选择上级分类",
|
||||
"categoryFullName": "组装分类名称",
|
||||
"categoryFullNamePlaceholder": "请输入组装分类名称",
|
||||
"isShow": "是否显示",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序号",
|
||||
"addCategory": "添加商品分类",
|
||||
"updateCategory": "编辑商品分类",
|
||||
"categoryDeleteTips": "确定要删除该数据吗?",
|
||||
"categoryDeleteTips1": "子级分类也会删除,确定要删除该数据吗?",
|
||||
"spreadGoodsCategory": "推广",
|
||||
"goodsCategorySpreadTitle": "商品分类推广",
|
||||
"spreadLink": "推广链接",
|
||||
"copy": "复制",
|
||||
"downloadQrcode": "下载二维码",
|
||||
"tabGoodsCategory": "商品分类",
|
||||
"tabGoodsCategoryConfig": "分类设置"
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
{
|
||||
"categoryTemplate": "分类模板",
|
||||
"categoryType": "分类类型",
|
||||
"categorystyleOne": "一级分类",
|
||||
"categorystyleTwo": "二级分类",
|
||||
"pageSettings": "页面设置",
|
||||
"pageTitle": "页面名称",
|
||||
"pageTitlePlaceholder": "请输入页面名称",
|
||||
"searchControl": "搜索栏",
|
||||
"searchTitle": "搜索栏文字",
|
||||
"searchTitlePlaceholder": "请输入搜索栏文字",
|
||||
"open": "开启",
|
||||
"close": "关闭",
|
||||
"goodsStyle": "商品排列",
|
||||
"singleCols": "单列",
|
||||
"doubleCols": "双列",
|
||||
"sort": "商品排序",
|
||||
"sortPlaceholder": "请选择商品排序",
|
||||
"cartControl": "购物车显示",
|
||||
"cartStyle": "购物车样式",
|
||||
"cartTextPlaceholder": "请输入购物车按钮文字",
|
||||
"cartEvent": "点击按钮",
|
||||
"detail": "跳转商品详情",
|
||||
"cart": "加入购物车",
|
||||
"tabGoodsCategory": "商品分类",
|
||||
"tabGoodsCategoryConfig": "分类设置"
|
||||
}
|
||||
59
niucloud/addon/shop/admin/lang/zh-cn/goods.evaluate.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"evaluateId": "",
|
||||
"evaluateIdPlaceholder": "请输入",
|
||||
"orderId": "订单id",
|
||||
"orderIdPlaceholder": "请输入订单id",
|
||||
"orderGoodsId": "订单项ID",
|
||||
"orderGoodsIdPlaceholder": "请输入订单项ID",
|
||||
"goodsId": "商品ID",
|
||||
"goodsIdPlaceholder": "请选择商品",
|
||||
"memberId": "会员ID",
|
||||
"memberIdPlaceholder": "请输入会员ID",
|
||||
"content": "评价内容",
|
||||
"contentPlaceholder": "请输入评价内容",
|
||||
"images": "评价图片",
|
||||
"imagesPlaceholder": "请输入评价图片",
|
||||
"isAnonymous": "是否匿名",
|
||||
"anonymous": "匿名",
|
||||
"notAnonymous": "不匿名",
|
||||
"scores": "评价等级",
|
||||
"scoresPlaceholder": "请输入评价分数 1-5",
|
||||
"auditName": "审核状态",
|
||||
"explainFirst": "商家回复",
|
||||
"explainFirstPlaceholder": "请输入商家回复",
|
||||
"createTime": "评价时间",
|
||||
"createTimePlaceholder": "请输入评价时间",
|
||||
"again": "追评",
|
||||
"againTime": "追评时间",
|
||||
"againTimePlaceholder": "请输入追评时间",
|
||||
"isShow": "是否显示",
|
||||
"show": "显示",
|
||||
"notShow": "不显示",
|
||||
"isShowPlaceholder": "请输入是否显示 1显示 2不显示",
|
||||
"addEvaluate": "添加自评",
|
||||
"updateEvaluate": "编辑商品评价",
|
||||
"evaluateDeleteTips": "确定要删除该数据吗?",
|
||||
"goodsInfo": "商品信息",
|
||||
"memberHead": "会员头像",
|
||||
"memberName": "会员名称",
|
||||
"memberNamePlaceholder": "请输入会员名称",
|
||||
"adopt": "通过",
|
||||
"refuse": "拒绝",
|
||||
"auditAdoptTips": "确定要通过审核吗?",
|
||||
"reply": "回复",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"topping": "置顶",
|
||||
"cancelTopping": "取消置顶",
|
||||
"memberHeadPlaceholder": "请上传会员头像",
|
||||
"batchDelete": "批量删除",
|
||||
"batchDeleteTips": "确定要批量删除选中的评价吗?",
|
||||
"batchAdopt": "批量通过",
|
||||
"batchAdoptTips": "确定要批量通过选中的评价吗?",
|
||||
"batchRefuse": "批量拒绝",
|
||||
"batchRefuseTips": "确定要批量拒绝选中的评价吗?",
|
||||
"batchEmptySelectedCommentsTips": "请先选择要操作的评价",
|
||||
"status":"审核状态",
|
||||
"statusPlaceholder":"请选择审核状态"
|
||||
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"orderId": "订单id",
|
||||
"orderGoodsId": "订单项ID",
|
||||
"goodsId": "商品ID",
|
||||
"memberId": "会员ID",
|
||||
"content": "评价内容",
|
||||
"images": "评价图片",
|
||||
"isAnonymous": "0 匿名 1不匿名",
|
||||
"scores": "评价分数 1-5",
|
||||
"isAudit": "审核状态 1待审 2通过 3拒绝",
|
||||
"explainFirst": "解释内容",
|
||||
"againContent": "追评内容",
|
||||
"againImages": "追评图片",
|
||||
"againExplain": "追评解释",
|
||||
"againTime": "追评时间",
|
||||
"againIsAudit": "审核状态 1待审 2通过 3拒绝",
|
||||
"isShow": "是否显示 1显示 2不显示",
|
||||
"orderIdPlaceholder": "请输入订单id",
|
||||
"orderGoodsIdPlaceholder": "请输入订单项ID",
|
||||
"goodsIdPlaceholder": "请输入商品ID",
|
||||
"memberIdPlaceholder": "请输入会员ID",
|
||||
"contentPlaceholder": "请输入评价内容",
|
||||
"imagesPlaceholder": "请上传评价图片",
|
||||
"isAnonymousPlaceholder": "请输入0 匿名 1不匿名",
|
||||
"scoresPlaceholder": "请输入评价分数 1-5",
|
||||
"isAuditPlaceholder": "请输入审核状态 1待审 2通过 3拒绝",
|
||||
"explainFirstPlaceholder": "请输入解释内容",
|
||||
"againContentPlaceholder": "请输入追评内容",
|
||||
"againImagesPlaceholder": "请上传追评图片",
|
||||
"againExplainPlaceholder": "请输入追评解释",
|
||||
"againTimePlaceholder": "请输入追评时间",
|
||||
"againIsAuditPlaceholder": "请输入审核状态 1待审 2通过 3拒绝",
|
||||
"isShowPlaceholder": "请输入是否显示 1显示 2不显示",
|
||||
"addEvaluate": "添加商品评价",
|
||||
"updateEvaluate": "编辑商品评价",
|
||||
"evaluateDeleteTips": "确定要删除该商品评价吗?"
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"tabGoodsLabel": "商品标签",
|
||||
"tabGoodsLabelGroup": "标签分组",
|
||||
"groupName": "分组名称",
|
||||
"groupNamePlaceholder": "请输入分组名称",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序",
|
||||
"addLabelGroup": "添加标签分组",
|
||||
"updateLabelGroup": "编辑标签分组",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"labelGroupDeleteTips": "确定要删除该数据吗?"
|
||||
}
|
||||
32
niucloud/addon/shop/admin/lang/zh-cn/goods.label_list.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"tabGoodsLabel": "商品标签",
|
||||
"tabGoodsLabelGroup": "标签分组",
|
||||
"labelName": "标签名称",
|
||||
"labelNamePlaceholder": "请输入标签名称",
|
||||
"groupName": "标签分组",
|
||||
"groupNamePlaceholder": "请选择标签分组",
|
||||
"styleType": "效果设置",
|
||||
"styleByDiy": "自定义",
|
||||
"styleByIcon": "图片",
|
||||
"textColor": "文字颜色",
|
||||
"bgColor": "背景颜色",
|
||||
"borderColor": "边框颜色",
|
||||
"colorTips": "若未设置颜色,则为默认色",
|
||||
"icon": "上传图片",
|
||||
"iconTips": "建议尺寸:80px*30px,若未上传将显示默认",
|
||||
"memo": "标签说明",
|
||||
"memoPlaceholder": "请输入标签说明",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序",
|
||||
"addLabel": "添加商品标签",
|
||||
"updateLabel": "编辑商品标签",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"labelDeleteTips": "确定要删除该数据吗?",
|
||||
"statusOn": "开启",
|
||||
"statusOff": "关闭",
|
||||
"status": "状态",
|
||||
"label": "标签",
|
||||
"createTime": "创建时间",
|
||||
"copyLabel": "复制",
|
||||
"labelCopyTips": "确定要复制该标签吗?"
|
||||
}
|
||||
139
niucloud/addon/shop/admin/lang/zh-cn/goods.list.json
Normal file
@ -0,0 +1,139 @@
|
||||
{
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsCategory": "商品分类",
|
||||
"goodsCategoryPlaceholder": "全部",
|
||||
"goodsType": "商品类型",
|
||||
"goodsTypePlaceholder": "请选择商品类型",
|
||||
"brand": "商品品牌",
|
||||
"brandPlaceholder": "请输入商品品牌",
|
||||
"labelIds": "商品标签",
|
||||
"labelIdsPlaceholder": "请选择商品标签",
|
||||
"saleNum": "销量",
|
||||
"startSaleNumPlaceholder": "最低销量",
|
||||
"startSaleNumTips": "最低销量输入错误",
|
||||
"endSaleNumPlaceholder": "最高销量",
|
||||
"endSaleNumTips": "最高销量输入错误",
|
||||
"shopSaleNumTips": "最低销量不能大于最高销量",
|
||||
"skuPrice": "价格",
|
||||
"startPricePlaceholder": "最低价格",
|
||||
"startPriceTips": "最低价格输入错误",
|
||||
"endPricePlaceholder": "最高价格",
|
||||
"endPriceTips": "最高价格输入错误",
|
||||
"shopPriceTips": "最低价格不能大于最高价格",
|
||||
"statusOn": "销售中",
|
||||
"statusOff": "仓库中",
|
||||
"statusAll": "全部商品",
|
||||
"batchOnGoods": "批量上架",
|
||||
"batchOffGoods": "批量下架",
|
||||
"batchDeleteGoods": "批量删除",
|
||||
"batchSetting": "批量设置",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"goodsInfo": "商品",
|
||||
"stock": "库存",
|
||||
"status": "状态",
|
||||
"sort": "排序",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"createTime": "创建时间",
|
||||
"addGoods": "添加商品",
|
||||
"statusActionOn": "上架",
|
||||
"statusActionOff": "下架",
|
||||
"statusChangeTips": "确定要下架该商品吗?",
|
||||
"spreadGoods": "推广",
|
||||
"copyGoods": "复制",
|
||||
"updateGoods": "编辑商品",
|
||||
"goodsCopyTips": "确定要复制该商品吗?",
|
||||
"goodsDeleteTips": "确定要删除该商品吗?",
|
||||
"batchGoodsDeleteTips": "确定要删除这些商品吗",
|
||||
"batchOperationSku": "批量设置",
|
||||
"editStockPopupTitle": "编辑商品库存",
|
||||
"editPricePopupTitle": "编辑商品价格",
|
||||
"skuName": "规格名称",
|
||||
"price": "销售价",
|
||||
"pricePlaceholder": "请输入销售价",
|
||||
"priceTips": "销售价格式输入错误",
|
||||
"priceNotZeroTips": "销售价不能小于0",
|
||||
"marketPrice": "划线价",
|
||||
"marketPricePlaceholder": "请输入划线价",
|
||||
"marketPriceTips": "划线价格式输入错误",
|
||||
"marketPriceNotZeroTips": "划线价不能小于0",
|
||||
"market_price": "划线价",
|
||||
"market_pricePlaceholder": "请输入划线价",
|
||||
"market_priceTips": "划线价格式输入错误",
|
||||
"market_priceNotZeroTips": "划线价不能小于0",
|
||||
"costPrice": "成本价",
|
||||
"costPricePlaceholder": "请输入成本价",
|
||||
"costPriceTips": "成本价格式输入错误",
|
||||
"costPriceNotZeroTips": "成本价不能小于0",
|
||||
"cost_price": "成本价",
|
||||
"cost_pricePlaceholder": "请输入成本价",
|
||||
"cost_priceTips": "成本价格式输入错误",
|
||||
"cost_priceNotZeroTips": "成本价不能小于0",
|
||||
"stockPlaceholder": "请输入库存",
|
||||
"stockTips": "库存格式输入错误",
|
||||
"stockNotZeroTips": "库存不能小于0",
|
||||
"goodsSpreadTitle": "商品推广",
|
||||
"spreadLink": "推广链接",
|
||||
"copy": "复制",
|
||||
"downloadQrcode": "下载二维码",
|
||||
"memberPrice": "会员价",
|
||||
"editMemberPricePopupTitle": "编辑会员价",
|
||||
"memberDiscount": "会员价优惠方式",
|
||||
"discount": "会员折扣",
|
||||
"fixedPrice": "指定会员价",
|
||||
"nonparticipation": "不参与",
|
||||
"goodsSku": "商品规格",
|
||||
"memberEnjoyDiscount": "会员享受折扣",
|
||||
"discountUnit": "折",
|
||||
"yuanUnit": "元",
|
||||
"editMemberPrice": "修改会员价",
|
||||
"memberLevel": "会员等级",
|
||||
"memberPricePlaceholder": "请输入会员价",
|
||||
"discountHint": "会员折扣说明:按照默认会员等级折扣优惠",
|
||||
"fixedPriceHint": "会员价说明:指定优惠价格,商品未参与活动时,按照会员价优惠,若商品参与活动,则以活动价为准",
|
||||
"addGoodsLabel": "添加商品标签",
|
||||
"addGoodsService": "添加商品服务",
|
||||
"addGoodsCategory": "添加分类",
|
||||
"addGoodsBrand": "添加品牌",
|
||||
"addGoodsPoster": "添加海报",
|
||||
"virtualSaleNumPlaceholder": "请输入虚拟销量",
|
||||
"posterPlaceholder": "请选择商品海报",
|
||||
"goodsCategoryPlaceholderTwo": "请选择商品分类",
|
||||
"virtualSaleNumDesc": "虚拟销量只在前台展示中参与计算",
|
||||
"virtualSaleNumTips": "虚拟销量格式输入错误",
|
||||
"virtualSaleNumNotZeroTips": "虚拟销量不能小于0",
|
||||
"giftTips": "当商品设置为赠品时,该商品仅用于活动赠送,不会在前台展示或出售",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"isFreeShipping": "是否免邮",
|
||||
"feeType": "运费设置",
|
||||
"selectTemplate": "选择模板",
|
||||
"fixedShipping": "统一运费",
|
||||
"deliveryMoney": "固定运费",
|
||||
"deliveryMoneyPlaceholder": "请输入固定运费",
|
||||
"deliveryMoneyTips": "固定运费格式输入错误",
|
||||
"deliveryMoneyNotZeroTips": "固定运费不能小于0",
|
||||
"deliveryTemplateId": "运费模板",
|
||||
"deliveryTemplateIdPlaceholder": "请选择运费模板",
|
||||
"addDeliveryTemplateId": "添加运费模板",
|
||||
"deliveryType": "配送方式",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"yuan": "元",
|
||||
"label": "商品标签",
|
||||
"service": "商品服务",
|
||||
"virtualSaleNum": "虚拟销量",
|
||||
"goodsBrand": "商品品牌",
|
||||
"goodsPoster": "商品海报",
|
||||
"isGift": "是否赠品",
|
||||
"batchSettingTip": "每次仅能设置一项,点击确认成功之后生效",
|
||||
"setStock": "修改库存",
|
||||
"addStock": "增加库存",
|
||||
"reduceStock": "减少库存",
|
||||
"stockNum": "目标数值",
|
||||
"stockNumTips": "批量调整商品库存,若商品正在参与营销活动,则不会修改库存",
|
||||
"confirm": "确认",
|
||||
"diyForm": "万能表单",
|
||||
"diyFormPlaceholder": "请选择万能表单",
|
||||
"addDiyForm": "添加表单",
|
||||
"productClassificationPlaceholder":"请选择商品分类"
|
||||
}
|
||||
171
niucloud/addon/shop/admin/lang/zh-cn/goods.real_edit.json
Normal file
@ -0,0 +1,171 @@
|
||||
{
|
||||
"addGoods": "添加商品",
|
||||
"updateGoods": "编辑商品",
|
||||
"basicInfoTab": "基础信息",
|
||||
"goodsType": "商品类型",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsNameMaxLengthTips": "商品名称不能超过60个字符",
|
||||
"subTitle": "副标题",
|
||||
"subTitlePlaceholder": "请输入副标题",
|
||||
"subTitleMaxLengthTips": "副标题不能超过100个字符",
|
||||
"goodsImage": "商品图片",
|
||||
"goodsImagePlaceholder": "请上传商品图片",
|
||||
"goodsVideo": "商品视频",
|
||||
"goodsVideoPlaceholder": "请上传商品视频",
|
||||
"goodsVideoTipTile": "注意事项:",
|
||||
"goodsVideoTipOne": "1、检查upload文件夹是否有读写权限。",
|
||||
"goodsVideoTipTwo": "2、PHP默认上传限制为2MB,需要在php.ini配置文件中修改“post_max_size”和“upload_max_filesize”的大小。",
|
||||
"goodsVideoTipThree": "3、视频支持手动输入外链视频地址或者上传本地视频文件",
|
||||
"goodsVideoTipFour": "4、必须上传.mp4视频格式",
|
||||
"goodsVideoTipFive": "5、视频文件大小不能超过500MB",
|
||||
"goodsCategory": "商品分类",
|
||||
"refresh": "刷新",
|
||||
"addGoodsCategory": "添加分类",
|
||||
"goodsCategoryPlaceholder": "请选择商品分类",
|
||||
"brand": "商品品牌",
|
||||
"brandPlaceholder": "请输入商品品牌",
|
||||
"addGoodsBrand": "添加品牌",
|
||||
"poster": "商品海报",
|
||||
"posterPlaceholder": "请选择商品海报",
|
||||
"addGoodsPoster": "添加海报",
|
||||
"posterTips": "不设置将使用默认海报",
|
||||
"diyForm": "万能表单",
|
||||
"diyFormPlaceholder": "请选择万能表单",
|
||||
"addDiyForm": "添加表单",
|
||||
"label": "商品标签",
|
||||
"addGoodsLabel": "添加商品标签",
|
||||
"goodsService": "商品服务",
|
||||
"addGoodsService": "添加商品服务",
|
||||
"supplier": "供应商",
|
||||
"supplierPlaceholder": "请选择供应商",
|
||||
"addSupplier": "添加供应商",
|
||||
"status": "商品状态",
|
||||
"statusOn": "上架",
|
||||
"statusOff": "下架",
|
||||
"isGive": "是否赠品",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"priceStockTab": "价格库存",
|
||||
"specType": "规格类型",
|
||||
"singleSpec": "单规格",
|
||||
"multiSpec": "多规格",
|
||||
"price": "销售价",
|
||||
"marketPrice": "划线价",
|
||||
"costPrice": "成本价",
|
||||
"weight": "重量",
|
||||
"volume": "体积",
|
||||
"goodsStock": "商品库存",
|
||||
"goodsStockPlaceholder": "请输入商品库存",
|
||||
"skuNo": "商品编码",
|
||||
"yuan": "元",
|
||||
"defaultUnit": "件",
|
||||
"skuNoPlaceholder": "请输入商品编码",
|
||||
"goodsSku": "商品规格",
|
||||
"specNamePlaceholder": "请输入规格项,如颜色、尺码、大小",
|
||||
"specValueNamePlaceholder": "请输入规格值,如:白色",
|
||||
"addSpecValue": "+添加规格值",
|
||||
"addSpec": "添加规格",
|
||||
"batchOperationSku": "批量设置",
|
||||
"all": "全部",
|
||||
"stock": "库存",
|
||||
"skuWeight": "重量(kg)",
|
||||
"skuVolume": "体积(m³)",
|
||||
"confirm": "确定",
|
||||
"image": "图片",
|
||||
"defaultSku": "默认规格",
|
||||
"unit": "单位",
|
||||
"unitPlaceholder": "请输入单位,默认为:件",
|
||||
"virtualSaleNum": "虚拟销量",
|
||||
"virtualSaleNumPlaceholder": "请输入虚拟销量",
|
||||
"virtualSaleNumDesc": "虚拟销量只在前台展示中参与计算",
|
||||
"virtualSaleNumTips": "虚拟销量格式输入错误",
|
||||
"virtualSaleNumNotZeroTips": "虚拟销量不能小于0",
|
||||
"giftTips": "当商品设置为赠品时,该商品仅用于活动赠送,不会在前台展示或出售",
|
||||
"maxAddSpecTips": "最多添加5个规格项",
|
||||
"pleaseEditSpecPlaceholder": "请编辑规格信息",
|
||||
"refreshSuccess": "刷新成功",
|
||||
"deliveryTab": "配送设置",
|
||||
"advancedSetup": "高级设置",
|
||||
"diyDetailTemplate": "商品详情模版",
|
||||
"diyDetailTemplatePlaceholder": "请选择商品详情模版",
|
||||
"addDetailTemp": "添加模板",
|
||||
"detailTempTip": "不设置将使用默认商品详情模板",
|
||||
"deliveryType": "配送方式",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"pleaseSelectSku": "请先选择商品规格",
|
||||
"isLimit": "是否限购",
|
||||
"isLimitTips": "启用限购后,购买商品时,会对该商品购买量做限制判断。",
|
||||
"limitType": "限购类型",
|
||||
"limitTypeTips": "单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
|
||||
"singleTime": "单次限购",
|
||||
"singlePerson": "单人限购",
|
||||
"maxBuy": "限购数量",
|
||||
"maxBuyPlaceholder": "请输入限购数量",
|
||||
"maxBuyTips": "[限购数量]格式输入错误",
|
||||
"maxBuyWarnTips": "限购数量超出商品库存时,买家将无法购买该商品",
|
||||
"maxBuyNotZeroTips": "限购数量不能小于1",
|
||||
"minBuy": "起购数量",
|
||||
"minBuyTips": "起购数量超出商品库存时,买家将无法购买该商品",
|
||||
"minBuyFormatErrorTips": "[起购数量]格式输入错误",
|
||||
"minBuyNotZeroTips": "起购数量不能小于0",
|
||||
"minBuyGreaterThanMaxBuyTips": "起购数量不能大于限购数量",
|
||||
"isFreeShipping": "是否免邮",
|
||||
"feeType": "运费设置",
|
||||
"selectTemplate": "选择模板",
|
||||
"fixedShipping": "统一运费",
|
||||
"deliveryMoney": "固定运费",
|
||||
"deliveryMoneyPlaceholder": "请输入固定运费",
|
||||
"deliveryMoneyTips": "固定运费格式输入错误",
|
||||
"deliveryMoneyNotZeroTips": "固定运费不能小于0",
|
||||
"deliveryTemplateId": "运费模板",
|
||||
"deliveryTemplateIdPlaceholder": "请选择运费模板",
|
||||
"addDeliveryTemplateId": "添加运费模板",
|
||||
"goodsDesc": "商品详情",
|
||||
"goodsDescPlaceholder": "请填写商品详情",
|
||||
"goodsDescMaxTips": "商品描述字符数应在5~50000之间",
|
||||
"pricePlaceholder": "请输入销售价",
|
||||
"priceTips": "[销售价]格式输入错误",
|
||||
"priceNotZeroTips": "销售价不能小于0",
|
||||
"marketPricePlaceholder": "请输入划线价",
|
||||
"marketPriceTips": "[划线价]格式输入错误",
|
||||
"marketPriceNotZeroTips": "划线价不能小于0",
|
||||
"costPricePlaceholder": "请输入成本价",
|
||||
"costPriceTips": "[成本价]格式输入错误",
|
||||
"costPriceNotZeroTips": "成本价不能小于0",
|
||||
"weightPlaceholder": "请输入重量",
|
||||
"weightTips": "[重量(kg)]格式输入错误",
|
||||
"weightNotZeroTips": "重量(kg)不能小于0",
|
||||
"volumePlaceholder": "请输入体积",
|
||||
"volumeTips": "[体积(m³)]格式输入错误",
|
||||
"volumeNotZeroTips": "体积(m³)不能小于0",
|
||||
"stockPlaceholder": "请输入库存",
|
||||
"stockTips": "[库存]格式输入错误",
|
||||
"stockNotZeroTips": "库存不能小于0",
|
||||
"specNameRequire": "规格项不能为空",
|
||||
"specNameRepeat": "规格项不能重复",
|
||||
"specValueRequire": "规格值不能为空",
|
||||
"specValueNameRepeat": "规格值不能重复",
|
||||
"lackDefaultSpec": "商品缺少默认规格",
|
||||
"goodsArguments": "商品参数",
|
||||
"goodsArgumentsTemp": "商品参数模板",
|
||||
"goodsArgumentsTempPlaceholder": "请选择商品参数模板",
|
||||
"goodsArgumentsTempHint": "商品可以添加自定义商品参数,也可以通过参数模板批量设置商品参数",
|
||||
"argumentsName": "参数名",
|
||||
"argumentsValue": "参数值",
|
||||
"argumentsSortHint": "设置排序,改变商品规格展示顺序",
|
||||
"operation": "操作",
|
||||
"delAttr": "删除",
|
||||
"noData": "无数据",
|
||||
"addGoodsArguments": "添加商品参数",
|
||||
"memberDiscount": "会员等级折扣",
|
||||
"discount": "会员折扣",
|
||||
"fixedPrice": "指定会员价",
|
||||
"nonparticipation": "不参与",
|
||||
"discountHint": "会员折扣说明:按照默认会员等级折扣优惠",
|
||||
"fixedPriceHint": "会员价说明:指定优惠价格,商品未参与活动时,按照会员价优惠,若商品参与活动,则以活动价为准",
|
||||
"participateInActiveDisableTips": "商品正在参与营销活动,禁止操作"
|
||||
}
|
||||
22
niucloud/addon/shop/admin/lang/zh-cn/goods.recycle.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsCategory": "商品分类",
|
||||
"goodsCategoryPlaceholder": "全部",
|
||||
"goodsType": "商品类型",
|
||||
"goodsTypePlaceholder": "请选择商品类型",
|
||||
"price": "价格",
|
||||
"saleNum": "销量",
|
||||
"statusOn": "销售中",
|
||||
"statusOff": "仓库中",
|
||||
"batchRecycle": "批量恢复",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"goodsInfo": "商品",
|
||||
"stock": "库存",
|
||||
"stockPlaceholder": "请输入商品库存(总和)",
|
||||
"status": "状态",
|
||||
"createTime": "创建时间",
|
||||
"recycle": "恢复",
|
||||
"goodsRecycleTips": "确定要恢复该商品吗?",
|
||||
"batchGoodsRecycleTips": "确定要恢复这些商品吗"
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"goodsSearch": "商品搜索",
|
||||
"goodsCode": "商品编码",
|
||||
"defaultSearch": "默认搜索",
|
||||
"defaultWord": "默认搜索关键词",
|
||||
"defaultWordPlaceholder": "请输入默认搜索关键词",
|
||||
"defaultWordTips": "默认搜索,将显示在前台搜索框,前台点击时直接作为关键词进行搜索",
|
||||
"hotSearch": "热门搜索",
|
||||
"indexKeyword": "搜索的关键字",
|
||||
"searchPlaceholder": "请输入搜索关键字",
|
||||
"addSearch": "添加",
|
||||
"enable": "商品编码唯一性",
|
||||
"enableTips": "开启后,将验证商品编码唯一性,不能重复",
|
||||
"searchTips": "列表中已存在该关键字",
|
||||
"keyWordTips": "搜索关键字不能为空",
|
||||
"goodSort": "商品排序",
|
||||
"sortType": "排序方式",
|
||||
"sortTypePlaceholder": "请选择排序方式",
|
||||
"sortTypeTips": "选择排序方式时,前台商品将依据排序号优先进行正序或倒序排列,当排序号相同时,均按照创建时间倒序排列。",
|
||||
"sortColumn": "排序字段",
|
||||
"sortColumnTips": "请选择用于排序的字段,例如 排序号、价格、销量,不同的排序字段将影响商品的显示优先级。",
|
||||
"sortColumnPlaceholder": "请选择排序字段",
|
||||
"defaultSort": "默认排序值",
|
||||
"defaultSortPlaceholder": "请输入默认排序值",
|
||||
"defaultSortTips": "默认排值是当添加商品时,如果没有设置排序值的情况下,则按照该位置设置的默认数值参与排序 "
|
||||
}
|
||||
10
niucloud/addon/shop/admin/lang/zh-cn/goods.service.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"serviceName": "服务名称",
|
||||
"serviceNamePlaceholder": "请输入服务名称",
|
||||
"desc": "描述",
|
||||
"descPlaceholder": "请输入描述",
|
||||
"addServe": "添加商品服务",
|
||||
"updateServe": "编辑商品服务",
|
||||
"serveDeleteTips": "确定要删除该数据吗?",
|
||||
"imagePlaceholder": "请上传服务图片"
|
||||
}
|
||||
164
niucloud/addon/shop/admin/lang/zh-cn/goods.virtual_edit.json
Normal file
@ -0,0 +1,164 @@
|
||||
{
|
||||
"addGoods": "添加商品",
|
||||
"updateGoods": "编辑商品",
|
||||
"basicInfoTab": "基础信息",
|
||||
"goodsType": "商品类型",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsNameMaxLengthTips": "商品名称不能超过60个字符",
|
||||
"subTitle": "副标题",
|
||||
"subTitlePlaceholder": "请输入副标题",
|
||||
"subTitleMaxLengthTips": "副标题不能超过100个字符",
|
||||
"goodsImage": "商品图片",
|
||||
"goodsImagePlaceholder": "请上传商品图片",
|
||||
"goodsVideo": "商品视频",
|
||||
"goodsVideoPlaceholder": "请上传商品视频",
|
||||
"goodsVideoTipTile": "注意事项:",
|
||||
"goodsVideoTipOne": "1、检查upload文件夹是否有读写权限。",
|
||||
"goodsVideoTipTwo": "2、PHP默认上传限制为2MB,需要在php.ini配置文件中修改“post_max_size”和“upload_max_filesize”的大小。",
|
||||
"goodsVideoTipThree": "3、视频支持手动输入外链视频地址或者上传本地视频文件",
|
||||
"goodsVideoTipFour": "4、必须上传.mp4视频格式",
|
||||
"goodsVideoTipFive": "5、视频文件大小不能超过500MB",
|
||||
"goodsCategory": "商品分类",
|
||||
"advancedSetup": "高级设置",
|
||||
"diyDetailTemplate": "商品详情模版",
|
||||
"diyDetailTemplatePlaceholder": "请选择商品详情模版",
|
||||
"addDetailTemp": "添加模板",
|
||||
"detailTempTip": "不设置将使用默认商品详情模板",
|
||||
"refresh": "刷新",
|
||||
"addGoodsCategory": "添加分类",
|
||||
"goodsCategoryPlaceholder": "请选择商品分类",
|
||||
"brand": "商品品牌",
|
||||
"brandPlaceholder": "请输入商品品牌",
|
||||
"addGoodsBrand": "添加品牌",
|
||||
"poster": "商品海报",
|
||||
"posterPlaceholder": "请选择商品海报",
|
||||
"addGoodsPoster": "添加海报",
|
||||
"posterTips": "不设置将使用默认海报",
|
||||
"diyForm": "万能表单",
|
||||
"diyFormPlaceholder": "请选择万能表单",
|
||||
"addDiyForm": "添加表单",
|
||||
"label": "商品标签",
|
||||
"addGoodsLabel": "添加商品标签",
|
||||
"goodsService": "商品服务",
|
||||
"addGoodsService": "添加商品服务",
|
||||
"supplier": "供应商",
|
||||
"supplierPlaceholder": "请选择供应商",
|
||||
"addSupplier": "添加供应商",
|
||||
"status": "商品状态",
|
||||
"statusOn": "上架",
|
||||
"statusOff": "下架",
|
||||
"isGive": "是否赠品",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"priceStockTab": "价格库存",
|
||||
"specType": "规格类型",
|
||||
"singleSpec": "单规格",
|
||||
"multiSpec": "多规格",
|
||||
"price": "销售价",
|
||||
"marketPrice": "划线价",
|
||||
"costPrice": "成本价",
|
||||
"goodsStock": "商品库存",
|
||||
"goodsStockPlaceholder": "请输入商品库存",
|
||||
"skuNo": "商品编码",
|
||||
"yuan": "元",
|
||||
"defaultUnit": "件",
|
||||
"skuNoPlaceholder": "请输入商品编码",
|
||||
"goodsSku": "商品规格",
|
||||
"specNamePlaceholder": "请输入规格项,如颜色、尺码、大小",
|
||||
"specValueNamePlaceholder": "请输入规格值,如:白色",
|
||||
"addSpecValue": "+添加规格值",
|
||||
"addSpec": "添加规格",
|
||||
"batchOperationSku": "批量设置",
|
||||
"all": "全部",
|
||||
"stock": "库存",
|
||||
"confirm": "确定",
|
||||
"image": "图片",
|
||||
"defaultSku": "默认规格",
|
||||
"unit": "单位",
|
||||
"unitPlaceholder": "请输入单位,默认为:件",
|
||||
"virtualSaleNum": "虚拟销量",
|
||||
"virtualSaleNumPlaceholder": "请输入虚拟销量",
|
||||
"virtualSaleNumDesc": "虚拟销量只在前台展示中参与计算",
|
||||
"virtualSaleNumTips": "虚拟销量格式输入错误",
|
||||
"virtualSaleNumNotZeroTips": "虚拟销量不能小于0",
|
||||
"giftTips": "当商品设置为赠品时,该商品仅用于活动赠送,不会在前台展示或出售",
|
||||
"virtualSetTips": "当设置为店内核销时,若存在未完成的订单,则无法编辑",
|
||||
"maxAddSpecTips": "最多添加5个规格项",
|
||||
"pleaseEditSpecPlaceholder": "请编辑规格信息",
|
||||
"refreshSuccess": "刷新成功",
|
||||
"isLimit": "是否限购",
|
||||
"isLimitTips": "启用限购后,购买商品时,会对该商品购买量做限制判断。",
|
||||
"limitType": "限购类型",
|
||||
"limitTypeTips": "单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
|
||||
"singleTime": "单次限购",
|
||||
"singlePerson": "单人限购",
|
||||
"maxBuy": "限购数量",
|
||||
"maxBuyPlaceholder": "请输入限购数量",
|
||||
"maxBuyTips": "[限购数量]格式输入错误",
|
||||
"maxBuyWarnTips": "限购数量超出商品库存时,买家将无法购买该商品",
|
||||
"maxBuyNotZeroTips": "限购数量不能小于1",
|
||||
"minBuy": "起购数量",
|
||||
"minBuyTips": "起购数量超出商品库存时,买家将无法购买该商品",
|
||||
"minBuyFormatErrorTips": "[起购数量]格式输入错误",
|
||||
"minBuyNotZeroTips": "起购数量不能小于0",
|
||||
"minBuyGreaterThanMaxBuyTips": "起购数量不能大于限购数量",
|
||||
"goodsDesc": "商品详情",
|
||||
"goodsDescPlaceholder": "请填写商品详情",
|
||||
"goodsDescMaxTips": "商品描述字符数应在5~50000之间",
|
||||
"pricePlaceholder": "请输入销售价",
|
||||
"priceTips": "[销售价]格式输入错误",
|
||||
"priceNotZeroTips": "销售价不能小于0",
|
||||
"marketPricePlaceholder": "请输入划线价",
|
||||
"marketPriceTips": "[划线价]格式输入错误",
|
||||
"marketPriceNotZeroTips": "划线价不能小于0",
|
||||
"costPricePlaceholder": "请输入成本价",
|
||||
"costPriceTips": "[成本价]格式输入错误",
|
||||
"costPriceNotZeroTips": "成本价不能小于0",
|
||||
"stockPlaceholder": "请输入库存",
|
||||
"stockTips": "[库存]格式输入错误",
|
||||
"stockNotZeroTips": "库存不能小于0",
|
||||
"specNameRequire": "规格项不能为空",
|
||||
"specNameRepeat": "规格项不能重复",
|
||||
"specValueRequire": "规格值不能为空",
|
||||
"specValueNameRepeat": "规格值不能重复",
|
||||
"lackDefaultSpec": "商品缺少默认规格",
|
||||
"setDeliverGoods": "发货设置",
|
||||
"autoDeliverGoods": "自动发货",
|
||||
"handDeliverGoods": "手动发货",
|
||||
"setTakeGoods": "收货设置",
|
||||
"autoTakeGoods": "自动收货",
|
||||
"handTakeGoods": "买家确认收货",
|
||||
"verifyTakeGoods": "到店核销",
|
||||
"virtualIndate": "有效期",
|
||||
"virtualIndatePlaceholder": "请输入有效期",
|
||||
"verifyVirtualIndate": "核销有效期",
|
||||
"verifyVirtualIndateOne": "永久",
|
||||
"verifyVirtualIndateTwo": "购买后几日有效",
|
||||
"verifyVirtualIndateThree": "指定过期日期",
|
||||
"verifyHint": "无论何时购买此商品,到达指定时间后都将过期,无法核销。",
|
||||
"sky": "天",
|
||||
"virtualIndateErrorHint": "核销有效期不能小于1天",
|
||||
"virtualIndateErrorOneHint": "核销有效期不能小于等于当前时间",
|
||||
"goodsArguments": "商品参数",
|
||||
"goodsArgumentsTemp": "商品参数模板",
|
||||
"goodsArgumentsTempPlaceholder": "请选择商品参数模板",
|
||||
"goodsArgumentsTempHint": "商品可以添加自定义商品参数,也可以通过参数模板批量设置商品参数",
|
||||
"argumentsName": "参数名",
|
||||
"argumentsValue": "参数值",
|
||||
"argumentsSortHint": "设置排序,改变商品规格展示顺序",
|
||||
"operation": "操作",
|
||||
"delAttr": "删除",
|
||||
"noData": "无数据",
|
||||
"addGoodsArguments": "添加商品参数",
|
||||
"memberDiscount": "会员等级折扣",
|
||||
"discount": "会员折扣",
|
||||
"fixedPrice": "指定会员价",
|
||||
"nonparticipation": "不参与",
|
||||
"discountHint": "会员折扣说明:按照默认会员等级折扣优惠",
|
||||
"fixedPriceHint": "会员价说明:指定优惠价格,商品未参与活动时,按照会员价优惠,若商品参与活动,则以活动价为准",
|
||||
"participateInActiveDisableTips": "商品正在参与营销活动,禁止操作"
|
||||
}
|
||||
20
niucloud/addon/shop/admin/lang/zh-cn/index.index.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"realtimeOverview": "实时概况",
|
||||
"updateTime": "更新时间:",
|
||||
"todayOrderCount": "今日订单数",
|
||||
"todayOrderSale": "今日销售额",
|
||||
"todayAddMemberCount": "今日退款金额",
|
||||
"todayBrowseCount": "今日浏览量",
|
||||
"yesterday": "昨日:",
|
||||
"orderCount": "订单总数",
|
||||
"salesTotal": "销售总额(元)",
|
||||
"memberTotal": "退款金额",
|
||||
"browseTotal": "总浏览量",
|
||||
"agentMatters": "待办事项",
|
||||
"waitPayOrder": "待付款订单",
|
||||
"waitDeliveryOrder": "待发货订单",
|
||||
"waitTakeOrder": "待收货订单",
|
||||
"refundOrder": "退款订单",
|
||||
"saleGoodsNum": "出售商品数量",
|
||||
"warehouseGoodsNum": "仓库商品数量"
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
{
|
||||
"addCoupon": "添加优惠券",
|
||||
"title": "名称",
|
||||
"titlePlaceholder": "请如:XXX优惠券,最多20个字",
|
||||
"type": "类型",
|
||||
"price": "面值",
|
||||
"receiveType": "是否手动领取",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"remainCount": "剩余数量",
|
||||
"limitCount": "已领取数量",
|
||||
"receive": "领取记录",
|
||||
"user": "是",
|
||||
"grant": "否",
|
||||
"limit": "限量",
|
||||
"unlimited": "不限量",
|
||||
"receiveNumber": "发放数量",
|
||||
"pricePlaceholder": "请输入优惠券面值",
|
||||
"remainCountPlaceholder": "最多发放100000张",
|
||||
"reduction": "满减券",
|
||||
"noThreshold": "无门槛券",
|
||||
"threshold": "使用门槛",
|
||||
"minConditionMoneyPlaceholder": "请输入优惠券的最低消费金额",
|
||||
"userLimitCount": "限领张数",
|
||||
"userLimitCountPlaceholder": "请输入限领张数",
|
||||
"receiveTime": "领取时间",
|
||||
"limitedTime": "限时",
|
||||
"unlimitedTime": "不限时",
|
||||
"days": "天数",
|
||||
"times": "固定时间",
|
||||
"validType": "有效期",
|
||||
"lengthPlaceholder": "请输入使用时间",
|
||||
"status": "状态",
|
||||
"open": "开启",
|
||||
"close": "关闭",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"validTimePlaceholder": "用券截止时间",
|
||||
"arrivalTimePlaceholder": "领券截止时间"
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
{
|
||||
"editCoupon": "编辑优惠券",
|
||||
"title": "名称",
|
||||
"titlePlaceholder": "请如:XXX优惠券,最多20个字",
|
||||
"type": "类型",
|
||||
"price": "面值",
|
||||
"receiveType": "是否手动领取",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"remainCount": "剩余数量",
|
||||
"limitCount": "已领取数量",
|
||||
"receive": "领取记录",
|
||||
"user": "是",
|
||||
"grant": "否",
|
||||
"limit": "限量",
|
||||
"unlimited": "不限量",
|
||||
"receiveNumber": "发放数量",
|
||||
"pricePlaceholder": "请输入优惠券面值",
|
||||
"remainCountPlaceholder": "最多发放100000张",
|
||||
"reduction": "满减券",
|
||||
"noThreshold": "无门槛券",
|
||||
"threshold": "使用门槛",
|
||||
"minConditionMoneyPlaceholder": "请输入优惠券的最低消费金额",
|
||||
"userLimitCount": "限领张数",
|
||||
"userLimitCountPlaceholder": "请输入限领张数",
|
||||
"receiveTime": "领取时间",
|
||||
"limitedTime": "限时",
|
||||
"unlimitedTime": "不限时",
|
||||
"days": "天数",
|
||||
"times": "固定时间",
|
||||
"validType": "使用时间",
|
||||
"lengthPlaceholder": "请输入使用时间",
|
||||
"status": "状态",
|
||||
"open": "开启",
|
||||
"close": "关闭",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"validTimePlaceholder": "用券截止时间",
|
||||
"arrivalTimePlaceholder": "领券截止时间"
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
{
|
||||
"addCoupon": "添加优惠券",
|
||||
"title": "名称",
|
||||
"titlePlaceholder": "请输入优惠券名称",
|
||||
"type": "类型",
|
||||
"price": "面值",
|
||||
"receiveType": "是否手动领取",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"count": "数量",
|
||||
"countTips1": "1、剩余数量是指可主动领取优惠券的剩余数量,总数是指可主动领取优惠券的累计数量",
|
||||
"countTips2": "2、已领取数量是指用户在前台主动领取的优惠券数量",
|
||||
"countTips3": "3、已发放数量是指商家在后台给用户直接发放以及用户参与各种营销活动发放的优惠券数量",
|
||||
"countTips4": "4、发放数量不受优惠券剩余数量限制",
|
||||
"sumCount": "剩余 / 总数",
|
||||
"giveCount": "已发放",
|
||||
"noLimit": "不限量",
|
||||
"receive": "领取记录",
|
||||
"edit": "编辑",
|
||||
"Status": "是否关闭领取",
|
||||
"threshold": "使用门槛",
|
||||
"reduction": "满减券",
|
||||
"noThreshold": "无门槛券",
|
||||
"couponDeleteTips": "确定要删除该优惠券吗?",
|
||||
"couponCloseTips": "确定要关闭该优惠券吗?关闭后将不可领取,若会员已领取将变为失效",
|
||||
"validType": "有效期",
|
||||
"statusName": "状态",
|
||||
"receiveTypeTime": "领取有效期",
|
||||
"spreadGoods": "推广",
|
||||
"close": "关闭",
|
||||
"couponSpreadTitle": "优惠券推广",
|
||||
"downloadQrcode": "下载二维码",
|
||||
"spreadLink": "推广链接",
|
||||
"receiveUseCount": "已使用",
|
||||
"collectionCoupon": "领取记录",
|
||||
"collectionTitle": "优惠券名称",
|
||||
"userName": "领用会员",
|
||||
"collectionReceiveType": "领用方式",
|
||||
"createTime": "领取时间",
|
||||
"expireTime": "到期时间",
|
||||
"status": "当前状态",
|
||||
"useTime": "使用时间",
|
||||
"validity": "使用有效期",
|
||||
"mobile": "手机号",
|
||||
"memberInfo": "会员信息",
|
||||
"memberInfoPlaceholder": "请输入会员编码/昵称/手机号搜索",
|
||||
"collectionSumCount": "发放数量",
|
||||
"couponInfo": "优惠券基本信息",
|
||||
"receiveCount": "已领取",
|
||||
"receiveExpireCount": "已过期",
|
||||
"receiveInvalidCount": "已失效",
|
||||
"showOrder": "查看订单",
|
||||
"send": "发券",
|
||||
"sendRecord": "发放记录",
|
||||
"rangeTypePlaceholder": "请选择发放对象",
|
||||
"sendTime": "发放时间",
|
||||
"sendStatus": "发放状态",
|
||||
"selectCoupon": "优惠券名称",
|
||||
"sendNum": "每人发放数量",
|
||||
"sendNumPrompt": "请输入每人发放数量",
|
||||
"num": "张",
|
||||
"sendNumTip": "不受优惠券库存限制",
|
||||
"sendNumTipTwo": "输入框限制不能输入超过10",
|
||||
"rangeType": "发放会员",
|
||||
"point": "积分",
|
||||
"balance": "余额",
|
||||
"memberLabel": "会员标签",
|
||||
"memberLabelPlaceholder": "请选择会员标签",
|
||||
"memberLevel": "会员等级",
|
||||
"memberLevelPlaceholder": "请选择会员等级",
|
||||
"memberLevelTip": "会员等级不能为空",
|
||||
"memberTip": "会员不能为空",
|
||||
"memberLabelTip": "会员标签不能为空",
|
||||
"sendNumTipThree": "发放数量不能为空",
|
||||
"sendNumTipFour": "每人发放数量要大于0小于10",
|
||||
"sendNumTipFive": "输入格式不正确",
|
||||
"sendCouponTitle": "优惠券发放",
|
||||
"batchEmptySelectedGoodsTips": "请先选择需要批量操作的优惠券",
|
||||
"batchDelete": "批量删除",
|
||||
"batchClose": "批量关闭",
|
||||
"batchCloseTips": "确定要关闭选中的优惠券吗?关闭后将不可领取,若会员已领取将变为失效",
|
||||
"batchDeleteTips": "确定要删除选中的优惠券吗?"
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"selectCoupon": "选择的优惠券",
|
||||
"sendNum": "每人发放数量",
|
||||
"sendNumPrompt": "请输入每人发放数量",
|
||||
"num": "张",
|
||||
"sendNumTip": "不受优惠券库存限制",
|
||||
"sendNumTipTwo": "输入框限制不能输入超过10",
|
||||
"rangeType": "发放对象",
|
||||
"memberInfo": "会员信息",
|
||||
"mobile": "手机号",
|
||||
"point": "积分",
|
||||
"balance": "余额",
|
||||
"memberLabel": "会员标签",
|
||||
"memberLabelPlaceholder": "请选择会员标签",
|
||||
"memberLevel": "会员等级",
|
||||
"memberLevelPlaceholder": "请选择会员等级",
|
||||
"memberLevelTip": "会员等级不能为空",
|
||||
"memberTip": "会员不能为空",
|
||||
"memberLabelTip": "会员标签不能为空",
|
||||
"sendNumTipThree": "发放数量不能为空",
|
||||
"sendNumTipFour": "每人发放数量要大于0小于10",
|
||||
"sendNumTipFive": "输入格式不正确"
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"editDiscount": "添加限时折扣",
|
||||
"name": "活动名称",
|
||||
"namePlaceholder": "请输入活动名称",
|
||||
"nameTip": "活动名称用于展示在商家后台管理",
|
||||
"title": "标题",
|
||||
"titlePlaceholder": "请输入活动标题",
|
||||
"titleTip": "活动标题用户展示在手机或者电脑前端展示使用,建议输入长度不要大于5",
|
||||
"activityTime": "活动时间",
|
||||
"discountTimePlaceholder": "请选择活动时间",
|
||||
"selectProduct": "选择商品",
|
||||
"selectProductPlaceholder": "请选择商品",
|
||||
"noSpaceAllowed": "内容不能为空",
|
||||
"batchOperation": "批量设置",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"discountType": "折扣类型",
|
||||
"price": "原价",
|
||||
"discounts": "打折",
|
||||
"discountsTips": "[打折]格式错误",
|
||||
"discountsTipsTwo": "打折折扣不可小于0",
|
||||
"discountsTipsThree": "打折折扣不可大于9.9",
|
||||
"discountsPlaceholder": "请输入打折折扣",
|
||||
"reduceMoney": "减钱",
|
||||
"reduceMoneyTips": "[减钱]格式错误",
|
||||
"reduceMoneyTipsTwo": "减钱金额不可小于0",
|
||||
"reduceMoneyTipsThree": "减钱金额不可大于原价金额",
|
||||
"reduceMoneyPlaceholder": "请输入减钱金额",
|
||||
"promotional": "促销价",
|
||||
"promotionalTips": "[促销价]格式错误",
|
||||
"promotionalTipsTwo": "促销价金额不可小于0",
|
||||
"promotionalTipsThree": "促销价金额不可大于原价金额",
|
||||
"promotionalPlaceholder": "请输入促销价",
|
||||
"delete": "删除",
|
||||
"enabled": "设为参与",
|
||||
"noEnabled": "设为不参与",
|
||||
"skuDiscountSettings": "规格折扣设置",
|
||||
"skuDiscountSettingsPlaceholder": "请输入规格折扣设置"
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"headTitle": "顶部广告图",
|
||||
"image": "图片上传",
|
||||
"imagePlaceholder": "请上传图片",
|
||||
"toLink": "跳转链接",
|
||||
"toLinkPlaceholder": "请输入跳转链接",
|
||||
"addConfigList": "添加广告图"
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"baseInfo": "基础信息",
|
||||
"name": "活动名称",
|
||||
"title": "标题",
|
||||
"status": "状态",
|
||||
"paymentAmount": "支付金额",
|
||||
"memberCount": "参与会员数",
|
||||
"orderCount": "支付订单数",
|
||||
"createTime": "创建时间",
|
||||
"startTime": "活动开始时间",
|
||||
"endTime": "活动结束时间",
|
||||
"keywordPlaceholder": "请输入商品名称",
|
||||
"keyword": "商品名称",
|
||||
"goodsInfo": "商品信息",
|
||||
"price": "商品价格",
|
||||
"activeOrderMoney": "累计订单金额",
|
||||
"activeOrderNum": "累计订单数",
|
||||
"activeMemberNum": "参与会员数",
|
||||
"activeSuccessNum": "支付销量",
|
||||
"orderInfo": "订单编号",
|
||||
"payTime": "支付时间",
|
||||
"orderNo": "订单编号",
|
||||
"orderMoney": "订单金额",
|
||||
"buyInfo": "买家/收货人",
|
||||
"payType": "支付类型",
|
||||
"orderStatus": "订单状态",
|
||||
"toBePaid": "待支付",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"consumptionMoney": "消费总额",
|
||||
"participationNum": "参与次数",
|
||||
"orderTime": "最后下单时间",
|
||||
"memberInfo": "会员信息"
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
{
|
||||
"editDiscount": "编辑限时折扣",
|
||||
"name": "活动名称",
|
||||
"namePlaceholder": "请输入活动名称",
|
||||
"nameTip": "活动名称用于展示在商家后台管理",
|
||||
"title": "标题",
|
||||
"titlePlaceholder": "请输入活动标题",
|
||||
"titleTip": "活动标题用于在手机或者电脑前端,建议输入长度不要大于5",
|
||||
"activityTime": "活动时间",
|
||||
"discountTimePlaceholder": "请选择活动时间",
|
||||
"noSpaceAllowed": "内容不能为空",
|
||||
"selectProduct": "选择商品",
|
||||
"selectProductPlaceholder": "请选择商品",
|
||||
"batchOperation": "批量设置",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"discountType": "折扣类型",
|
||||
"price": "原价",
|
||||
"discounts": "打折",
|
||||
"discountsTips": "[打折]格式错误",
|
||||
"discountsTipsTwo": "打折折扣不可小于0",
|
||||
"discountsTipsThree": "打折折扣不可大于9.9",
|
||||
"discountsPlaceholder": "请输入打折折扣",
|
||||
"reduceMoney": "减钱",
|
||||
"reduceMoneyTips": "[减钱]格式错误",
|
||||
"reduceMoneyTipsTwo": "减钱金额不可小于0",
|
||||
"reduceMoneyTipsThree": "减钱金额不可大于原价金额",
|
||||
"reduceMoneyPlaceholder": "请输入减钱金额",
|
||||
"promotional": "促销价",
|
||||
"promotionalTips": "[促销价]格式错误",
|
||||
"promotionalTipsTwo": "促销价金额不可小于0",
|
||||
"promotionalTipsThree": "促销价金额不可大于原价金额",
|
||||
"promotionalPlaceholder": "请输入促销价",
|
||||
"delete": "删除",
|
||||
"enabled": "设为参与",
|
||||
"noEnabled": "设为不参与",
|
||||
"skuDiscountSettings": "规格折扣设置",
|
||||
"skuDiscountSettingsPlaceholder": "请输入规格折扣设置"
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
{
|
||||
"addDiscount": "添加限时折扣",
|
||||
"name": "名称",
|
||||
"namePlaceholder": "请输入活动名称",
|
||||
"title": "标题",
|
||||
"status": "状态",
|
||||
"statusPlaceholder": "请选择状态",
|
||||
"paymentAmount": "支付金额",
|
||||
"memberCount": "会员数",
|
||||
"orderCount": "订单数",
|
||||
"discountTime": "活动时间",
|
||||
"detail": "详情",
|
||||
"close": "关闭",
|
||||
"closeTips": "活动正在进行中,是否确认关闭当前活动?",
|
||||
"deleteTips": "是否确认删除当前活动",
|
||||
"baseInfo": "基础信息",
|
||||
"createTime": "创建时间",
|
||||
"startTime": "活动开始时间",
|
||||
"endTime": "活动结束时间",
|
||||
"keywordPlaceholder": "请输入商品名称",
|
||||
"keyword": "商品名称",
|
||||
"goodsInfo": "商品信息",
|
||||
"price": "商品价格",
|
||||
"activeOrderMoney": "累计订单金额",
|
||||
"activeOrderNum": "累计订单数",
|
||||
"activeMemberNum": "参与会员数",
|
||||
"activeSuccessNum": "支付销量",
|
||||
"orderInfo": "订单编号",
|
||||
"payTime": "支付时间",
|
||||
"orderNo": "订单编号",
|
||||
"orderMoney": "订单金额",
|
||||
"buyInfo": "买家/收货人",
|
||||
"payType": "支付类型",
|
||||
"orderStatus": "订单状态",
|
||||
"toBePaid": "待支付",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"consumptionMoney": "消费总额",
|
||||
"participationNum": "参与次数",
|
||||
"orderTime": "最后下单时间",
|
||||
"memberInfo": "会员信息",
|
||||
"activeName": "活动名称",
|
||||
"participationMemberCount": "参与会员数",
|
||||
"payOrderCount": "支付订单数",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"batchCloseTips": "是否确认批量关闭当前活动?",
|
||||
"batchDeleteTips": "是否确认批量删除当前活动?",
|
||||
"batchClose":"批量关闭",
|
||||
"batchDelete":"批量删除"
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
{
|
||||
"addGoods": "添加商品",
|
||||
"baseInfo": "基础设置",
|
||||
"goodsType": "商品类型",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsTitle": "副标题",
|
||||
"goodsTitlePlaceholder": "请输入副标题",
|
||||
"image": "商品图片",
|
||||
"imagePlaceholder": "请选择商品图片",
|
||||
"selectProduct": "选择商品",
|
||||
"selectGoodsPlaceholder": "请选择商品",
|
||||
"goodsStatus": "商品状态",
|
||||
"goodsSelect": "选择商品",
|
||||
"redemptionSettings": "积分设置",
|
||||
"batchOperation": "批量设置",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"goodsSelectPopupGoodsInfo": "商品信息",
|
||||
"price": "销售价",
|
||||
"stock": "兑换库存",
|
||||
"stockPlaceholder": "请输入兑换库存",
|
||||
"stockTips": "[兑换库存]格式错误",
|
||||
"stockTipsTwo": "兑换库存不可小于等于0",
|
||||
"stockTipsThree": "兑换限制数量不可大于商品库存",
|
||||
"limit": "兑换限制",
|
||||
"limitPlaceholder": "请输入兑换限制",
|
||||
"limitTips": "[兑换限制]格式错误",
|
||||
"limitTipsTwo": "兑换限制数量不可小于等于0",
|
||||
"limitTipsThree": "兑换限制数量不能大于兑换库存",
|
||||
"limitUnit": "件/人",
|
||||
"integralUnit": "积分",
|
||||
"prickUnit": "元",
|
||||
"pointPlaceholder": "请输入积分积分",
|
||||
"pointTips": "[积分]格式错误",
|
||||
"pointTipsTwo": "积分不可小于等于0",
|
||||
"money": "兑换价",
|
||||
"newPrice": "价格",
|
||||
"moneyTips": "[价格]格式错误",
|
||||
"moneyTipsTwo": "价格不可小于0",
|
||||
"limitRules": "每人每单可兑换件数",
|
||||
"couponSelect": "选择优惠券",
|
||||
"couponSelectPlaceholder": "请选择优惠券",
|
||||
"couponName": "优惠券名称",
|
||||
"couponType": "类型",
|
||||
"couponPrice": "面值",
|
||||
"sumCount": "总库存",
|
||||
"threshold": "使用门槛",
|
||||
"validType": "有效期",
|
||||
"receiveTypeTime": "领取有效期",
|
||||
"balance": "兑换余额",
|
||||
"balancePlaceholder": "请输入兑换余额",
|
||||
"balanceTips": "[兑换余额]格式错误",
|
||||
"balanceTipsTwo": "兑换余额不可小于等于0",
|
||||
"balanceType": "余额类型",
|
||||
"goodsSkuTitle": "选择商品规格",
|
||||
"goodsSkuPlaceholder": "请选择商品规格",
|
||||
"goodsStock": "库存",
|
||||
"enabled": "设为参与",
|
||||
"noEnabled": "设为不参与",
|
||||
"noEnabledTip": "请至少设置一个规格参与",
|
||||
"goodsDetail": "商品详情"
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
{
|
||||
"editGoods": "编辑商品",
|
||||
"baseInfo": "基础设置",
|
||||
"goodsType": "商品类型",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsTitle": "副标题",
|
||||
"goodsTitlePlaceholder": "请输入副标题",
|
||||
"image": "商品图片",
|
||||
"imagePlaceholder": "请选择商品图片",
|
||||
"selectProduct": "选择商品",
|
||||
"selectGoodsPlaceholder": "请选择商品",
|
||||
"goodsStatus": "商品状态",
|
||||
"goodsSelect": "选择商品",
|
||||
"redemptionSettings": "积分设置",
|
||||
"batchOperation": "批量设置",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"goodsSelectPopupGoodsInfo": "商品信息",
|
||||
"price": "销售价",
|
||||
"stock": "兑换库存",
|
||||
"stockPlaceholder": "请输入兑换库存",
|
||||
"stockTips": "[兑换库存]格式错误",
|
||||
"stockTipsTwo": "兑换库存不可小于等于0",
|
||||
"stockTipsThree": "兑换限制数量不可大于商品库存",
|
||||
"limit": "兑换限制",
|
||||
"limitPlaceholder": "请输入兑换限制",
|
||||
"limitTips": "[兑换限制]格式错误",
|
||||
"limitTipsTwo": "兑换限制数量不可小于等于0",
|
||||
"limitTipsThree": "兑换限制数量不能大于兑换库存",
|
||||
"limitUnit": "件/人",
|
||||
"integralUnit": "积分",
|
||||
"prickUnit": "元",
|
||||
"pointPlaceholder": "请输入积分积分",
|
||||
"pointTips": "[积分]格式错误",
|
||||
"pointTipsTwo": "积分不可小于等于0",
|
||||
"money": "兑换价",
|
||||
"newPrice": "价格",
|
||||
"moneyTips": "[价格]格式错误",
|
||||
"moneyTipsTwo": "价格不可小于0",
|
||||
"limitRules": "每人每单可兑换件数",
|
||||
"couponSelect": "选择优惠券",
|
||||
"couponSelectPlaceholder": "请选择优惠券",
|
||||
"couponName": "优惠券名称",
|
||||
"couponType": "类型",
|
||||
"couponPrice": "面值",
|
||||
"sumCount": "总库存",
|
||||
"threshold": "使用门槛",
|
||||
"validType": "有效期",
|
||||
"receiveTypeTime": "领取有效期",
|
||||
"balance": "兑换余额",
|
||||
"balancePlaceholder": "请输入兑换余额",
|
||||
"balanceTips": "[兑换余额]格式错误",
|
||||
"balanceTipsTwo": "兑换余额不可小于等于0",
|
||||
"balanceType": "余额类型",
|
||||
"goodsSkuTitle": "选择商品规格",
|
||||
"goodsSkuPlaceholder": "请选择商品规格",
|
||||
"goodsStock": "库存",
|
||||
"enabled": "设为参与",
|
||||
"noEnabled": "设为不参与",
|
||||
"noEnabledTip": "请至少设置一个规格参与",
|
||||
"goodsDetail": "商品详情"
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"addGoods": "添加商品",
|
||||
"goods": "商品",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"status": "状态",
|
||||
"statusPlaceholder": "请选择状态",
|
||||
"goodsType": "商品类型",
|
||||
"exchangePrice": "兑换价格",
|
||||
"pointUnit": "积分",
|
||||
"priceUnit": "元",
|
||||
"redeemedAndSurplus": "已兑/剩余",
|
||||
"deleteTips": "是否确认删除当前商品",
|
||||
"createTime": "创建时间",
|
||||
"spreadGoods": "推广",
|
||||
"copyGoods": "复制",
|
||||
"spreadLink": "推广链接",
|
||||
"copy": "复制",
|
||||
"downloadQrcode": "下载二维码",
|
||||
"goodsSpreadTitle": "积分商品推广",
|
||||
"up": "上架",
|
||||
"upTips": "是否确认上架当前商品",
|
||||
"down": "下架",
|
||||
"downTips": "是否确认下架当前商品",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"batchUpTips":"是否确认批量上架选中的商品?",
|
||||
"batchDownTips":"是否确认批量下架选中的商品?",
|
||||
"batchDeleteTips":"是否确认批量删除选中的商品?",
|
||||
"batchUp":"批量上架",
|
||||
"batchDown":"批量下架",
|
||||
"batchDelete":"批量删除"
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
{
|
||||
"orderNo": "订单编号",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"orderMoney": "实付金额(元)",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"piece": "件",
|
||||
"activeRefund": "主动退款",
|
||||
"notes": "备注",
|
||||
"offlinePayment": "线下支付",
|
||||
"orderClose": "关闭订单",
|
||||
"editPrice": "修改价格",
|
||||
"editAddress": "修改地址",
|
||||
"sendOutGoods": "发货",
|
||||
"confirmTakeDelivery": "确认收货",
|
||||
"all": "全部",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"refunding": "退款中",
|
||||
"notesDetail": "备注信息",
|
||||
"delivery": "订单发货",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"goodsName": "商品名称",
|
||||
"num": "商品数量",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"fromType": "订单来源",
|
||||
"payType": "支付类型",
|
||||
"orderInfo": "订单信息",
|
||||
"refundStatusName": "退款状态",
|
||||
"outTradeNo": "交易流水号",
|
||||
"exportOrderType": "导出订单类型",
|
||||
"shopOrder": "订单数据表",
|
||||
"shopOrderGoods": "订单商品表",
|
||||
"point": "积分"
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"rankName": "榜单标题",
|
||||
"rankImages": "榜单图片",
|
||||
"rankRemark": "榜单说明",
|
||||
"save": "保存",
|
||||
"imagePlaceholder": "请上传榜单图片",
|
||||
"rankNamePlaceholder": "请输入榜单名称",
|
||||
"rankRemarkPlaceholder": "请输入榜单说明",
|
||||
"useDefaultRankRemark": "使用默认说明",
|
||||
"noColor": "常规颜色",
|
||||
"selectedColor": "选中文字颜色",
|
||||
"selectedBgColor": "选中背景颜色"
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
"addRanking": "添加榜单",
|
||||
"updateRanking": "修改榜单",
|
||||
"rankName": "榜单名称",
|
||||
"rankBanner": "榜单banner",
|
||||
"imagePlaceholder": "请上传图片",
|
||||
"rankNamePlaceholder": "请输入榜单名称",
|
||||
"rankType": "排行周期",
|
||||
"rankTypePlaceholder": "请选择榜单周期",
|
||||
"batchDeletion": "批量删除",
|
||||
"goodsSource": "商品来源",
|
||||
"goodsSourcePlaceholder": "请选择商品来源",
|
||||
"addCategory": "添加分类",
|
||||
"categoryTips": "商品分类不能为空",
|
||||
"brand": "商品品牌",
|
||||
"brandPlaceholder": "请选择商品品牌",
|
||||
"brandTips": "商品品牌不能为空",
|
||||
"addBrand": "添加品牌",
|
||||
"label": "商品标签",
|
||||
"labelTips": "商品标签不能为空",
|
||||
"addLabel": "添加商品标签",
|
||||
"sort": "排序",
|
||||
"sortPlaceholder": "请输入排序号",
|
||||
"ruleType": "排序规则",
|
||||
"ruleTypePlaceholder": "请选择排序规则",
|
||||
"selectGoods": "选择商品",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"goodsJsonEmpty": "商品数据不能为空",
|
||||
"limitTips": "输入格式不正确",
|
||||
"rankTypeTips": "天:1天,周:7天,月:30天,季度:90天",
|
||||
"sortRules": "从大到小排列,支持手动修改排序号调整排名,以满足特定需求展示效果",
|
||||
"isShow": "状态"
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"addRanking": "添加榜单",
|
||||
"rankName": "榜单名称",
|
||||
"rankType": "排行周期",
|
||||
"rankNamePlaceholder": "请输入榜单名称",
|
||||
"batchDeletion": "批量删除",
|
||||
"showGoodsNum": "榜单商品数量",
|
||||
"goodsSource": "商品来源",
|
||||
"ruleType": "排序规则",
|
||||
"createTime": "创建时间",
|
||||
"deleteTips": "确定删除该榜单吗?",
|
||||
"batchEmptySelectedGoodsTips": "请先选择要删除的榜单",
|
||||
"batchGoodsDeleteTips": "确定删除选中的榜单吗?",
|
||||
"sortTips": "排序号格式输入错误",
|
||||
"sortRules": "按照排序号从大到小排序",
|
||||
"isShow": "状态"
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"baseInfo": "基础信息",
|
||||
"name": "活动名称",
|
||||
"title": "标题",
|
||||
"status": "状态",
|
||||
"paymentAmount": "支付金额",
|
||||
"memberCount": "参与会员数",
|
||||
"orderCount": "支付订单数",
|
||||
"createTime": "创建时间",
|
||||
"startTime": "活动开始时间",
|
||||
"endTime": "活动结束时间",
|
||||
"keywordPlaceholder": "请输入商品名称",
|
||||
"keyword": "商品名称",
|
||||
"goodsInfo": "商品信息",
|
||||
"price": "商品价格",
|
||||
"activeOrderMoney": "累计订单金额",
|
||||
"activeOrderNum": "累计订单数",
|
||||
"activeMemberNum": "参与会员数",
|
||||
"activeSuccessNum": "支付销量",
|
||||
"orderInfo": "订单编号",
|
||||
"payTime": "支付时间",
|
||||
"orderNo": "订单编号",
|
||||
"orderMoney": "订单金额",
|
||||
"buyInfo": "买家/收货人",
|
||||
"payType": "支付类型",
|
||||
"orderStatus": "订单状态",
|
||||
"toBePaid": "待支付",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"consumptionMoney": "消费总额",
|
||||
"participationNum": "参与次数",
|
||||
"orderTime": "最后下单时间",
|
||||
"memberInfo": "会员信息"
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
{
|
||||
"addFullDiscountBonus": "添加满减送",
|
||||
"editFullDiscountBonus": "修改满减送",
|
||||
"activeName": "活动名称",
|
||||
"activityTime": "活动时间",
|
||||
"namePlaceholder": "请输入活动名称",
|
||||
"conditionType": "条件类型",
|
||||
"overNyuan": "满N元",
|
||||
"overNgoods": "满N件",
|
||||
"ruleType": "优惠规则",
|
||||
"ladder": "阶梯优惠",
|
||||
"cycle": "循环优惠",
|
||||
"ruleJson": "优惠设置",
|
||||
"activityLevel": "活动层级",
|
||||
"addActivityLevel": "添加活动层级",
|
||||
"discountThreshold": "优惠门槛",
|
||||
"placeholder": "请输入",
|
||||
"delete": "删除",
|
||||
"discountContent": "优惠内容",
|
||||
"discountMoney": "订单金额优惠",
|
||||
"reduce": "减价",
|
||||
"discountRate": "打折",
|
||||
"freeShipping": "包邮",
|
||||
"freeTips": "仅参与该活动的商品包邮,非整单包邮",
|
||||
"givePoint": "送积分",
|
||||
"giveGrowth": "送成长值",
|
||||
"giveBalance": "送余额",
|
||||
"giveCoupon": "送优惠券",
|
||||
"giveCouponTips": "如果优惠券数量不足、限领数量已达上限或优惠券状态不是“进行中”,都将导致赠送失败。",
|
||||
"name": "优惠券名称",
|
||||
"type": "优惠券类型",
|
||||
"couponPrice": "优惠券面值",
|
||||
"couponGiveNum": "赠券数",
|
||||
"giveGoods": "送赠品",
|
||||
"giveGoodsTips": "当赠品库存不足或下架时则不赠送",
|
||||
"stock": "库存",
|
||||
"giveNum": "赠送数量",
|
||||
"joinMemberType": "活动对象",
|
||||
"allMember": "所有会员参与",
|
||||
"selectedMemberLevel": "指定会员等级",
|
||||
"selectedMemberLabel": "指定会员标签",
|
||||
"memberLevel": "会员等级",
|
||||
"memberLevelPlaceholder": "请选择会员等级",
|
||||
"memberLabel": "会员标签",
|
||||
"memberLabelPlaceholder": "请选择会员标签",
|
||||
"goodsType": "参与商品",
|
||||
"allGoods": "全部商品参与",
|
||||
"selectedGoods": "指定商品参与",
|
||||
"selectedGoodsNot": "指定商品不参与",
|
||||
"selectGoods": "选择商品",
|
||||
"remark": "备注",
|
||||
"rankRemarkPlaceholder": "请输入备注",
|
||||
"selectActivityTime": "请选择活动时间",
|
||||
"selectActivityStartTime": "请选择活动开始时间",
|
||||
"selectActivityEndTime": "请选择活动结束时间",
|
||||
"selectActivityTimeTips": "活动结束时间不能小于等于活动开始时间",
|
||||
"addLevelLimit": "层级限制最多添加五个",
|
||||
"labelTips": "请选择会员标签",
|
||||
"levelTips": "请选择会员等级",
|
||||
"goodsJsonEmpty": "请选择商品",
|
||||
"couponPlaceholder": "请选择优惠券",
|
||||
"limitPlaceholder": "请输入优惠门槛",
|
||||
"discountsPlaceholder": "请输入折扣或金额",
|
||||
"growthPlaceholder": "请输入赠送成长值",
|
||||
"pointPlaceholder": "请输入赠送积分",
|
||||
"balancePlaceholder": "请输入赠送余额",
|
||||
"valueMustBeGreaterThanZero": "优惠门槛必须大于0",
|
||||
"pointMustBeGreaterThanZero": "赠送积分必须大于0",
|
||||
"balanceMustBeGreaterThanZero": "赠送余额必须大于0",
|
||||
"growthMustBeGreaterThanZero": "赠送成长值必须大于0",
|
||||
"discountMustBeGreaterThanZero": "优惠内容必须大于0",
|
||||
"discountMustBeGreaterThanNine": "范围大于等于0.1且小于等于9.9",
|
||||
"limitTips": "输入格式不正确",
|
||||
"limitTipsTwo": "每个层级的门槛金额不能相同",
|
||||
"addSuccess": "添加成功",
|
||||
"updateSuccess": "编辑成功",
|
||||
"addFail": "添加失败",
|
||||
"updateFail": "编辑失败",
|
||||
"goodOnlyOne": "同一商品在一个时间段内只能参加一个满减送活动",
|
||||
"discountLimit": "优惠金额不能大于优惠门槛",
|
||||
"giveNumPlaceholder": "请输入赠送数量",
|
||||
"giveNumMustBeGreaterThanZero": "赠送数量必须大于0",
|
||||
"giveNumMustBeGreaterThanStock": "赠送数量不能大于库存",
|
||||
"limitTipsThree": "必须大于上一层级的优惠门槛",
|
||||
"ruleTypeTips": "阶梯优惠根据设定的门槛逐级增加优惠,达到特定层级门槛即可享受对应优惠,最高可设5个层级。",
|
||||
"ruleTypeTipsTwo": "循环优惠指每次达到门槛即获赠一次优惠,无次数上限,需合理设置门槛。",
|
||||
"goodsOffTips": "该商品已下架"
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
{
|
||||
"addFullDiscountBonus": "添加满减送",
|
||||
"name": "活动名称",
|
||||
"detailTitle": "满减送活动详情",
|
||||
"activeDetail": "活动详情",
|
||||
"namePlaceholder": "请输入活动名称",
|
||||
"title": "标题",
|
||||
"status": "状态",
|
||||
"statusPlaceholder": "请选择状态",
|
||||
"activityTime": "活动时间",
|
||||
"detail": "详情",
|
||||
"close": "关闭",
|
||||
"closeTips": "活动正在进行中,是否确认关闭当前活动?",
|
||||
"deleteTips": "是否确认删除当前活动",
|
||||
"createTime": "创建时间",
|
||||
"startTime": "活动开始时间",
|
||||
"endTime": "活动结束时间",
|
||||
"keywordPlaceholder": "请输入商品名称",
|
||||
"keyword": "商品名称",
|
||||
"price": "商品价格",
|
||||
"activeOrderMoney": "累计订单金额",
|
||||
"activeOrderNum": "支付订单数",
|
||||
"activeMemberNum": "参与会员数",
|
||||
"paymentAmount": "支付金额",
|
||||
"memberCount": "会员数",
|
||||
"orderCount": "订单数",
|
||||
"activeSuccessNum": "支付销量",
|
||||
"activeName": "活动名称",
|
||||
"participationMemberCount": "参与会员数",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"all": "全部",
|
||||
"orderTime": "最后下单时间",
|
||||
"consumptionMoney": "消费总额",
|
||||
"memberInfo": "会员信息",
|
||||
"participationNum": "参与次数",
|
||||
"goodsInfo": "商品信息",
|
||||
"discountThreshold": "优惠门槛",
|
||||
"giveGoods": "送赠品",
|
||||
"givePoint": "送积分",
|
||||
"giveBalance": "送余额",
|
||||
"giveGrowth": "送成长值",
|
||||
"giveCoupon": "送优惠券",
|
||||
"discountMoney": "订单优惠",
|
||||
"freeShipping": "包邮",
|
||||
"basicInfo": "基本信息",
|
||||
"totalPoint": "累计赠送积分",
|
||||
"totalBalance": "累计赠送余额",
|
||||
"totalCouponNum": "累计赠送优惠券",
|
||||
"totalGoodsNum": "累计赠送商品数",
|
||||
"activeMember": "活动会员",
|
||||
"batchDelete": "批量删除",
|
||||
"batchClose": "批量关闭",
|
||||
"batchEmptySelectedActiveDeleteTips": "请先选择要删除的活动",
|
||||
"batchEmptySelectedActiveCloseTips": "请先选择要关闭的活动",
|
||||
"batchGoodsDeleteTips": "确定删除选中的活动吗?",
|
||||
"batchGoodsCloseTips": "确定关闭选中的活动吗?"
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
{
|
||||
"basicInfoTab": "基础设置",
|
||||
"bannerList": "顶部广告图",
|
||||
"activeStatus": "是否启用",
|
||||
"validityType": "有效期",
|
||||
"validityDay": "天数",
|
||||
"validityDayPlaceholder": "请输入有效天数",
|
||||
"validityDayTips": "有效天数不可小于等于0",
|
||||
"validityDayTipsLeft": "达成门槛立即生效,",
|
||||
"validityDayTipsRight": "天有效期",
|
||||
"validityTime": "固定时间",
|
||||
"validityTimePlaceholder": "请选择有效期截止时间",
|
||||
"validityTimePlaceholderTwo": "请先选择参与门槛时间",
|
||||
"validityTimePlaceholderThree": "有效期截止时间不可小于参与门槛时间",
|
||||
"validityTimeTips": "达成门槛立即生效,有效期截止为",
|
||||
"validityTimeTipsTwo": "修改有效期将同步更新所有未参与活动用户的结束时间",
|
||||
"participationWay": "参与门槛",
|
||||
"neverOrder": "从未下过单的会员",
|
||||
"assignTimeOrder": "指定时间内未下过单的会员",
|
||||
"assignTimeRegister": "指定时间内注册的会员",
|
||||
"appointTimePlaceholder": "请选择指定时间",
|
||||
"activityGoods": "活动商品",
|
||||
"selectGoods": "选择商品",
|
||||
"goodsSkuIdsPlaceholder": "请选择商品",
|
||||
"limitNum": "限购数量",
|
||||
"limitNumPlaceholder": "请输入限购数量",
|
||||
"limitNumTips": "限购数量不可小于等于0",
|
||||
"limitNumTipsThree": "限购数量不可超过已选商品数量",
|
||||
"oldPrice": "原价",
|
||||
"newcomerPrice": "新人价",
|
||||
"newcomerPricePlaceholder": "请输入新人价",
|
||||
"newcomerPriceTips": "[新人价]格式错误",
|
||||
"newcomerPriceTipsOne": "新人价不可小于0",
|
||||
"newcomerPriceTipsTwo": "新人价不可大于原价",
|
||||
"batchOperation": "批量操作",
|
||||
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
|
||||
"activeDesc": "规则说明",
|
||||
"activeDescPlaceholder": "请输入规则说明",
|
||||
"useDefaultActiveDesc": "使用默认说明",
|
||||
"image": "图片上传",
|
||||
"imagePlaceholder": "请上传图片",
|
||||
"toLink": "跳转链接",
|
||||
"toLinkPlaceholder": "请输入跳转链接",
|
||||
"addConfigList": "添加广告图"
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
{
|
||||
"orderNo": "订单编号",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"goodsPriceNumberTips": "新人价商品购买数量为1时,单价显示新人价,购买数量大于1时,单价显示原价或折扣价或会员价",
|
||||
"orderMoney": "实付金额(元)",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"piece": "件",
|
||||
"createTime": "创建时间",
|
||||
"activeRefund": "主动退款",
|
||||
"notes": "备注",
|
||||
"offlinePayment": "线下支付",
|
||||
"orderClose": "关闭订单",
|
||||
"editPrice": "修改价格",
|
||||
"editAddress": "修改地址",
|
||||
"sendOutGoods": "发货",
|
||||
"confirmTakeDelivery": "确认收货",
|
||||
"all": "全部",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"refunding": "退款中",
|
||||
"notesDetail": "备注信息",
|
||||
"delivery": "订单发货",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"goodsName": "商品名称",
|
||||
"num": "商品数量",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"fromType": "订单来源",
|
||||
"payType": "支付类型",
|
||||
"orderInfo": "订单信息",
|
||||
"refundStatusName": "退款状态",
|
||||
"outTradeNo": "交易流水号",
|
||||
"exportOrderType": "导出订单类型",
|
||||
"shopOrder": "订单数据表",
|
||||
"shopOrderGoods": "订单商品表",
|
||||
"point": "积分"
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
{
|
||||
"failuresNum": "发货失败单数",
|
||||
"succeedNum": "发货成功单数",
|
||||
"totalNum": "总发货单数",
|
||||
"operationTime": "操作时间",
|
||||
"operationType": "操作类型",
|
||||
"state": "状态",
|
||||
"operator": "操作人",
|
||||
"importData": "批量发货",
|
||||
"templateType": "模板类型",
|
||||
"fullOrderDelivery": "整单发货模板",
|
||||
"openOrderDelivery": "拆单发货模板",
|
||||
"uploadFile": "上传文件",
|
||||
"createTime": "时间",
|
||||
"uploadFilePlaceholder": "请上传文件",
|
||||
"operatorPlaceholder": "请选择操作人",
|
||||
"causeFailure": "下载失败记录",
|
||||
"downloadRecord": "下载记录",
|
||||
"orderTemplate": "下载整单发货模板.xls",
|
||||
"orderGoodsTemplate": "下载拆单发货模板.xls",
|
||||
"checkCause": "查看失败原因",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"checkCause1": "失败原因"
|
||||
}
|
||||
40
niucloud/addon/shop/admin/lang/zh-cn/order.config.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"closeOrderInfo": "自动取消订单",
|
||||
"closeOrderInfoLeft": "提交订单",
|
||||
"closeOrderInfoRight": "分钟未付款,自动取消订单",
|
||||
"closeOrderInfoBottom": "订单取消时间必须在10-1440分钟之间",
|
||||
"CloseLengthPlaceholder": "请输入订单取消时间",
|
||||
"isClose": "自动取消订单",
|
||||
"confirm": "自动确认收货",
|
||||
"confirmLeft": "发货后",
|
||||
"confirmRight": "天,自动确认收货",
|
||||
"confirmBottom": "自动确认收货时间必须在1-30天之间",
|
||||
"finishLengthPlaceholder": "请输入自动确认收货时间",
|
||||
"isFinish": "自动确认收货",
|
||||
"refund": "确认收货后售后",
|
||||
"refundLeft": "确认收货",
|
||||
"refundRight": "天内,可申请售后",
|
||||
"refundBottom": "确认收货后售后时间必须在1-30天之间",
|
||||
"noAllowRefund": "确认收货后不支持售后",
|
||||
"validRefundLengthPlaceholder": "请输入确认收货后售后时间",
|
||||
"invoice": "发票设置",
|
||||
"isInvoice": "发票开关",
|
||||
"isInvoiceClose": "关闭",
|
||||
"isInvoiceOpen": "开启",
|
||||
"invoiceContent": "发票内容",
|
||||
"insert": "添加",
|
||||
"paperInvoice": "纸质发票",
|
||||
"electronicInvoice": "电子发票",
|
||||
"invoicePlaceholder": "所有发票内容不能为空",
|
||||
"invoiceType": "发票类型",
|
||||
"invoiceTypePlaceholder": "请至少选择一个发票类型",
|
||||
"evaluate": "评价设置",
|
||||
"isEvaluate": "评价开关",
|
||||
"evaluateIsToExamine": "评价审核",
|
||||
"evaluateIsShow": "评价显示",
|
||||
"isEvaluateOpen": "开启",
|
||||
"isEvaluateClose": "关闭",
|
||||
"diyForm": "万能表单",
|
||||
"diyFormPlaceholder": "请选择万能表单",
|
||||
"addDiyForm": "添加表单"
|
||||
}
|
||||
145
niucloud/addon/shop/admin/lang/zh-cn/order.detail.json
Normal file
@ -0,0 +1,145 @@
|
||||
{
|
||||
"orderNo": "订单编号",
|
||||
"orderInfo": "订单信息",
|
||||
"outTradeNo": "交易流水号",
|
||||
"orderType": "订单类型",
|
||||
"orderForm": "订单来源",
|
||||
"takerName": "收货人",
|
||||
"takerMobile": "收货人手机号",
|
||||
"takerFullAddress": "收货地址",
|
||||
"goodsDetail": "商品信息",
|
||||
"goodsName": "商品名称",
|
||||
"price": "价格",
|
||||
"num": "数量",
|
||||
"goodsMoney": "商品总额",
|
||||
"preferentialMoney": "优惠金额",
|
||||
"deliveryMoney": "配送金额",
|
||||
"operateLog": "订单日志",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"orderMoney": "订单金额",
|
||||
"buyInfo": "买家/收货人",
|
||||
"deliveryType": "配送方式",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"piece": "件",
|
||||
"payType": "支付方式",
|
||||
"notes": "备注",
|
||||
"editAddress": "修改地址",
|
||||
"remind": "提醒",
|
||||
"remindTips1": "买家付款成功后,货款将直接进入您的商户号(微信、支付宝)",
|
||||
"remindTips2": "请及时关注你发出的包裹状态,确保可以配送至买家手中",
|
||||
"remindTips3": "如果买家表示没收到货或货物有问题,请及时联系买家处理,友好协商",
|
||||
"close": "关闭订单",
|
||||
"finish": "确认收货",
|
||||
"delivery": "订单发货",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"memberRemark": "买家留言",
|
||||
"discountMoney": "总优惠金额",
|
||||
"couponMoney": "优惠券优惠金额",
|
||||
"manjianDiscountMoney": "满减优惠金额",
|
||||
"orderDelivery": "物流信息",
|
||||
"devliveryTime": "发货时间",
|
||||
"companyName": "物流公司",
|
||||
"logisticNo": "物流单号",
|
||||
"packageInfo": "物流包裹信息",
|
||||
"deliveryInfo": "发货信息",
|
||||
"goodsInfo": "商品信息",
|
||||
"logisticInfo": "物流信息",
|
||||
"storeName": "自提点名称",
|
||||
"storeAddress": "自提点地址",
|
||||
"storeMobile": "自提点电话",
|
||||
"tradeTime": "营业时间",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"package": "包裹",
|
||||
"noLogisticsRequired": "无需物流",
|
||||
"notLogistics": "暂无物流信息",
|
||||
"refundStatusName": "退款状态",
|
||||
"orderInfoEmpty": "暂无数据",
|
||||
"editPrice": "修改价格",
|
||||
"adjustMoneyDialogTitle": "调整价格",
|
||||
"adjustMoneyUnit": "元",
|
||||
"adjustMoneyTips": "注意 : 只有订单未付款时才支持改价,改价后请联系买家刷新订单核实订单金额后再支付。当订单总额为0元时,订单将自动支付",
|
||||
"adjustMoneyDeliveryMoney": "运费",
|
||||
"adjustMoneyGoodsInfo": "商品信息",
|
||||
"adjustMoneyPrice": "单价",
|
||||
"adjustMoneyNum": "数量",
|
||||
"adjustMoneySubTotal": "小计",
|
||||
"adjustMoneyDiscountMoney": "优惠金额",
|
||||
"adjustMoneyLabel": "调整金额",
|
||||
"adjustMoneyTotal": "总计",
|
||||
"point": "积分",
|
||||
"electronicSheetPrintTitle": "打印电子面单",
|
||||
"electronicSheetTemplate": "面单模板",
|
||||
"electronicSheetTemplatePlaceholder": "请选择面单模板",
|
||||
"electronicSheetPrintResult": "打印结果",
|
||||
"deliveryPackageNo": "包裹编号",
|
||||
"printStatus": "状态",
|
||||
"printResultCode": "状态码",
|
||||
"printRemark": "备注",
|
||||
"electronicSheetPrintOperation": "打印面单",
|
||||
"printTicket": "打印小票",
|
||||
"deliveryWay": "发货方式",
|
||||
"manualWriteWay": "手动填写",
|
||||
"electronicSheetWay": "电子面单",
|
||||
"contacts": "联系人",
|
||||
"contactsPlaceholder": "请输入联系人",
|
||||
"ContactInformation": "联系方式",
|
||||
"ContactInformationPlaceholder": "请输入联系方式",
|
||||
"selfPickupStores": "自提门店",
|
||||
"address": "地址",
|
||||
"province": "请选择省",
|
||||
"city": "请选择市",
|
||||
"area": "请选择区/县",
|
||||
"detailedAddress": "请输入详细地址",
|
||||
"refundTitle": "商家主动退款",
|
||||
"refundMoney": "退款金额",
|
||||
"voluntaryRefund": "主动退款",
|
||||
"refundState": "完成状态",
|
||||
"refundType": "退款方式",
|
||||
"refundInstructions": "退款说明",
|
||||
"refundInstructionsOne": "1、如果是退部分金额,退款后可以是部分退款状态或退款完成状态",
|
||||
"refundInstructionsTwo": "2、如果是退全部金额,则退款后一定是退款完成状态",
|
||||
"refundInstructionsThree": "3、退款完成才会执行相关业务如核销码失效,卡包失效等操作",
|
||||
"backRefund": "原路退款",
|
||||
"offlineRefund": "线下退款",
|
||||
"refundToBalance": "退款到余额",
|
||||
"partialRefund": "部分退款状态",
|
||||
"refundFinish": "退款完成状态",
|
||||
"shopActiveRefundMoneyPlaceholder": "主动退款金额不能为空或为零",
|
||||
"shopActiveRefundMoneyTwoPlaceholder": "主动退款金额不能大于可退款总额",
|
||||
"refundGoodsItem": "商品项",
|
||||
"refundGoodsInfo": "商品信息",
|
||||
"refundGoodsSku": "规格",
|
||||
"refundGoodsPrice": "售价",
|
||||
"refundPayPrice": "实付金额",
|
||||
"refundGoodsNum": "数量",
|
||||
"refundGoodsPlaceholder": "请选择退款的商品",
|
||||
"formDetail": "表单详情",
|
||||
"buyerAskDeliveryTime": "要求自提时间",
|
||||
"verifyCode": "核销码",
|
||||
"buyers": "买家",
|
||||
"buyersReserveMobile": "预留手机",
|
||||
"storeTakerName": "提货人",
|
||||
"verifierMember": "核销人",
|
||||
"buyerAskDeliveryTime2":"预约配送时间",
|
||||
"deliveryTransporterMobile": "配送员手机号",
|
||||
"deliveryTransporterName": "配送员",
|
||||
"deliveryTransporterStatus":"配送状态",
|
||||
"deliveryTransporterInfo":"配送信息"
|
||||
}
|
||||
40
niucloud/addon/shop/admin/lang/zh-cn/order.invoice.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"isInvoice": "是否开票",
|
||||
"isInvoicePlaceholder": "请输入开票类型",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"headType": "抬头类型",
|
||||
"headerTypeName": "抬头类型",
|
||||
"person": "个人",
|
||||
"firm": "企业",
|
||||
"headTypePlaceholder": "请输入抬头类型",
|
||||
"headerName": "发票抬头",
|
||||
"headerNamePlaceholder": "请输入发票抬头",
|
||||
"name": "发票内容",
|
||||
"tradeType": "发票类型",
|
||||
"typeName": "发票名称",
|
||||
"headTypeName": "抬头类型",
|
||||
"taxNumber": "纳税人识别号",
|
||||
"mobile": "手机号",
|
||||
"email": "邮件",
|
||||
"telephone": "电话号",
|
||||
"address": "地址",
|
||||
"bankTame": "开户银行",
|
||||
"bankCardNumber": "开户行账号",
|
||||
"money": "开票金额",
|
||||
"invoiceNumber": "发票号码",
|
||||
"invoiceVoucher": "发票凭证",
|
||||
"remark": "备注",
|
||||
"createTime": "创建时间",
|
||||
"invoiceTime": "开票时间",
|
||||
"status": "状态",
|
||||
"operation": "操作",
|
||||
"detail": "详情",
|
||||
"hasInvoice": "已开票",
|
||||
"noInvoice": "未开票",
|
||||
"all": "全部",
|
||||
"invoice": "开票",
|
||||
"viewOrder": "查看订单",
|
||||
"invoiceNumberPlaceholder": "请输入发票号码",
|
||||
"invoiceVoucherPlaceholder": "请输入发票凭证"
|
||||
}
|
||||
164
niucloud/addon/shop/admin/lang/zh-cn/order.list.json
Normal file
@ -0,0 +1,164 @@
|
||||
{
|
||||
"orderNo": "订单编号",
|
||||
"createTime": "下单时间",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"memberInfo": "会员信息",
|
||||
"memberInfoPlaceholder": "请输入会员编号/昵称/账号/手机号搜索",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"orderMoney": "实付金额(元)",
|
||||
"point": "积分",
|
||||
"buyInfo": "买家/收货人",
|
||||
"deliveryType": "配送方式",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"piece": "件",
|
||||
"rightsProtection": "售后",
|
||||
"activeRefund": "主动退款",
|
||||
"notes": "备注",
|
||||
"offlinePayment": "线下支付",
|
||||
"orderClose": "关闭订单",
|
||||
"editPrice": "修改价格",
|
||||
"editAddress": "修改地址",
|
||||
"sendOutGoods": "发货",
|
||||
"confirmTakeDelivery": "确认收货",
|
||||
"all": "全部",
|
||||
"toBePaid": "待支付",
|
||||
"toBeShipped": "待发货",
|
||||
"shipped": "已发货",
|
||||
"receivedGoods": "已收货",
|
||||
"completed": "已完成",
|
||||
"closed": "已关闭",
|
||||
"refunding": "退款中",
|
||||
"notesDetail": "备注信息",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"goodsName": "商品名称",
|
||||
"num": "商品数量",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"fromType": "订单来源",
|
||||
"payType": "支付类型",
|
||||
"orderInfo": "订单信息",
|
||||
"refundStatusName": "退款状态",
|
||||
"outTradeNo": "交易流水号",
|
||||
"exportOrderType": "导出订单类型",
|
||||
"shopOrder": "订单数据表",
|
||||
"shopOrderGoods": "订单商品表",
|
||||
"adjustMoneyDialogTitle": "调整价格",
|
||||
"adjustMoneyUnit": "元",
|
||||
"adjustMoneyTips": "注意 : 只有订单未付款时才支持改价,改价后请联系买家刷新订单核实订单金额后再支付。当订单总额为0元时,订单将自动支付",
|
||||
"adjustMoneyDeliveryMoney": "运费",
|
||||
"adjustMoneyGoodsInfo": "商品信息",
|
||||
"adjustMoneyPrice": "单价",
|
||||
"adjustMoneyNum": "数量",
|
||||
"adjustMoneySubTotal": "小计",
|
||||
"adjustMoneyDiscountMoney": "优惠金额",
|
||||
"adjustMoneyLabel": "调整金额",
|
||||
"adjustMoneyTotal": "总计",
|
||||
"contacts": "联系人",
|
||||
"contactsPlaceholder": "请输入联系人",
|
||||
"ContactInformation": "联系方式",
|
||||
"ContactInformationPlaceholder": "请输入联系方式",
|
||||
"address": "地址",
|
||||
"province": "请选择省",
|
||||
"city": "请选择市",
|
||||
"area": "请选择区/县",
|
||||
"detailedAddress": "请输入详细地址",
|
||||
"selfPickupStores": "自提门店",
|
||||
"electronicSheetPrintTitle": "打印电子面单",
|
||||
"electronicSheetTemplate": "面单模板",
|
||||
"electronicSheetTemplatePlaceholder": "请选择面单模板",
|
||||
"electronicSheetPrintResult": "打印结果",
|
||||
"deliveryPackageNo": "包裹编号",
|
||||
"batchPrintElectronicSheet": "批量打印电子面单",
|
||||
"batchEmptySelectedOrderTips": "请选择要操作的订单",
|
||||
"notSupportPrintElectronicSheetTips": "当前选择的订单不支持打印电子面单",
|
||||
"printStatus": "状态",
|
||||
"printResultCode": "状态码",
|
||||
"printRemark": "备注",
|
||||
"electronicSheetPrintOperation": "打印面单",
|
||||
"printTicket": "打印小票",
|
||||
"deliveryWay": "发货方式",
|
||||
"manualWriteWay": "手动填写",
|
||||
"electronicSheetWay": "电子面单",
|
||||
"refundTitle": "商家主动退款",
|
||||
"refundMoney": "退款金额",
|
||||
"voluntaryRefund": "主动退款",
|
||||
"refundState": "完成状态",
|
||||
"refundType": "退款方式",
|
||||
"refundInstructions": "退款说明",
|
||||
"refundInstructionsOne": "1、如果是退部分金额,退款后可以是部分退款状态或退款完成状态",
|
||||
"refundInstructionsTwo": "2、如果是退全部金额,则退款后一定是退款完成状态",
|
||||
"refundInstructionsThree": "3、退款完成才会执行相关业务如核销码失效,卡包失效等操作",
|
||||
"backRefund": "原路退款",
|
||||
"offlineRefund": "线下退款",
|
||||
"refundToBalance": "退款到余额",
|
||||
"partialRefund": "部分退款状态",
|
||||
"refundFinish": "退款完成状态",
|
||||
"shopActiveRefundMoneyPlaceholder": "主动退款金额不能为空或为零",
|
||||
"shopActiveRefundMoneyTwoPlaceholder": "主动退款金额不能大于可退款总额",
|
||||
"refundGoodsItem": "商品项",
|
||||
"refundGoodsInfo": "商品信息",
|
||||
"refundGoodsSku": "规格",
|
||||
"refundGoodsPrice": "售价",
|
||||
"refundPayPrice": "实付金额",
|
||||
"refundGoodsNum": "数量",
|
||||
"refundGoodsPlaceholder": "请选择退款的商品",
|
||||
"orderType": "订单类型",
|
||||
"orderForm": "订单来源",
|
||||
"takerName": "收货人",
|
||||
"takerMobile": "收货人手机号",
|
||||
"takerFullAddress": "收货地址",
|
||||
"goodsDetail": "商品信息",
|
||||
"price": "价格",
|
||||
"detailNum": "数量",
|
||||
"goodsMoney": "商品总额",
|
||||
"preferentialMoney": "优惠金额",
|
||||
"deliveryMoney": "配送金额",
|
||||
"operateLog": "订单日志",
|
||||
"detailOrderMoney": "订单金额",
|
||||
"payWay": "支付方式",
|
||||
"remind": "提醒",
|
||||
"remindTips1": "买家付款成功后,货款将直接进入您的商户号(微信、支付宝)",
|
||||
"remindTips2": "请及时关注你发出的包裹状态,确保可以配送至买家手中",
|
||||
"remindTips3": "如果买家表示没收到货或货物有问题,请及时联系买家处理,友好协商",
|
||||
"close": "关闭订单",
|
||||
"finish": "确认收货",
|
||||
"delivery": "订单发货",
|
||||
"memberRemark": "买家留言",
|
||||
"discountMoney": "总优惠金额",
|
||||
"couponMoney": "优惠券优惠金额",
|
||||
"manjianDiscountMoney": "满减优惠金额",
|
||||
"orderDelivery": "物流信息",
|
||||
"devliveryTime": "发货时间",
|
||||
"companyName": "物流公司",
|
||||
"logisticNo": "物流单号",
|
||||
"packageInfo": "物流包裹信息",
|
||||
"deliveryInfo": "发货信息",
|
||||
"goodsInfo": "商品信息",
|
||||
"logisticInfo": "物流信息",
|
||||
"storeName": "自提点名称",
|
||||
"storeAddress": "自提点地址",
|
||||
"storeMobile": "自提点电话",
|
||||
"tradeTime": "营业时间",
|
||||
"package": "包裹",
|
||||
"noLogisticsRequired": "无需物流",
|
||||
"notLogistics": "暂无物流信息",
|
||||
"orderInfoEmpty": "暂无数据",
|
||||
"buyerAskDeliveryTime": "要求自提时间",
|
||||
"deleteTips": "是否确认删除该订单?",
|
||||
"batchDeleteTips": "是否确认批量删除选中的订单?"
|
||||
}
|
||||
108
niucloud/addon/shop/admin/lang/zh-cn/order.refund.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"goodsName": "商品名称",
|
||||
"orderNo": "订单编号",
|
||||
"orderRefundNo": "退款编号",
|
||||
"refundTime": "退款时间",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"orderRefundNoPlaceholder": "请输入退款编号",
|
||||
"goodsInfo": "商品信息",
|
||||
"orderMoney": "订单金额",
|
||||
"realityMoney": "实付金额",
|
||||
"goodsMoney": "商品金额",
|
||||
"buyMember": "买家",
|
||||
"refundMoney": "退款金额",
|
||||
"createTime": "申请时间",
|
||||
"refundStatus": "退款状态",
|
||||
"all": "全部",
|
||||
"refundType": "退款方式",
|
||||
"applyForRefund": "申请退款",
|
||||
"refundEnd": "售后结束",
|
||||
"toBeReturned": "买家待退货",
|
||||
"receivedGoods": "卖家待收货",
|
||||
"refundRefuse": "卖家拒绝",
|
||||
"orderInfo": "订单信息",
|
||||
"outTradeNo": "交易流水号",
|
||||
"orderType": "订单类型",
|
||||
"orderForm": "订单来源",
|
||||
"takerName": "收货人",
|
||||
"takerMobile": "收货人手机号",
|
||||
"takerFullAddress": "收货地址",
|
||||
"goodsDetail": "商品信息",
|
||||
"price": "价格",
|
||||
"num": "数量",
|
||||
"preferentialMoney": "优惠金额",
|
||||
"deliveryMoney": "配送金额",
|
||||
"operateLog": "订单日志",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"detailOrderMoney": "实付金额(元)",
|
||||
"buyInfo": "买家/收货人",
|
||||
"deliveryType": "配送方式",
|
||||
"piece": "件",
|
||||
"payType": "支付方式",
|
||||
"notes": "备注",
|
||||
"editAddress": "修改地址",
|
||||
"remind": "提醒",
|
||||
"remindTips1": "如果未发货,请点击同意退款给买家。",
|
||||
"remindTips2": "如果实际已发货,请主动与买家联系。",
|
||||
"remindTips3": "如果订单整体退款后,优惠券和余额会退还给买家。",
|
||||
"close": "关闭订单",
|
||||
"finish": "确认收货",
|
||||
"delivery": "订单发货",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"memberRemark": "买家留言",
|
||||
"discountMoney": "订单详情",
|
||||
"orderDelivery": "物流信息",
|
||||
"devliveryTime": "发货时间",
|
||||
"companyName": "物流公司",
|
||||
"logisticNo": "物流单号",
|
||||
"packageInfo": "物流包裹信息",
|
||||
"deliveryInfo": "发货信息",
|
||||
"logisticInfo": "物流信息",
|
||||
"storeName": "自提点名称",
|
||||
"storeAddress": "自提点地址",
|
||||
"storeMobile": "自提点电话",
|
||||
"tradeTime": "营业时间",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"refundReason": "退款原因",
|
||||
"afterSales": "售后信息",
|
||||
"orderRefundRefuse": "退款拒绝",
|
||||
"orderRefundAgree": "同意退款",
|
||||
"agree": "同意",
|
||||
"applyMoney": "申请金额",
|
||||
"refuse": "拒绝",
|
||||
"transferAccounts": "转账",
|
||||
"refuseReason": "拒绝原因",
|
||||
"shopReasonPlaceholder": "请输入拒绝原因",
|
||||
"confirmDelivery": "确认收货",
|
||||
"orderDeliveryTips": "确定商品收到了吗?",
|
||||
"agreeRefundDelivery": "同意买家收货",
|
||||
"refundDeliveryAddress": "退货地址",
|
||||
"refundVoucher": "申请凭证",
|
||||
"refundRemark": "退款描述",
|
||||
"agreeMoney": "退款金额",
|
||||
"moneyPlaceholder": "请输入退款金额",
|
||||
"refundAddressPlaceholder": "请输入退货地址",
|
||||
"expressCompany": "物流公司",
|
||||
"expressRemark": "物流说明",
|
||||
"orderInfoEmpty": "暂无数据",
|
||||
"closeRefund": "关闭售后",
|
||||
"closeRefundTips": "建议先与用户沟通协商,确认后再关闭售后流程。请谨慎操作,确定要关闭售后吗?"
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
{
|
||||
"orderNo": "订单编号",
|
||||
"orderInfo": "订单信息",
|
||||
"outTradeNo": "交易流水号",
|
||||
"orderType": "订单类型",
|
||||
"orderForm": "订单来源",
|
||||
"takerName": "收货人",
|
||||
"takerMobile": "收货人手机号",
|
||||
"takerFullAddress": "收货地址",
|
||||
"goodsDetail": "商品信息",
|
||||
"goodsName": "商品名称",
|
||||
"price": "价格",
|
||||
"num": "数量",
|
||||
"goodsMoney": "商品总额",
|
||||
"preferentialMoney": "优惠金额",
|
||||
"deliveryMoney": "配送金额",
|
||||
"operateLog": "订单日志",
|
||||
"orderNoPlaceholder": "请输入订单编号",
|
||||
"orderStatus": "订单状态",
|
||||
"orderStatusPlaceholder": "请选择订单状态",
|
||||
"orderFrom": "订单类型",
|
||||
"orderFromPlaceholder": "请选择订单类型",
|
||||
"payTime": "支付时间",
|
||||
"orderGoods": "商品",
|
||||
"goodsPriceNumber": "单价(元)/数量",
|
||||
"orderMoney": "实付金额(元)",
|
||||
"buyInfo": "买家/收货人",
|
||||
"deliveryType": "配送方式",
|
||||
"startDate": "开始时间",
|
||||
"endDate": "结束时间",
|
||||
"piece": "件",
|
||||
"payType": "支付方式",
|
||||
"notes": "备注",
|
||||
"editAddress": "修改地址",
|
||||
"remind": "提醒",
|
||||
"remindTips1": "如果未发货,请点击同意退款给买家。",
|
||||
"remindTips2": "如果实际已发货,请主动与买家联系。",
|
||||
"remindTips3": "如果订单整体退款后,优惠券和余额会退还给买家。",
|
||||
"close": "关闭订单",
|
||||
"finish": "确认收货",
|
||||
"delivery": "订单发货",
|
||||
"deliveryTypePlaceholder": "请选择配送方式",
|
||||
"company": "物流公司",
|
||||
"companyPlaceholder": "请选择物流公司",
|
||||
"expressNumber": "物流单号",
|
||||
"expressNumberPlaceholder": "请输入物流单号",
|
||||
"orderGoodsIdsPlaceholder": "请选择订单项",
|
||||
"virtualDelivery": "虚拟发货",
|
||||
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
|
||||
"orderFinishTips": "是否确认用户已经收货?",
|
||||
"orderGoodsPlaceholder": "请选择要发货的商品",
|
||||
"memberRemark": "买家留言",
|
||||
"discountMoney": "订单详情",
|
||||
"orderDelivery": "物流信息",
|
||||
"devliveryTime": "发货时间",
|
||||
"companyName": "物流公司",
|
||||
"logisticNo": "物流单号",
|
||||
"packageInfo": "物流包裹信息",
|
||||
"deliveryInfo": "发货信息",
|
||||
"goodsInfo": "商品信息",
|
||||
"logisticInfo": "物流信息",
|
||||
"storeName": "自提点名称",
|
||||
"storeAddress": "自提点地址",
|
||||
"storeMobile": "自提点电话",
|
||||
"tradeTime": "营业时间",
|
||||
"deliveryStatusName": "发货状态",
|
||||
"orderRefundNo": "退款编号",
|
||||
"createTime": "申请时间",
|
||||
"refundMoney": "退款金额",
|
||||
"refundReason": "退款原因",
|
||||
"afterSales": "售后信息",
|
||||
"refundStatus": "退款状态",
|
||||
"orderRefundRefuse": "退款拒绝",
|
||||
"orderRefundAgree": "同意退款",
|
||||
"agree": "同意",
|
||||
"applyMoney": "申请金额",
|
||||
"refuse": "拒绝",
|
||||
"transferAccounts": "转账",
|
||||
"refuseReason": "拒绝原因",
|
||||
"shopReasonPlaceholder": "请输入拒绝原因",
|
||||
"confirmDelivery": "确认收货",
|
||||
"orderDeliveryTips": "确定商品收到了吗?",
|
||||
"agreeRefundDelivery": "同意买家收货",
|
||||
"refundDeliveryAddress": "退货地址",
|
||||
"refundVoucher": "申请凭证",
|
||||
"refundRemark": "退款描述",
|
||||
"agreeMoney": "退款金额",
|
||||
"refundType": "退款方式",
|
||||
"moneyPlaceholder": "请输入退款金额",
|
||||
"refundAddressPlaceholder": "请输入退货地址",
|
||||
"expressCompany": "物流公司",
|
||||
"expressRemark": "物流说明",
|
||||
"orderInfoEmpty": "暂无数据"
|
||||
}
|
||||
37
niucloud/addon/shop/admin/lang/zh-cn/stat.goods.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"goodsOverview": "商品概况",
|
||||
"timeFilter": "时间筛选",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"search": "搜索",
|
||||
"goodsAccessNum": "商品浏览量",
|
||||
"goodsAccessNumTip": "统计时间内,所有商品详情页被访问的次数,一个人在统计时间内访问多次记为多次",
|
||||
"goodsVisitCount": "商品访客数",
|
||||
"goodsVisitCountTips": "统计时间内,访问任何商品详情页的人数,一个人在统计时间范围内访问多次只记为一个",
|
||||
"cartNum": "加购件数",
|
||||
"cartNumTips": "统计时间内,添加商品进入购物车的商品件数",
|
||||
"saleNum": "下单件数",
|
||||
"saleNumTips": "统计时间内,成功下单的商品件数之和(不剔除退款订单)",
|
||||
"payNum": "支付件数",
|
||||
"payNumTips": "统计时间内, 成功付款订单的商品件数之和(不剔除退款订单)",
|
||||
"payMoney": "支付金额",
|
||||
"payMoneyTips": "统计时间内,成功付款订单的商品金额之和(不剔除退款订单)",
|
||||
"refundMoney": "退款金额",
|
||||
"refundMoneyTips": "统计时间内,成功退款的商品金额之和",
|
||||
"refundNum": "退款件数",
|
||||
"refundNumTips": "统计时间内,成功退款的商品件数之和",
|
||||
"goodsRank": "商品排行",
|
||||
"goodsName": "商品名称",
|
||||
"goodsNamePlaceholder": "请输入商品名称",
|
||||
"goodsCategory": "商品分类",
|
||||
"all": "全部",
|
||||
"totalType": "统计类型",
|
||||
"totalTypePlaceholder": "请选择统计类型",
|
||||
"goodsInfo": "商品信息",
|
||||
"accessNum": "访问次数",
|
||||
"visitCount": "访客数",
|
||||
"cartNumber": "加入购物车数量",
|
||||
"saleNumber": "商品销量",
|
||||
"payTotal": "支付总金额",
|
||||
"collectNum": "收藏数量"
|
||||
}
|
||||
432
niucloud/addon/shop/admin/views/address/edit.vue
Normal file
@ -0,0 +1,432 @@
|
||||
<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" v-loading="loading">
|
||||
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules" class="page-form">
|
||||
<el-form-item :label="t('addressType')" prop="address_type">
|
||||
<div class="flex flex-col">
|
||||
<div>
|
||||
<el-checkbox v-model="formData.is_delivery_address" :label="t('deliveryAddress')" :true-label="1" :false-label="0"/>
|
||||
<el-checkbox v-model="formData.is_default_delivery" :label="t('defaultDeliveryAddress')" :true-label="1" :false-label="0" v-show="formData.is_delivery_address"/>
|
||||
</div>
|
||||
<div>
|
||||
<el-checkbox v-model="formData.is_refund_address" :label="t('refundAddress')" :true-label="1" :false-label="0"/>
|
||||
<el-checkbox v-model="formData.is_default_refund" :label="t('defaultRefundAddress')" :true-label="1" :false-label="0" v-show="formData.is_refund_address"/>
|
||||
</div>
|
||||
</div>
|
||||
</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="10" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('mobile')" prop="mobile">
|
||||
<el-input v-model.trim="formData.mobile" clearable :placeholder="t('mobilePlaceholder')" maxlength="11" class="input-width" @keyup="filterNumber($event)" @blur="formData.mobile = $event.target.value"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('fullAddress')" prop="address_area">
|
||||
<el-select v-model="formData.province_id" value-key="id" clearable class="w-[200px]" ref="provinceRef">
|
||||
<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" clearable class="w-[200px] ml-3" ref="cityRef">
|
||||
<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" clearable class="w-[200px] ml-3" ref="districtRef">
|
||||
<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">
|
||||
<el-input v-model.trim="formData.address" clearable :placeholder="t('addressPlaceholder')" @input="areaChange()" class="input-width"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div id="container" class="w-[800px] h-[520px] relative" v-loading="mapLoading"></div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer !z-[9999]">
|
||||
<el-button type="primary" @click="onSave(formRef)">{{ 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, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||
import { getShopAddressInfo, addShopAddress, editShopAddress } from '@/addon/shop/api/shop_address'
|
||||
import { getMap, getAreaListByPid, getAreaByCode } from '@/app/api/sys'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { createMarker, latLngToAddress, addressToLatLng } from '@/utils/qqmap'
|
||||
import { filterNumber, debounce } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const id: number = parseInt(route.query.id as string)
|
||||
const loading = ref(false)
|
||||
const pageName = route.meta.title
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
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.lat, formData.lng)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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.lat = result.location.lat
|
||||
formData.lng = result.location.lng
|
||||
formData.address = 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 : 0
|
||||
storeArea.district_id = data.district ? data.district.id : 0
|
||||
})
|
||||
} else {
|
||||
console.error(message, result)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
id: 0,
|
||||
contact_name: '',
|
||||
mobile: '',
|
||||
province_id: 0,
|
||||
city_id: 0,
|
||||
district_id: 0,
|
||||
address: '',
|
||||
full_address: '',
|
||||
lat: 39.908626,
|
||||
lng: 116.397190,
|
||||
is_delivery_address: 0,
|
||||
is_refund_address: 0,
|
||||
is_default_delivery: 0,
|
||||
is_default_refund: 0
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const setFormData = async (id: number = 0) => {
|
||||
loading.value = true
|
||||
Object.assign(formData, initialFormData)
|
||||
const data = await (await getShopAddressInfo(id)).data
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
if (id) setFormData(id)
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
address_type: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!formData.is_delivery_address && !formData.is_refund_address) {
|
||||
callback(new Error(t('addressTypeRequire')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
],
|
||||
contact_name: [
|
||||
{ required: true, message: t('contactNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
mobile: [
|
||||
{ required: true, message: t('mobilePlaceholder'), trigger: 'blur' },
|
||||
{
|
||||
trigger: 'blur',
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value && !/^1[3-9]\d{9}$/.test(value)) {
|
||||
callback(new Error(t('mobileTips')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
],
|
||||
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' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取市
|
||||
*/
|
||||
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 areaChange = debounce(() => {
|
||||
setTimeout(() => {
|
||||
// let province = areaList.province.map((item) => { if (item.id == formData.province_id) { return item.name } })
|
||||
// let city = areaList.city.map((item) => { if (item.id == formData.city_id) { return item.name } })
|
||||
// let district = areaList.district.map((item) => { if (item.id == formData.district_id) { return item.name } })
|
||||
// 获取省名称:找到第一个id匹配的省,取它的name;没找到则返回空字符串
|
||||
let province = areaList.province.find(item => item.id == formData.province_id)?.name || '';
|
||||
// 获取市名称
|
||||
let city = areaList.city.find(item => item.id == formData.city_id)?.name || '';
|
||||
// 获取区名称
|
||||
let district = areaList.district.find(item => item.id == formData.district_id)?.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.lat = result.location.lat
|
||||
formData.lng = result.location.lng
|
||||
} 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 onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
const data = formData
|
||||
let province = areaList.province.find(item => item.id == formData.province_id)?.name || '';
|
||||
// 获取市名称:逻辑同上
|
||||
let city = areaList.city.find(item => item.id == formData.city_id)?.name || '';
|
||||
// 获取区名称:逻辑同上
|
||||
let district = areaList.district.find(item => item.id == formData.district_id)?.name || '';
|
||||
|
||||
const address = [
|
||||
data.province_id ? (provinceRef.value.selectedLabel || province) : '',
|
||||
data.city_id ? (cityRef.value.selectedLabel || city) : '',
|
||||
data.district_id ? (districtRef.value.selectedLabel || district) : '',
|
||||
data.address
|
||||
]
|
||||
data.full_address = address.join('')
|
||||
|
||||
const save = id ? editShopAddress : addShopAddress
|
||||
save(data).then(res => {
|
||||
loading.value = false
|
||||
history.back()
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
history.back()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
157
niucloud/addon/shop/admin/views/address/list.vue
Normal file
@ -0,0 +1,157 @@
|
||||
<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>
|
||||
<el-button type="primary" @click="addEvent">{{ t('addShopAddress') }}</el-button>
|
||||
</div>
|
||||
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="shopAddressTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('mobile')" prop="mobile">
|
||||
<el-input v-model.trim="shopAddressTable.searchParam.mobile" :placeholder="t('mobilePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('fullAddress')" prop="full_address">
|
||||
<el-input v-model.trim="shopAddressTable.searchParam.full_address" :placeholder="t('fullAddressPlaceholder')" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadShopAddressList()">{{ 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="shopAddressTable.data" size="large" v-loading="shopAddressTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !shopAddressTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="contact_name" :label="t('contactName')" min-width="120" />
|
||||
<el-table-column prop="mobile" :label="t('mobile')" min-width="120" />
|
||||
<el-table-column prop="full_address" :label="t('fullAddress')" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="is_delivery_address" :label="t('addressType')" min-width="120" align="left">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.is_delivery_address">
|
||||
{{ t('deliveryAddress') }}
|
||||
<el-tag size="small" v-if="row.is_default_delivery">{{ t('default') }}</el-tag>
|
||||
</div>
|
||||
<div v-if="row.is_refund_address">
|
||||
{{ t('refundAddress') }}
|
||||
<el-tag size="small" v-if="row.is_default_refund">{{ t('default') }}</el-tag>
|
||||
</div>
|
||||
</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="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="shopAddressTable.page"
|
||||
v-model:page-size="shopAddressTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="shopAddressTable.total"
|
||||
@size-change="loadShopAddressList()" @current-change="loadShopAddressList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getShopAddressList, deleteShopAddress } from '@/addon/shop/api/shop_address'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const shopAddressTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
mobile: '',
|
||||
full_address: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取商家地址库列表
|
||||
*/
|
||||
const loadShopAddressList = (page: number = 1) => {
|
||||
shopAddressTable.loading = true
|
||||
shopAddressTable.page = page
|
||||
|
||||
getShopAddressList({
|
||||
page: shopAddressTable.page,
|
||||
limit: shopAddressTable.limit,
|
||||
...shopAddressTable.searchParam
|
||||
}).then(res => {
|
||||
shopAddressTable.loading = false
|
||||
shopAddressTable.data = res.data.data
|
||||
shopAddressTable.total = res.data.total
|
||||
setTablePageStorage(shopAddressTable.page, shopAddressTable.limit, shopAddressTable.searchParam)
|
||||
}).catch(() => {
|
||||
shopAddressTable.loading = false
|
||||
})
|
||||
}
|
||||
loadShopAddressList(getTablePageStorage(shopAddressTable.searchParam).page)
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
/**
|
||||
* 添加商家地址库
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/order/address/edit')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑商家地址库
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/order/address/edit?id=' + data.id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除商家地址库
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('shopAddressDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteShopAddress(id).then(() => {
|
||||
loadShopAddressList(getTablePageStorage(shopAddressTable.searchParam).page)
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadShopAddressList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
157
niucloud/addon/shop/admin/views/delivery/company.vue
Normal file
@ -0,0 +1,157 @@
|
||||
<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-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<el-form :inline="true" :model="companyTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('companyName')" prop="company_name">
|
||||
<el-input v-model.trim="companyTable.searchParam.company_name" :placeholder="t('companyNamePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadCompanyList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="addEvent">{{ t('addCompany') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="companyTable.data" size="large" v-loading="companyTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !companyTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="company_name" :label="t('companyName')" min-width="120" />
|
||||
<el-table-column prop="logo" :label="t('logo')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<div class="w-[50px] h-[50px] flex items-center justify-center">
|
||||
<img v-if="row.logo" class="max-w-[100%] max-h-[100%]" :src="img(row.logo)" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="url" :label="t('url')" min-width="120" />
|
||||
<el-table-column prop="kd100_express_no" :label="t('expressNoKd100')" min-width="120" />
|
||||
<el-table-column prop="express_no" :label="t('expressNo')" min-width="120" />
|
||||
<el-table-column prop="express_no_electronic_sheet" :label="t('expressNoElectronicSheet')" min-width="120" />
|
||||
<el-table-column :label="t('electronicSheetSwitchName')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.electronic_sheet_switch == 1 ? '支持' : '不支持' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.company_id)">{{ t('delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="companyTable.page" v-model:page-size="companyTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="companyTable.total"
|
||||
@size-change="loadCompanyList()" @current-change="loadCompanyList" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getCompanyPageList, deleteCompany } from '@/addon/shop/api/delivery'
|
||||
import { img, setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const companyTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
company_name: '',
|
||||
logo: '',
|
||||
url: '',
|
||||
create_time: '',
|
||||
modify_time: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取物流公司列表
|
||||
*/
|
||||
const loadCompanyList = (page: number = 1) => {
|
||||
companyTable.loading = true
|
||||
companyTable.page = page
|
||||
|
||||
getCompanyPageList({
|
||||
page: companyTable.page,
|
||||
limit: companyTable.limit,
|
||||
...companyTable.searchParam
|
||||
}).then(res => {
|
||||
companyTable.loading = false
|
||||
companyTable.data = res.data.data
|
||||
companyTable.total = res.data.total
|
||||
setTablePageStorage(companyTable.page, companyTable.limit, companyTable.searchParam);
|
||||
}).catch(() => {
|
||||
companyTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadCompanyList(getTablePageStorage(companyTable.searchParam).page);
|
||||
|
||||
/**
|
||||
* 添加物流公司
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/order/delivery/company_add')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑物流公司
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/order/delivery/company_edit?company_id=' + data.company_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除物流公司
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('companyDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteCompany(id).then(() => {
|
||||
loadCompanyList(getTablePageStorage(companyTable.searchParam).page);
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadCompanyList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
316
niucloud/addon/shop/admin/views/delivery/company_edit.vue
Normal file
@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-page-header :content="formData.company_id ? t('updateCompany') : t('addCompany')" :icon="ArrowLeft" @back="back()" />
|
||||
</el-card>
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-form :model="formData" label-width="150px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('companyName')" prop="company_name">
|
||||
<el-input v-model.trim="formData.company_name" maxlength="20" clearable :placeholder="t('companyNamePlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('logo')">
|
||||
<upload-image v-model="formData.logo" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('url')">
|
||||
<el-input v-model.trim="formData.url" clearable :placeholder="t('urlPlaceholder')" class="input-width" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('expressNoKd100')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kd100_express_no" clearable :placeholder="t('expressNoKd100Placeholder')" class="input-width" />
|
||||
<p class="w-[380px] text-[12px] text-[#999] mt-[5px] leading-[20px]">{{ t('expressNoTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('expressNo')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.express_no" clearable :placeholder="t('expressNoPlaceholder')" class="input-width" />
|
||||
<p class="w-[380px] text-[12px] text-[#999] mt-[5px] leading-[20px]">{{ t('expressNoTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('expressNoElectronicSheet')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.express_no_electronic_sheet" clearable :placeholder="t('expressNoElectronicSheetPlaceholder')" class="input-width" />
|
||||
<p class="w-[380px] text-[12px] text-[#999] mt-[5px] leading-[20px]">{{ t('expressNoElectronicSheetTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('electronicSheetSwitch')">
|
||||
<el-switch v-model="formData.electronic_sheet_switch" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('expType')" prop="exp_type" v-show="formData.electronic_sheet_switch">
|
||||
<div class="w-[600px]">
|
||||
<el-table :data="formData.exp_type" size="large" v-show="formData.exp_type.length">
|
||||
<template #empty>
|
||||
<span>{{ formData.exp_type.length == 0 ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="name" :label="t('expTypeName')" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model.trim="row.text" class="input-width" maxlength="20" clearable show-word-limit />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="name" :label="t('expTypeValue')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model.trim="row.value" class="!w-[150px]" maxlength="6" clearable show-word-limit @keyup="filterNumber($event)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="60">
|
||||
<template #default="{ row,$index }">
|
||||
<el-button type="primary" link @click="deleteExpTypeValueEvent($index)">
|
||||
{{ t('delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-button type="primary" plain @click="addExpTypeValueEvent" :class="{'mt-[10px]': formData.exp_type.length}" v-show="formData.exp_type.length < expTypeMaxLength">{{ t('addExpType') }}</el-button>
|
||||
<div class="text-[12px] text-[#999] mt-[5px] leading-[20px]">
|
||||
<span>{{ t('expTypeTips') }}</span>
|
||||
<a class="ml-[3px] text-[var(--el-color-primary)]" target="_blank" href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/hgx758hom5p6wz0l">{{ t('examine') }}</a>
|
||||
</div>
|
||||
<p class="text-[12px] text-[#999] mt-[3px] leading-[20px]">{{ t('expTypeTips1') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('printStyle')" prop="print_style" v-show="formData.electronic_sheet_switch">
|
||||
<div class="w-[600px]">
|
||||
<el-table :data="formData.print_style" size="large" v-show="formData.print_style.length">
|
||||
<template #empty>
|
||||
<span>{{ formData.print_style.length == 0 ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
|
||||
<el-table-column prop="name" :label="t('printStyleName')" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model.trim="row.template_name" class="input-width" maxlength="20" clearable show-word-limit />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="name" :label="t('printStyleId')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model.trim="row.template_size" class="!w-[150px]" maxlength="6" clearable show-word-limit />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="60">
|
||||
<template #default="{ row,$index }">
|
||||
<el-button type="primary" link @click="deletePrintStyleValueEvent($index)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
|
||||
<el-button type="primary" plain @click="addPrintStyleValueEvent" :class="{'mt-[10px]': formData.print_style.length}" v-show="formData.print_style.length < printStyleMaxLength">{{ t('addPrintStyle') }}</el-button>
|
||||
<div class="text-[12px] text-[#999] mt-[5px] leading-[20px]">
|
||||
<span>{{ t('printStyleTips') }}</span>
|
||||
<a class="ml-[3px] text-[var(--el-color-primary)]" target="_blank" href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/vpptucr1q5ahcxa7">{{ t('examine') }}</a>
|
||||
</div>
|
||||
<p class="text-[12px] text-[#999] mt-[3px] leading-[20px]">{{ t('printStyleTips1') }}</p>
|
||||
<p class="text-[12px] text-[#999] mt-[3px] leading-[20px]">{{ t('printStyleTips2') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" @click="save(formRef)">{{ t('save') }}</el-button>
|
||||
<el-button @click="back()">{{ t('back') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { addCompany, editCompany, getCompanyInfo } from '@/addon/shop/api/delivery'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { filterNumber } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loading = ref(true)
|
||||
|
||||
const back = () => {
|
||||
router.push('/shop/order/delivery/company')
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
company_id: '',
|
||||
company_name: '',
|
||||
logo: '',
|
||||
url: '',
|
||||
kd100_express_no: '',
|
||||
express_no: '',
|
||||
express_no_electronic_sheet: "",
|
||||
print_style: [],
|
||||
exp_type: [],
|
||||
electronic_sheet_switch: 1
|
||||
}
|
||||
|
||||
const printStyleMaxLength = ref(10)
|
||||
const expTypeMaxLength = ref(10)
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
formData.company_id = ref(route.query.company_id)
|
||||
|
||||
const getCompanyInfoFn = () => {
|
||||
getCompanyInfo(formData.company_id).then(res => {
|
||||
loading.value = false;
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
if (formData.company_id) {
|
||||
getCompanyInfoFn();
|
||||
} else {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
company_name: [
|
||||
{ required: true, message: t('companyNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
exp_type: [
|
||||
{
|
||||
trigger: 'blur',
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!value.length) {
|
||||
callback()
|
||||
return false;
|
||||
}
|
||||
let textArr = []; //业务名称集合
|
||||
let valArr = []; //业务值集合
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (!value[i].text) {
|
||||
callback(new Error(t('expTypeTextTips')))
|
||||
break;
|
||||
} else if (value[i].text) {
|
||||
textArr.push(value[i].text);
|
||||
}
|
||||
if (!value[i].value) {
|
||||
callback(new Error(t('expTypeValueTips')))
|
||||
break;
|
||||
} else if (parseFloat(value[i].value) == 0) {
|
||||
callback(new Error(t('expTypeValueNullTips')))
|
||||
break;
|
||||
} else if (value[i].value) {
|
||||
valArr.push(value[i].value);
|
||||
}
|
||||
}
|
||||
if (new Set(textArr).size !== textArr.length) {
|
||||
callback(new Error(t('expTypeTextRepeatTips')))
|
||||
}
|
||||
if (new Set(valArr).size !== valArr.length) {
|
||||
callback(new Error(t('expTypeValueRepeatTips')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
],
|
||||
print_style: [
|
||||
{
|
||||
trigger: 'blur',
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!value.length) {
|
||||
callback()
|
||||
return false;
|
||||
}
|
||||
let nameArr = []; //业务名称集合
|
||||
let sizeArr = []; //业务值集合
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (!value[i].template_name) {
|
||||
callback(new Error(t('printStyleNameTips')))
|
||||
break;
|
||||
} else if (value[i].template_name) {
|
||||
nameArr.push(value[i].template_name);
|
||||
}
|
||||
if (!value[i].template_size) {
|
||||
callback(new Error(t('printStyleSizeTips')))
|
||||
break;
|
||||
} else if (value[i].template_size) {
|
||||
sizeArr.push(value[i].template_size);
|
||||
}
|
||||
}
|
||||
if (new Set(nameArr).size !== nameArr.length) {
|
||||
callback(new Error(t('printStyleNameRepeatTips')))
|
||||
}
|
||||
if (new Set(sizeArr).size !== sizeArr.length) {
|
||||
callback(new Error(t('printStyleSizeRepeatTips')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 添加模版样式
|
||||
const addPrintStyleValueEvent = () => {
|
||||
formData.print_style.push({
|
||||
template_name: '',
|
||||
template_size: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 添加业务类型
|
||||
const addExpTypeValueEvent = () => {
|
||||
formData.exp_type.push({
|
||||
text: '',
|
||||
value: ''
|
||||
})
|
||||
}
|
||||
|
||||
// 删除模版样式
|
||||
const deletePrintStyleValueEvent = (index: any) => {
|
||||
formData.print_style.splice(index, 1)
|
||||
}
|
||||
|
||||
// 删除业务类型
|
||||
const deleteExpTypeValueEvent = (index: any) => {
|
||||
formData.exp_type.splice(index, 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const repeat = ref(false)
|
||||
const save = async(formEl: FormInstance | undefined) => {
|
||||
if (repeat.value || !formEl) return
|
||||
const api = formData.company_id ? editCompany : addCompany
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
|
||||
if (valid) {
|
||||
repeat.value = true
|
||||
|
||||
const data = formData
|
||||
api(data).then(res => {
|
||||
router.push('/shop/order/delivery/company')
|
||||
repeat.value = false
|
||||
}).catch(() => {
|
||||
repeat.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" :title="formData.deliver_id ? t('updateDeliver') : t('addDeliveryPersonnel')" 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('deliverName')" prop="deliver_name">
|
||||
<el-input v-model.trim="formData.deliver_name" clearable :placeholder="t('deliverNamePlaceholder')" class="input-width" maxlength="10" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliverMobile')" prop="deliver_mobile">
|
||||
<el-input v-model.trim="formData.deliver_mobile" clearable :placeholder="t('deliverMobilePlaceholder')" class="input-width" @keyup="filterNumber($event)" @blur="formData.deliver_mobile = $event.target.value" />
|
||||
</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 { addShopDeliver, editShopDeliver, getShopDeliverInfo } from '@/addon/shop/api/delivery'
|
||||
import { filterNumber } from '@/utils/common'
|
||||
|
||||
const showDialog = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
deliver_id: '',
|
||||
deliver_name: '',
|
||||
deliver_mobile: ''
|
||||
}
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
deliver_name: [
|
||||
{ required: true, message: t('deliverNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
deliver_mobile: [
|
||||
{ required: true, message: t('deliverMobilePlaceholder'), trigger: 'blur' },
|
||||
{ min: 11, max: 11, message: '请输入11位手机号码', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[23456789]\d{9}$/,
|
||||
message: '请输入正确的手机号码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['complete'])
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
const save = formData.deliver_id ? editShopDeliver : addShopDeliver
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
const data = formData
|
||||
|
||||
save(data).then(res => {
|
||||
loading.value = false
|
||||
showDialog.value = false
|
||||
emit('complete')
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const setFormData = async(row: any = null) => {
|
||||
Object.assign(formData, initialFormData)
|
||||
loading.value = true
|
||||
if (row) {
|
||||
const data = await (await getShopDeliverInfo(row.deliver_id)).data
|
||||
if (data) {
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showDialog,
|
||||
setFormData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.diy-dialog-wrap .el-form-item__label {
|
||||
height: auto !important;
|
||||
}
|
||||
</style>
|
||||
137
niucloud/addon/shop/admin/views/delivery/config.vue
Normal file
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<div class="main-container" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<div class="flex justify-between items-center mb-[20px]">
|
||||
<span class="text-page-title">{{ pageName }}</span>
|
||||
</div>
|
||||
<div ref="tableRef" :key="toggleIndex" v-if="!loading">
|
||||
<template v-for="(item, index) in tableData" :key="item.key">
|
||||
<div class="mb-[20px] bg-[#fff]">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<i class="iconfont icontuodong vues-rank mr-[5px]"></i>
|
||||
<el-input v-focus v-if="index === activeIndex" v-model.trim="inputValue" class="w-[120px]" maxlength="10" @blur="inputBlur" />
|
||||
<span v-else class="font-600 text-[14px]">{{ item.name }}</span>
|
||||
<el-icon class="text-color ml-[10px] cursor-pointer" @click="edit(index)">
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</div>
|
||||
<el-switch v-model="item.status" :active-value="1" :inactive-value="2" @change="update" />
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex items-center justify-between">
|
||||
<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>
|
||||
</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>
|
||||
</template>
|
||||
<template v-if="item.key === 'store'">
|
||||
<el-button type="primary" link @click="goRouter('/shop/order/delivery/store')">{{ t('deliveryStore') }}</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, nextTick, ref, toRaw } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import Sortable from 'sortablejs'
|
||||
import { getShopDeliveryList, setShopDeliveryConfig } from '@/addon/shop/api/delivery'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
const loading = ref(false)
|
||||
|
||||
interface TableDataType {
|
||||
key: string
|
||||
name: string
|
||||
status: number
|
||||
}
|
||||
|
||||
const tableData = ref<TableDataType[]>([])
|
||||
const getShopDeliveryListFn = () => {
|
||||
loading.value = true
|
||||
getShopDeliveryList().then(res => {
|
||||
tableData.value = res.data
|
||||
loading.value = false
|
||||
nextTick(() => {
|
||||
if (rowDrop) rowDrop()
|
||||
})
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
getShopDeliveryListFn()
|
||||
})
|
||||
// 拖拽排序
|
||||
const toggleIndex = ref(0)
|
||||
const tableRef = ref()
|
||||
const rowDrop = () => {
|
||||
Sortable.create(tableRef.value, {
|
||||
handle: '.vues-rank',
|
||||
animation: 300,
|
||||
onEnd({ newIndex, oldIndex }) {
|
||||
const currRow = tableData.value.splice(oldIndex, 1)[0]
|
||||
tableData.value.splice(newIndex, 0, currRow)
|
||||
toggleIndex.value += 1
|
||||
nextTick(() => {
|
||||
rowDrop()
|
||||
})
|
||||
update()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑名称
|
||||
const activeIndex = ref<number | null>(null)
|
||||
const inputValue = ref('')
|
||||
const edit = (index: number) => {
|
||||
activeIndex.value = index
|
||||
inputValue.value = toRaw(tableData.value[index].name)
|
||||
}
|
||||
const inputBlur = () => {
|
||||
if (inputValue.value == '' || tableData.value[activeIndex.value].name === inputValue.value) {
|
||||
activeIndex.value = null
|
||||
inputValue.value = ''
|
||||
return false
|
||||
}
|
||||
tableData.value[activeIndex.value].name = inputValue.value
|
||||
activeIndex.value = null
|
||||
update()
|
||||
}
|
||||
const update = () => {
|
||||
setShopDeliveryConfig({
|
||||
value: tableData.value
|
||||
})
|
||||
}
|
||||
const goRouter = (path: string) => {
|
||||
router.push({ path })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.text-color {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
:deep(.el-card__header) {
|
||||
padding-top: 5px !important;
|
||||
padding-bottom: 5px !important;
|
||||
}
|
||||
</style>
|
||||
198
niucloud/addon/shop/admin/views/delivery/electronic_sheet.vue
Normal file
@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<div class="flex justify-between items-center mb-[5px]">
|
||||
<span class="text-lg">{{pageName}}</span>
|
||||
<el-button type="primary" @click="addEvent">{{ t('addElectronicSheet') }}</el-button>
|
||||
</div>
|
||||
|
||||
<el-tabs model-value="/shop/delivery/electronic_sheet" @tab-change="handleClick">
|
||||
<el-tab-pane :label="t('tabESTemplate')" name="/shop/delivery/electronic_sheet" />
|
||||
<el-tab-pane :label="t('tabESConfig')" name="/shop/delivery/electronic_sheet/config" />
|
||||
</el-tabs>
|
||||
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<el-form :inline="true" :model="tableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model.trim="tableData.searchParam.template_name" :placeholder="t('templateNamePlaceholder')" maxlength="30" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('expressCompany')" prop="express_company_id">
|
||||
<el-select v-model="tableData.searchParam.express_company_id" :placeholder="t('expressCompanyPlaceholder')" clearable>
|
||||
<el-option v-for="item in companyList" :key="item.company_id" :label="item.company_name" :value="item.company_id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadList()">{{ 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="tableData.data" size="large" v-loading="tableData.loading">
|
||||
<template #empty>
|
||||
<span>{{ !tableData.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column :label="t('templateName')" min-width="200" :show-overflow-tooltip="true">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small" v-if="row.is_default">{{ t('isDefault') }}</el-tag>
|
||||
<span class="ml-[8px]">{{row.template_name}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="express_company_id" :label="t('expressCompany')" min-width="120" :show-overflow-tooltip="true">
|
||||
<template #default="{ row }">
|
||||
<div>{{ row.company.company_name }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="pay_type_name" :label="t('payType')" min-width="80" :show-overflow-tooltip="true"/>
|
||||
|
||||
<el-table-column prop="status" :label="t('status')" min-width="80" :show-overflow-tooltip="true" >
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.status == 1">{{ t('statusOn') }}</div>
|
||||
<div v-if="row.status == 0">{{ t('statusOff') }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" min-width="80" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link v-if="!row.is_default" @click="setDefaultEvent(row.id)">{{ t('setDefault') }}</el-button>
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link v-if="!row.is_default" @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="tableData.total"
|
||||
@size-change="loadList()" @current-change="loadList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getElectronicSheetPageList, deleteElectronicSheet, setDefaultElectronicSheet } from '@/addon/shop/api/electronic_sheet'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getCompanyList } from '@/addon/shop/api/delivery'
|
||||
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const tableData = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
template_name: '',
|
||||
express_company_id: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
const handleClick = (path: string) => {
|
||||
router.push({ path })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电子面单列表
|
||||
*/
|
||||
const loadList = (page: number = 1) => {
|
||||
tableData.loading = true
|
||||
tableData.page = page
|
||||
|
||||
getElectronicSheetPageList({
|
||||
page: tableData.page,
|
||||
limit: tableData.limit,
|
||||
...tableData.searchParam
|
||||
}).then(res => {
|
||||
tableData.loading = false
|
||||
tableData.data = res.data.data
|
||||
tableData.total = res.data.total
|
||||
setTablePageStorage(tableData.page, tableData.limit, tableData.searchParam)
|
||||
}).catch(() => {
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
loadList(getTablePageStorage(tableData.searchParam).page)
|
||||
|
||||
const companyList = ref([])
|
||||
|
||||
getCompanyList({
|
||||
electronic_sheet_switch: 1
|
||||
}).then((res:any) => {
|
||||
companyList.value = res.data
|
||||
})
|
||||
|
||||
/**
|
||||
* 添加电子面单
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/delivery/electronic_sheet_add')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑电子面单
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/delivery/electronic_sheet_edit?id=' + data.id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除电子面单
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('electronicSheetDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteElectronicSheet(id).then(() => {
|
||||
loadList(getTablePageStorage(tableData.searchParam).page)
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 设置默认电子面单模版
|
||||
*/
|
||||
const setDefaultEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('electronicSheetSetDefaultTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
setDefaultElectronicSheet({ id }).then(() => {
|
||||
loadList(getTablePageStorage(tableData.searchParam).page)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<div class="flex justify-between items-center mb-[5px] h-[32px]">
|
||||
<span class="text-lg">{{ pageName }}</span>
|
||||
</div>
|
||||
|
||||
<el-tabs model-value="/shop/delivery/electronic_sheet/config" @tab-change="handleClick">
|
||||
<el-tab-pane :label="t('tabESTemplate')" name="/shop/delivery/electronic_sheet" />
|
||||
<el-tab-pane :label="t('tabESConfig')" name="/shop/delivery/electronic_sheet/config" />
|
||||
</el-tabs>
|
||||
|
||||
<el-form class="page-form" :model="formData" :rules="formRules" label-width="150px" ref="formRef" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('apiSet') }}</h3>
|
||||
|
||||
<el-form-item :label="t('interfaceType')" prop="interface_type">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.interface_type">
|
||||
<el-radio label="kdbird" size="large">{{ t('kdn') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<template v-if="formData.interface_type == 'kdbird'">
|
||||
<p class="text-[12px] text-[#b2b2b2]">
|
||||
{{ t('promptTips1-1') }}
|
||||
<el-button class="button-size" type="primary" link @click="kdnEvent('https://www.kdniao.com/reg?from=niucloud')">https://www.kdniao.com</el-button>
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<div v-if="formData.interface_type == 'kdbird'">
|
||||
|
||||
<el-form-item :label="t('kdnEBusinessIDLabel')" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kdniao_id" :placeholder="t('kdnEBusinessIDPlaceholder')" class="input-width" clearable />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kdnEBusinessIDTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="API key" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kdniao_api_key" clearable :placeholder="t('kdnAppKeyPlaceholder')" class="input-width" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kdnAppKeyTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('printerSet') }}</h3>
|
||||
|
||||
<el-alert type="warning" :closable="false" class="!mb-[10px]">
|
||||
<template #default>
|
||||
<p>用双端口加载主JS文件Lodop.js(或CLodopfuncs.js兼容老版本)以防其中某端口被占</p>
|
||||
<p>HTTP推荐端口:8000/18000,HTTPS推荐端口:8443</p>
|
||||
<p>1. 请将打印机连接至本机。 </p>
|
||||
<p>2. 在本机上安装打印控件。下载链接:<a href="http://www.lodop.net/download.html" target="_blank" class="text-primary">http://www.lodop.net/download.html</a></p>
|
||||
<p>3. 将打印控件中的打印端口下面的打印端口设为相同。</p>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<el-form-item :label="t('serverPort1')" class="input-item-required" prop="server_port1">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.server_port1" :placeholder="t('serverPort1Placeholder')" class="input-width" clearable />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('serverPort2')" class="input-item-required" prop="server_port2">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.server_port2" :placeholder="t('serverPort2Placeholder')" class="input-width" clearable />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('httpsPort')" class="input-item-required" prop="https_port">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.https_port" :placeholder="t('httpsPortPlaceholder')" class="input-width" clearable />
|
||||
</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>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { FormInstance, FormRules } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setElectronicSheetConfig, getElectronicSheetConfig } from '@/addon/shop/api/electronic_sheet'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title;
|
||||
const loading = ref(true)
|
||||
|
||||
const handleClick = (path: string) => {
|
||||
router.push({ path })
|
||||
}
|
||||
|
||||
const formData: any = reactive({
|
||||
interface_type: 'kdbird',
|
||||
kdniao_id: '',
|
||||
kdniao_api_key: '',
|
||||
server_port1: '8000',
|
||||
server_port2: '18000',
|
||||
https_port: '8443'
|
||||
})
|
||||
|
||||
const setFormData = async() => {
|
||||
const data = await (await getElectronicSheetConfig()).data
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
|
||||
loading.value = false
|
||||
}
|
||||
setFormData()
|
||||
|
||||
const kdnEvent = (url: any) => {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = reactive<FormRules>({
|
||||
server_port1: [
|
||||
{ required: true, message: t('serverPort1Placeholder'), trigger: 'blur' },
|
||||
],
|
||||
server_port2: [
|
||||
{ required: true, message: t('serverPort2Placeholder'), trigger: 'blur' },
|
||||
],
|
||||
https_port: [
|
||||
{ required: true, message: t('httpsPortPlaceholder'), trigger: 'blur' },
|
||||
]
|
||||
})
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
const save = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
setElectronicSheetConfig(formData).then(() => {
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.input-item {
|
||||
margin-bottom: 10px !important
|
||||
}
|
||||
|
||||
.input-item-required {
|
||||
margin-bottom: 20px !important
|
||||
}
|
||||
|
||||
.button-size {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-radio.el-radio--large {
|
||||
height: auto !important
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,270 @@
|
||||
<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-form class="page-form" :model="formData" :rules="formRules" label-width="150px" ref="formRef" v-loading="loading">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
|
||||
<h3 class="panel-title !text-sm">{{ t('basicSettings') }}</h3>
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model.trim="formData.template_name" clearable :placeholder="t('templateNamePlaceholder')" class="input-width" maxlength="30" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('expressCompany')" prop="express_company_id">
|
||||
<el-select v-model="formData.express_company_id" :placeholder="t('expressCompanyPlaceholder')" clearable @change="handleSelectCompanyChange">
|
||||
<el-option v-for="item in companyList" :key="item.company_id" :label="item.company_name" :value="item.company_id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('expType')" prop="exp_type" v-show="expTypeList.length">
|
||||
<el-radio-group v-model="formData.exp_type">
|
||||
<el-radio v-for="(item,index) in expTypeList" :key="index" :value="item.value">{{ item.text }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('printStyle')" v-show="printStyleList.length">
|
||||
<div>
|
||||
<el-select v-model="formData.print_style" :placeholder="t('printStylePlaceholder')" clearable>
|
||||
<el-option v-for="(item,index) in printStyleList" :key="index" :label="item.template_name" :value="item.template_size" />
|
||||
</el-select>
|
||||
<div class="text-[12px] text-[#999] mt-[3px] leading-[20px]">{{ t('printStyleTips1') }}</div>
|
||||
<div class="text-[12px] text-[#999] mt-[3px] leading-[20px]">{{ t('printStyleTips2') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</el-card>
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<h3 class="panel-title !text-sm">{{ t('otherSettings') }}</h3>
|
||||
|
||||
<el-form-item :label="t('customerName')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.customer_name" clearable class="input-width" maxlength="20" />
|
||||
<div class="flex items-center mt-[5px] text-[12px] text-[#999] leading-[20px]">
|
||||
<span>{{ t('customerNameTips') }}</span>
|
||||
<a class="ml-[3px] text-[var(--el-color-primary)]" target="_blank" href="https://www.yuque.com/kdnjishuzhichi/rg4owd">{{ t('examine') }}</a>
|
||||
</div>
|
||||
<div class="flex items-center mt-[3px] text-[12px] text-[#999] leading-[20px]">
|
||||
<span>{{ t('customerNameTips1') }}</span>
|
||||
<a class="ml-[3px] text-[var(--el-color-primary)]" target="_blank" href="https://www.yuque.com/kdnjishuzhichi/dfcrg1/hrfw43">{{ t('examine') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('customerPwd')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.customer_pwd" clearable class="input-width" maxlength="50" />
|
||||
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('customerPwdTips') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('sendSite')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.send_site" clearable class="input-width" maxlength="20" />
|
||||
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('sendSiteTips') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('sendStaff')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.send_staff" clearable class="input-width" maxlength="20" />
|
||||
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('sendStaffTips') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('monthCode')">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.month_code" clearable class="input-width" maxlength="20" />
|
||||
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('monthCodeTips') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('payType')">
|
||||
<el-radio-group v-model="formData.pay_type">
|
||||
<el-radio v-for="(item,index) in payType" :value="parseInt(index)">{{ item }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('isNotice')">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.is_notice">
|
||||
<el-radio :value="1">{{ t('yes') }}</el-radio>
|
||||
<el-radio :value="0">{{ t('no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('isNoticeTips') }}</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('status')">
|
||||
<el-switch v-model="formData.status" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('isDefault')">
|
||||
<el-switch v-model="formData.is_default" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
|
||||
</el-card>
|
||||
</el-form>
|
||||
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer">
|
||||
<el-button type="primary" :loading="repeat" @click="confirm(formRef)">{{ t('save') }}</el-button>
|
||||
<el-button @click="back()">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from "@element-plus/icons-vue"
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import {
|
||||
addElectronicSheet,
|
||||
editElectronicSheet,
|
||||
getElectronicSheetInfo,
|
||||
getElectronicSheetPayType
|
||||
} from '@/addon/shop/api/electronic_sheet'
|
||||
import { getCompanyList } from '@/addon/shop/api/delivery'
|
||||
|
||||
const loading = ref(false)
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const repeat = ref(false)
|
||||
|
||||
const pageName = route.meta.title
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData: any = {
|
||||
id: route.query.id || 0,
|
||||
template_name: '',
|
||||
express_company_id: '',
|
||||
customer_name: '',
|
||||
customer_pwd: '',
|
||||
send_site: '',
|
||||
send_staff: '',
|
||||
month_code: '',
|
||||
pay_type: 1,
|
||||
is_notice: 0,
|
||||
status: 1,
|
||||
exp_type: 1,
|
||||
print_style: '',
|
||||
is_default: ''
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
template_name: [
|
||||
{ required: true, message: t('templateNamePlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
express_company_id: [
|
||||
{ required: true, message: t('expressCompanyPlaceholder'), trigger: 'blur' },
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const companyList: any = ref([]) // 物流公司列表
|
||||
const expTypeList: any = ref([]) // 业务类型
|
||||
const printStyleList: any = ref([]) // 模版样式
|
||||
const payType = ref([])
|
||||
|
||||
const init = async() => {
|
||||
getElectronicSheetPayType().then((res: any) => {
|
||||
payType.value = res.data;
|
||||
})
|
||||
|
||||
await getCompanyList({ electronic_sheet_switch: 1 }).then((res: any) => {
|
||||
companyList.value = res.data;
|
||||
})
|
||||
|
||||
if (formData.id) {
|
||||
loading.value = true
|
||||
getElectronicSheetInfo(formData.id).then((res: any) => {
|
||||
let data = res.data;
|
||||
if (data) Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
loading.value = false
|
||||
handleSelectCompanyChange(formData.express_company_id, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
const handleSelectCompanyChange = (value: any, load: any = false) => {
|
||||
if (!value) {
|
||||
expTypeList.value = [];
|
||||
printStyleList.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < companyList.value.length; i++) {
|
||||
if (companyList.value[i].company_id == value) {
|
||||
expTypeList.value = companyList.value[i].exp_type;
|
||||
expTypeList.value.forEach((item: any) => {
|
||||
if (item.value) item.value = parseInt(item.value);
|
||||
})
|
||||
printStyleList.value = companyList.value[i].print_style;
|
||||
|
||||
if (!load) {
|
||||
if (expTypeList.value.length) {
|
||||
formData.exp_type = expTypeList.value[0].value
|
||||
} else {
|
||||
formData.exp_type = 1; // 默认为1
|
||||
}
|
||||
if (printStyleList.value.length) {
|
||||
formData.print_style = printStyleList.value[0].value
|
||||
} else {
|
||||
formData.print_style = ''; // 默认为空
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const confirm = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
let save = formData.id ? editElectronicSheet : addElectronicSheet
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
|
||||
if (repeat.value) return
|
||||
repeat.value = true
|
||||
|
||||
let data = formData
|
||||
|
||||
save(data).then(res => {
|
||||
repeat.value = false
|
||||
if (!formData.id) {
|
||||
router.push('/shop/delivery/electronic_sheet')
|
||||
}
|
||||
}).catch(err => {
|
||||
repeat.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push('/shop/delivery/electronic_sheet')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
749
niucloud/addon/shop/admin/views/delivery/local.vue
Normal file
@ -0,0 +1,749 @@
|
||||
<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-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-item :label="t('feeType')">
|
||||
<el-radio-group v-model="formData.fee_type">
|
||||
<el-radio label="region">{{ t('region') }}</el-radio>
|
||||
<el-radio label="distance">{{ t('distance') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('feeSetting')" prop="distance" v-show="formData.fee_type == 'distance'">
|
||||
<div class="flex">
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.number="formData.base_dist" type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextOne') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.base_price" type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextTwo') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.number="formData.grad_dist" type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('feeSettingTextThree') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.grad_price" type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('priceUnit') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('weightFee')" prop="">
|
||||
<div class="flex">
|
||||
{{ t('weightFeeTextOne') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.weight_start" type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('weightFeeTextTwo') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.weight_unit" type="text" maxlength="6" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ t('weightFeeTextThree') }}
|
||||
<div class="w-[60px] mx-[5px]">
|
||||
<el-input v-model.trim="formData.weight_price" type="text" maxlength="8" @keyup="filterDigit($event)" />
|
||||
</div>
|
||||
{{ 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>
|
||||
</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)" />
|
||||
</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-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, computed, onMounted, onBeforeUnmount,toRaw } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
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 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,
|
||||
area: [
|
||||
{
|
||||
area_name: '',
|
||||
area_type: 'radius',
|
||||
start_price: 0,
|
||||
delivery_price: 0,
|
||||
area_json: {
|
||||
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 regExp = {
|
||||
required: /[\S]+/,
|
||||
number: /^\d{0,10}$/,
|
||||
digit: /^\d{0,10}(.?\d{0,2})$/,
|
||||
special: /^\d{0,10}(.?\d{0,3})$/
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
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')))
|
||||
}
|
||||
if (Test.require(formData.value.base_price)) {
|
||||
callback(new Error(t('basePriceRequire')))
|
||||
}
|
||||
if (Test.require(formData.value.grad_dist)) {
|
||||
callback(new Error(t('gradDistRequire')))
|
||||
}
|
||||
if (Test.require(formData.value.grad_price)) {
|
||||
callback(new Error(t('gradPriceRequire')))
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
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: 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 (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' }
|
||||
],
|
||||
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'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
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(()=>{
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const mapScript = document.createElement('script')
|
||||
getMap().then(res => {
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
let map: 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)
|
||||
|
||||
map = new TMap.Map('container', {
|
||||
center,
|
||||
zoom: 14
|
||||
})
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
const currArea = ref<number>(0)
|
||||
|
||||
/**
|
||||
* 添加配送区域
|
||||
*/
|
||||
const addArea = () => {
|
||||
formData.value.area.push({
|
||||
area_name: '',
|
||||
area_type: 'radius',
|
||||
start_price: 0,
|
||||
delivery_price: 0,
|
||||
area_json: {
|
||||
key: guid()
|
||||
}
|
||||
})
|
||||
const index = formData.value.area.length - 1
|
||||
createCircle(map, formData.value.area[index].area_json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配送区域
|
||||
*/
|
||||
const deleteArea = (index: number) => {
|
||||
const data = formData.value.area[index]
|
||||
deleteGeometry(data.area_json.key)
|
||||
formData.value.area.splice(index, 1)
|
||||
}
|
||||
|
||||
const selectArea = (index: number) => {
|
||||
currArea.value = index
|
||||
const data = formData.value.area[index]
|
||||
selectGeometry(data.area_json.key)
|
||||
}
|
||||
|
||||
const areaTypeChange = (index: number) => {
|
||||
const data = formData.value.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 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 (!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]
|
||||
setLocal(param).then(() => {
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push({ path: '/shop/order/delivery' })
|
||||
}
|
||||
</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>
|
||||
164
niucloud/addon/shop/admin/views/delivery/search.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({ path: '/shop/order/delivery' })" />
|
||||
</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">
|
||||
<el-form-item :label="t('interfaceType')" prop="interface_type">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.interface_type">
|
||||
<el-radio :label="1" size="large">{{ t('kdn') }}</el-radio>
|
||||
<el-radio :label="2" size="large">{{ t('kd100') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<p class="text-[12px] text-[#b2b2b2]" v-if="formData.interface_type == 1">
|
||||
{{ t('promptTips1-1') }}
|
||||
<el-button class="button-size" type="primary" link @click="openEvent('https://www.kdniao.com/reg?from=niucloud')">https://www.kdniao.com</el-button>
|
||||
</p>
|
||||
<p class="text-[12px] text-[#b2b2b2]" v-if="formData.interface_type == 2">
|
||||
{{ t('promptTips2') }}<el-button class="button-size" type="primary" link @click="openEvent('https://www.kuaidi100.com')">https://www.kuaidi100.com</el-button>
|
||||
</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<div v-if="formData.interface_type == 1">
|
||||
<el-form-item :label="t('isPayEdition')" prop="kdn_is_pay">
|
||||
<div>
|
||||
<el-radio-group v-model="formData.kdniao_is_pay">
|
||||
<el-radio :label="1" size="large">{{ t('PayPerOrder') }}</el-radio>
|
||||
<el-radio :label="2" size="large">{{ t('PayPerUse') }}</el-radio>
|
||||
</el-radio-group>
|
||||
<p class="text-[12px] text-[#b2b2b2]" v-if="formData.interface_type == 1">
|
||||
{{ t('promptTips1-2') }}
|
||||
</p>
|
||||
<p class="text-[12px] text-[#b2b2b2]" v-if="formData.interface_type == 1">
|
||||
{{ t('promptTips1-3') }}
|
||||
</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="EBusinessID" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kdniao_id" :placeholder="t('kdnEBusinessIDPlaceholder')" class="input-width" clearable />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kdnEBusinessIDTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="APPKEY" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kdniao_app_key" clearable :placeholder="t('kdnAppKeyPlaceholder')" class="input-width" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kdnAppKeyTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="formData.interface_type == 2">
|
||||
<el-form-item label="APPKEY" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kd100_app_key" clearable :placeholder="t('kd100AppKeyPlaceholder')" class="input-width" />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kd100AppKeyTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="CUSTOMER" class="input-item">
|
||||
<div>
|
||||
<el-input v-model.trim="formData.kd100_customer" :placeholder="t('kd100CustomerPlaceholder')" class="input-width" clearable />
|
||||
<p class="text-[12px] text-[#b2b2b2]">{{ t('kd100CustomerTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
</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 lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { FormInstance, FormRules } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setDeliverySearch, getDeliverySearch } from '@/addon/shop/api/delivery'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
const loading = ref(true)
|
||||
|
||||
interface formDataType {
|
||||
interface_type: number
|
||||
kdniao_id: string
|
||||
kdniao_app_key: string
|
||||
kdniao_is_pay: number
|
||||
kd100_app_key: string
|
||||
kd100_customer: string
|
||||
}
|
||||
|
||||
const formData = reactive<formDataType | any>({
|
||||
interface_type: 1,
|
||||
kdniao_id: '',
|
||||
kdniao_app_key: '',
|
||||
kdniao_is_pay: 1,
|
||||
kd100_app_key: '',
|
||||
kd100_customer: ''
|
||||
})
|
||||
|
||||
const setFormData = async() => {
|
||||
const data = await (await getDeliverySearch()).data
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
|
||||
loading.value = false
|
||||
}
|
||||
setFormData()
|
||||
|
||||
const openEvent = (url: any) => {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = reactive<FormRules>({})
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
const save = async(formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
setDeliverySearch(formData).then(() => {
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.input-item {
|
||||
margin-bottom: 10px !important
|
||||
}
|
||||
|
||||
.button-size {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.el-radio.el-radio--large {
|
||||
height: auto !important
|
||||
}
|
||||
</style>
|
||||
139
niucloud/addon/shop/admin/views/delivery/staff.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="box-card !border-none" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="$router.back()" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<el-form :inline="true" :model="tableData.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('deliverName')" prop="deliver_name">
|
||||
<el-input v-model.trim="tableData.searchParam.deliver_name" :placeholder="t('deliverNamePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('deliverMobile')" prop="deliver_mobile">
|
||||
<el-input v-model.trim="tableData.searchParam.deliver_mobile" :placeholder="t('deliverMobilePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getShopDeliveryFn()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="addEvent">
|
||||
{{ t('addDeliveryPersonnel') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="tableData.data" ref="tableRef" size="large" v-loading="tableData.loading">
|
||||
<template #empty>
|
||||
<span>{{ !tableData.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="deliver_name" :label="t('deliverName')" />
|
||||
<el-table-column prop="deliver_mobile" :label="t('deliverMobile')" />
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.deliver_id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="tableData.total"
|
||||
@size-change="getShopDeliveryFn()" @current-change="getShopDeliveryFn" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<delivery-personnel-edit ref="editCategoryDialog" @complete="getShopDeliveryFn(getTablePageStorage(tableData.searchParam).page)" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import deliveryPersonnelEdit from '@/addon/shop/views/delivery/components/delivery-personnel-edit.vue'
|
||||
import { getShopDelivery, deleteShopDeliver } from '@/addon/shop/api/delivery'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
const tableData = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
data: [],
|
||||
searchParam: {
|
||||
deliver_name: '',
|
||||
deliver_mobile: ''
|
||||
}
|
||||
})
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
/**
|
||||
* 获取配送员列表
|
||||
*/
|
||||
const getShopDeliveryFn = (page: number = 1) => {
|
||||
tableData.loading = true
|
||||
tableData.page = page
|
||||
|
||||
getShopDelivery({
|
||||
page: tableData.page,
|
||||
limit: tableData.limit,
|
||||
...tableData.searchParam
|
||||
}).then(res => {
|
||||
tableData.loading = false
|
||||
tableData.data = res.data.data
|
||||
tableData.total = res.data.total
|
||||
setTablePageStorage(tableData.page, tableData.limit, tableData.searchParam)
|
||||
}).catch(() => {
|
||||
tableData.loading = false
|
||||
})
|
||||
}
|
||||
getShopDeliveryFn(getTablePageStorage(tableData.searchParam).page)
|
||||
const editCategoryDialog: Record<string, any> | null = ref(null)
|
||||
|
||||
/**
|
||||
* 添加配送员
|
||||
*/
|
||||
const addEvent = () => {
|
||||
editCategoryDialog.value.setFormData()
|
||||
editCategoryDialog.value.showDialog = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑配送员
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
editCategoryDialog.value.setFormData(data)
|
||||
editCategoryDialog.value.showDialog = true
|
||||
}
|
||||
/**
|
||||
* 删除配送员
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('deliverDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteShopDeliver(id).then(() => {
|
||||
getShopDeliveryFn(getTablePageStorage(tableData.searchParam).page)
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
getShopDeliveryFn()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
164
niucloud/addon/shop/admin/views/delivery/store.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<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-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<el-form :inline="true" :model="storeTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('storeName')" prop="store_name">
|
||||
<el-input v-model.trim="storeTable.searchParam.store_name" :placeholder="t('storeNamePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadStoreList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="addEvent">
|
||||
{{ t('addStore') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="storeTable.data" size="large" v-loading="storeTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !storeTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column :label="t('storeInfo')" min-width="170" align="left">
|
||||
<template #default="{ row }">
|
||||
<div class="h-[50px] flex items-center">
|
||||
<el-image class="w-[50px] h-[50px] " :src="img(row.store_logo)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[50px] h-[50px]" src="@/addon/shop/assets/store_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<p class="ml-[10px] text-[14px]">{{ row.store_name }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_mobile" :label="t('storeMobile')" min-width="120" />
|
||||
<el-table-column prop="full_address" :label="t('fullAddress')" min-width="180" />
|
||||
<el-table-column prop="trade_time" :label="t('tradeTime')" min-width="120" />
|
||||
<el-table-column :label="t('createTime')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.create_time || '' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.store_id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="storeTable.page" v-model:page-size="storeTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="storeTable.total"
|
||||
@size-change="loadStoreList()" @current-change="loadStoreList" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getStoreList, deleteStore } from '@/addon/shop/api/delivery'
|
||||
import { img } from '@/utils/common'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
|
||||
|
||||
const route = useRoute()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const storeTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
store_name: '',
|
||||
create_time: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取自提门店列表
|
||||
*/
|
||||
const loadStoreList = (page: number = 1) => {
|
||||
storeTable.loading = true
|
||||
storeTable.page = page
|
||||
|
||||
getStoreList({
|
||||
page: storeTable.page,
|
||||
limit: storeTable.limit,
|
||||
...storeTable.searchParam
|
||||
}).then(res => {
|
||||
storeTable.loading = false
|
||||
storeTable.data = res.data.data
|
||||
storeTable.total = res.data.total
|
||||
setTablePageStorage(storeTable.page, storeTable.limit, storeTable.searchParam);
|
||||
}).catch(() => {
|
||||
storeTable.loading = false
|
||||
})
|
||||
}
|
||||
loadStoreList(getTablePageStorage(storeTable.searchParam).page);
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
/**
|
||||
* 添加自提门店
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push('/shop/order/delivery/store/edit')
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑自提门店
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push('/shop/order/delivery/store/edit?id=' + data.store_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除自提门店
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('storeDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteStore(id).then(() => {
|
||||
loadStoreList(getTablePageStorage(storeTable.searchParam).page);
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadStoreList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
531
niucloud/addon/shop/admin/views/delivery/store_edit.vue
Normal file
@ -0,0 +1,531 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none" shadow="never">
|
||||
<el-page-header :content="id ? t('updateStore') : t('addStore')" :icon="ArrowLeft" @back="back" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never" v-loading="loading">
|
||||
<el-form :model="formData" label-width="140px" ref="formRef" :rules="formRules" class="page-form">
|
||||
<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" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('storeDesc')">
|
||||
<el-input v-model.trim="formData.store_desc" type="textarea" rows="4" clearable :placeholder="t('storeDescPlaceholder')" class="input-width" maxlength="200" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('storeLogo')">
|
||||
<upload-image v-model="formData.store_logo" />
|
||||
</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" />
|
||||
</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" />
|
||||
<p class="text-[12px] text-[#999]">{{ t('tradeTimeTips') }}</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('storeDate')" 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('storeTime')" 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('addTimeRange') }}</span>
|
||||
</div>
|
||||
<div class="text-[12px] text-[#999]">{{ t('storeDateTips') }}</div>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('storeTimeInterval')" 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>
|
||||
<p class="text-[12px] text-[#999]">{{ t('storeTimeIntervalTips') }}</p>
|
||||
</div>
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('storeAddress')" prop="address_area">
|
||||
<el-select v-model="formData.province_id" value-key="id" clearable class="w-[200px]" ref="provinceRef">
|
||||
<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" clearable class="w-[200px] ml-3" ref="cityRef">
|
||||
<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" clearable class="w-[200px] ml-3" ref="districtRef">
|
||||
<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">
|
||||
<el-input v-model.trim="formData.address" clearable :placeholder="t('addressPlaceholder')" @input="areaChange()" class="input-width"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<div id="container" class="w-[800px] h-[520px] relative" v-loading="mapLoading"></div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="fixed-footer-wrap">
|
||||
<div class="fixed-footer !z-[1000]">
|
||||
<el-button type="primary" @click="onSave(formRef)">{{ 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, watch } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { getStoreInfo, addStore, editStore, getStoreInit } from '@/addon/shop/api/delivery'
|
||||
import { getMap, getAreaListByPid, getAreaByCode } from '@/app/api/sys'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { createMarker, latLngToAddress, addressToLatLng } from '@/utils/qqmap'
|
||||
import { filterNumber, debounce } from '@/utils/common'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const route = useRoute()
|
||||
const id: number = parseInt(route.query.id as string)
|
||||
const loading = ref(false)
|
||||
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()
|
||||
})
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化地图
|
||||
*/
|
||||
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)
|
||||
}
|
||||
|
||||
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.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 : 0
|
||||
storeArea.district_id = data.district ? data.district.id : 0
|
||||
})
|
||||
} else {
|
||||
console.error(message, result)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
store_id: 0,
|
||||
store_name: '',
|
||||
store_desc: '',
|
||||
store_logo: '',
|
||||
store_mobile: '',
|
||||
province_id: 0,
|
||||
province_name: '',
|
||||
city_id: 0,
|
||||
city_name: '',
|
||||
district_id: 0,
|
||||
district_name: '',
|
||||
address: '',
|
||||
full_address: '',
|
||||
longitude: 116.397190,
|
||||
latitude: 39.908626,
|
||||
trade_time: '',
|
||||
time_week: ['1', '2', '3', '4', '5', '6', '0'],
|
||||
trade_time_json: [
|
||||
{ start_time: '', end_time: '' } // 初始一个时间段
|
||||
],
|
||||
time_interval: 30
|
||||
}
|
||||
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
|
||||
// 添加时间段
|
||||
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 setFormData = async (id: number = 0) => {
|
||||
loading.value = true
|
||||
Object.assign(formData, initialFormData)
|
||||
const data = await (await getStoreInfo(id)).data
|
||||
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)
|
||||
}))
|
||||
}
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
if (id) setFormData(id)
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
store_name: [
|
||||
{ required: true, message: t('storeNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
store_logo: [
|
||||
{ required: true, message: t('storeLogoPlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
store_mobile: [
|
||||
{ required: true, message: t('storeMobilePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
trade_time: [
|
||||
{ required: true, message: t('tradeTimePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
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' }
|
||||
],
|
||||
time_week: [
|
||||
{ required: true, message: t('selectBusinessDays'), trigger: 'change' }
|
||||
],
|
||||
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' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取市
|
||||
*/
|
||||
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 areaChange = debounce(() => {
|
||||
setTimeout(() => {
|
||||
const address = [
|
||||
formData.province_id ? provinceRef.value.states.selectedLabel : '',
|
||||
formData.city_id ? cityRef.value.states.selectedLabel : '',
|
||||
formData.district_id ? districtRef.value.states.selectedLabel : '',
|
||||
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
|
||||
} 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 onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
await formEl.validate(async(valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
|
||||
const data = cloneDeep(formData)
|
||||
formData.province_name = formData.province_id ? provinceRef.value.states.selectedLabel : ''
|
||||
formData.city_name = formData.city_id ? cityRef.value.states.selectedLabel : ''
|
||||
formData.district_name = formData.district_id ? districtRef.value.states.selectedLabel : ''
|
||||
const address = [
|
||||
data.province_id ? provinceRef.value.states.selectedLabel : '',
|
||||
data.city_id ? cityRef.value.states.selectedLabel : '',
|
||||
data.district_id ? districtRef.value.states.selectedLabel : '',
|
||||
data.address
|
||||
]
|
||||
data.full_address = address.join('')
|
||||
|
||||
// **转换时间段为时间戳**
|
||||
data.trade_time_json = formData.trade_time_json.map(range => ({
|
||||
start_time: range.start_time ? timeTransition(range.start_time) : null,
|
||||
end_time: range.end_time ? timeTransition(range.end_time) : null
|
||||
}))
|
||||
|
||||
const save = id ? editStore : addStore
|
||||
|
||||
save(data).then(res => {
|
||||
loading.value = false
|
||||
history.back()
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
history.back()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
144
niucloud/addon/shop/admin/views/delivery/template.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<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-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-card class="box-card !border-none my-[10px] pt-0 table-search-wrap" shadow="never">
|
||||
<div class="flex justify-between items-center">
|
||||
<el-form :inline="true" :model="templateTable.searchParam" ref="searchFormRef">
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model.trim="templateTable.searchParam.template_name" :placeholder="t('templateNamePlaceholder')" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadTemplateList()">{{ t('search') }}</el-button>
|
||||
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="addEvent">
|
||||
{{ t('addTemplate') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<div class="mt-[10px]">
|
||||
<el-table :data="templateTable.data" size="large" v-loading="templateTable.loading">
|
||||
<template #empty>
|
||||
<span>{{ !templateTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column prop="template_name" :label="t('templateName')" min-width="120" />
|
||||
<el-table-column prop="fee_type_name" :label="t('feeTypeName')" min-width="120" />
|
||||
<el-table-column :label="t('freeShipping')" min-width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ row.is_free_shipping ? t('open') : t('close') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="create_time" :label="t('createTime')" 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="editEvent(row)">{{ t('edit') }}</el-button>
|
||||
<el-button type="primary" link @click="deleteEvent(row.template_id)">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[16px] flex justify-end">
|
||||
<el-pagination v-model:current-page="templateTable.page" v-model:page-size="templateTable.limit"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="templateTable.total"
|
||||
@size-change="loadTemplateList()" @current-change="loadTemplateList" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { getShippingTemplatePageList, deleteShippingTemplate } from '@/addon/shop/api/delivery'
|
||||
import { ElMessageBox, FormInstance } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const pageName = route.meta.title
|
||||
|
||||
const templateTable = reactive({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
template_name: ''
|
||||
}
|
||||
})
|
||||
|
||||
const searchFormRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 获取运费模板列表
|
||||
*/
|
||||
const loadTemplateList = (page: number = 1) => {
|
||||
templateTable.loading = true
|
||||
templateTable.page = page
|
||||
|
||||
getShippingTemplatePageList({
|
||||
page: templateTable.page,
|
||||
limit: templateTable.limit,
|
||||
...templateTable.searchParam
|
||||
}).then(res => {
|
||||
templateTable.loading = false
|
||||
templateTable.data = res.data.data
|
||||
templateTable.total = res.data.total
|
||||
setTablePageStorage(templateTable.page, templateTable.limit, templateTable.searchParam);
|
||||
}).catch(() => {
|
||||
templateTable.loading = false
|
||||
})
|
||||
}
|
||||
loadTemplateList(getTablePageStorage(templateTable.searchParam).page);
|
||||
|
||||
/**
|
||||
* 添加运费模板
|
||||
*/
|
||||
const addEvent = () => {
|
||||
router.push({ path: '/shop/order/shipping/template_edit' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑运费模板
|
||||
* @param data
|
||||
*/
|
||||
const editEvent = (data: any) => {
|
||||
router.push({ path: '/shop/order/shipping/template_edit', query: { id: data.template_id } })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除运费模板
|
||||
*/
|
||||
const deleteEvent = (id: number) => {
|
||||
ElMessageBox.confirm(t('templateDeleteTips'), t('warning'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteShippingTemplate(id).then(() => {
|
||||
loadTemplateList(getTablePageStorage(templateTable.searchParam).page);
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
loadTemplateList()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
505
niucloud/addon/shop/admin/views/delivery/template_edit.vue
Normal file
@ -0,0 +1,505 @@
|
||||
<template>
|
||||
<div class="main-container">
|
||||
<el-card class="card !border-none" shadow="never">
|
||||
<el-page-header :content="pageName" :icon="ArrowLeft" @back="back" />
|
||||
</el-card>
|
||||
|
||||
<el-card class="box-card mt-[15px] !border-none" shadow="never">
|
||||
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
|
||||
<el-form-item :label="t('templateName')" prop="template_name">
|
||||
<el-input v-model.trim="formData.template_name" clearable :placeholder="t('templateNamePlaceholder')" class="input-width" maxlength="60" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('feeTypeName')" prop="fee_type">
|
||||
<el-radio-group v-model="formData.fee_type">
|
||||
<el-radio label="num" size="large">{{ t('num') }}</el-radio>
|
||||
<el-radio label="weight" size="large">{{ t('weight') }}</el-radio>
|
||||
<el-radio label="volume" size="large">{{ t('volume') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('feeSetting')" prop="fee_data">
|
||||
<el-table :data="feeData" style="width: 100%" size="default">
|
||||
<el-table-column :label="t('deliveryArea')">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="area-input">
|
||||
<span v-if="$index" @click="selectArea('fee', $index)" class="cursor-pointer">{{ row.fee_area_names ? row.fee_area_names : t('areaPlaceholder') }}</span>
|
||||
<span v-else>{{ row.fee_area_names ? row.fee_area_names : t('areaPlaceholder') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="feeLabel.first">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="feeData[$index].snum" maxlength="8" @keyup="filterDigit($event)" @blur="feeData[$index].snum = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('fee')">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="feeData[$index].sprice" maxlength="8" @keyup="filterDigit($event)" @blur="feeData[$index].sprice = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="feeLabel.continue">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="feeData[$index].xnum" maxlength="8" @keyup="filterDigit($event)" @blur="feeData[$index].xnum = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('continueFee')">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="feeData[$index].xprice" @keyup="filterDigit($event)" maxlength="8" @blur="feeData[$index].xprice = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" width="150">
|
||||
<template #default="{ $index }">
|
||||
<el-button type="primary" @click="delArea('fee', $index)" link v-if="$index">{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[10px]">
|
||||
<el-button type="primary" @click="addArea('fee')">{{ t('addDeliveryArea') }}</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- 指定区域包邮 -->
|
||||
<el-form-item :label="t('freeShipping')" prop="is_free_shipping">
|
||||
<el-switch v-model="formData.is_free_shipping" size="small" :inactive-value="0" :active-value="1" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="formData.is_free_shipping" prop="free_shipping_data">
|
||||
<el-table :data="freeShippingData" style="width: 100%" size="default">
|
||||
<el-table-column :label="t('freeShippingArea')">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="area-input">
|
||||
<el-input v-model.trim="row.free_shipping_area_names" :placeholder="t('areaPlaceholder')" readonly @click="selectArea('free_shipping', $index)" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="freeShippingLabel">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="freeShippingData[$index].free_shipping_num" @keyup="filterDigit($event)" maxlength="8" @blur="freeShippingData[$index].free_shipping_num = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('freeShippingPrice')">
|
||||
<template #default="{ $index }">
|
||||
<el-input v-model.trim="freeShippingData[$index].free_shipping_price" @keyup="filterDigit($event)" maxlength="8" @blur="freeShippingData[$index].free_shipping_price = $event.target.value"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" width="150">
|
||||
<template #default="{ $index }">
|
||||
<el-button type="primary" @click="delArea('free_shipping', $index)" link>{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="form-tip">{{ t('freeShippingAreaTips') }}</div>
|
||||
<div class="mt-[10px]">
|
||||
<el-button type="primary" @click="addArea('free_shipping')">{{ t('addFreeShippingArea') }}</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- 指定区域不配送 -->
|
||||
<el-form-item :label="t('noDelivery')" prop="no_delivery">
|
||||
<el-switch v-model="formData.no_delivery" size="small" :inactive-value="0" :active-value="1" />
|
||||
</el-form-item>
|
||||
<el-form-item v-show="formData.no_delivery" prop="no_delivery_data">
|
||||
<el-table :data="noDeliveryData" style="width: 100%" size="default">
|
||||
<el-table-column :label="t('noDelivery')">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="area-input">
|
||||
<el-input v-model.trim="row.no_delivery_area_names" readonly @click="selectArea('no_delivery', $index)" :placeholder="t('areaPlaceholder')" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('operation')" align="right" width="150">
|
||||
<template #default="{ $index }">
|
||||
<el-button type="primary" @click="delArea('no_delivery', $index)" link>{{ t('delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt-[10px]">
|
||||
<el-button type="primary" @click="addArea('no_delivery')">{{ t('addNoDelivery') }}</el-button>
|
||||
</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>
|
||||
|
||||
<!-- 选择地区弹窗 -->
|
||||
<el-dialog v-model="showSelectAreaDialog" :title="t('selectArea')" width="80%" class="diy-dialog-wrap" :destroy-on-close="true" @opened="showSelectOpened">
|
||||
|
||||
<el-scrollbar height="50vh">
|
||||
<el-tree :data="areaTreeData" :props="{ children: 'child', label: 'name' }" default-expand-all show-checkbox ref="areaTreeRef" :default-checked-keys="selectedArea" node-key="id" />
|
||||
</el-scrollbar>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showSelectAreaDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="confirmSelectArea">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { t } from '@/lang'
|
||||
import { ElTree, FormInstance, ElMessage } from 'element-plus'
|
||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||
import { addShippingTemplate, editShippingTemplate, getShippingTemplateInfo } from '@/addon/shop/api/delivery'
|
||||
import { AnyObject } from '@/types/global'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { getAreatree } from '@/app/api/sys'
|
||||
import { filterDigit } from '@/utils/common'
|
||||
import Test from '@/utils/test'
|
||||
|
||||
const showSelectAreaDialog = ref(false)
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
template_id: '',
|
||||
template_name: '',
|
||||
fee_type: 'num',
|
||||
area: [],
|
||||
no_delivery: 0,
|
||||
is_free_shipping: 0,
|
||||
fee_data: [],
|
||||
free_shipping_data: [],
|
||||
no_delivery_data: []
|
||||
}
|
||||
const pageName = route.meta.title
|
||||
const formData: Record<string, any> = reactive({ ...initialFormData })
|
||||
const formRef = ref<FormInstance>()
|
||||
const areaTree = ref<AnyObject[]>([])
|
||||
|
||||
if (route.query.id) {
|
||||
loading.value = true
|
||||
getShippingTemplateInfo(route.query.id).then(({ data }) => {
|
||||
if (data) {
|
||||
Object.keys(formData).forEach((key: string) => {
|
||||
if (data[key] != undefined) formData[key] = data[key]
|
||||
})
|
||||
feeData.value = data.fee_data
|
||||
noDeliveryData.value = data.no_delivery_data
|
||||
freeShippingData.value = data.free_shipping_data
|
||||
}
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
getAreatree(2).then(res => {
|
||||
areaTree.value = res.data
|
||||
}).catch()
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = computed(() => {
|
||||
return {
|
||||
template_name: [
|
||||
{ required: true, message: t('templateNamePlaceholder'), trigger: 'blur' }
|
||||
],
|
||||
fee_data: [{ validator: feeDataValidate }],
|
||||
free_shipping_data: [{ validator: freeShippingDataValidate }],
|
||||
no_delivery_data: [{ validator: noDeliveryDataValidate }]
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 运费模板运费数据校验
|
||||
*/
|
||||
const feeDataValidate = (rule: any, value: any, callback: any) => {
|
||||
for (let i = 0; i < feeData.value.length; i++) {
|
||||
const item = feeData.value[i]
|
||||
if (!item.area_ids.length) {
|
||||
callback(new Error(t('areaPlaceholder')))
|
||||
break
|
||||
}
|
||||
if (Test.empty(item.snum) || item.snum < 0) {
|
||||
callback(new Error(feeLabel.value.first + t('notUnderZero')))
|
||||
break
|
||||
}
|
||||
if (Test.empty(item.xnum) || item.snum < 0) {
|
||||
callback(new Error(feeLabel.value.continue + t('notUnderZero')))
|
||||
break
|
||||
}
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
/**
|
||||
* 运费模板包邮数据校验
|
||||
*/
|
||||
const freeShippingDataValidate = (rule: any, value: any, callback: any) => {
|
||||
if (formData.is_free_shipping) {
|
||||
for (let i = 0; i < freeShippingData.value.length; i++) {
|
||||
const item = freeShippingData.value[i]
|
||||
if (!item.area_ids.length) {
|
||||
callback(new Error(t('freeShippingPlaceholder')))
|
||||
break
|
||||
}
|
||||
if (Test.empty(item.free_shipping_num) || item.free_shipping_num < 0) {
|
||||
callback(new Error(freeShippingLabel.value + t('notUnderZero')))
|
||||
break
|
||||
}
|
||||
}
|
||||
callback()
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 运费模板不配送地区校验
|
||||
*/
|
||||
const noDeliveryDataValidate = (rule: any, value: any, callback: any) => {
|
||||
if (formData.no_delivery) {
|
||||
for (let i = 0; i < noDeliveryData.value.length; i++) {
|
||||
const item = noDeliveryData.value[i]
|
||||
if (!item.area_ids.length) {
|
||||
callback(new Error(t('noDeliveryPlaceholder')))
|
||||
break
|
||||
}
|
||||
}
|
||||
callback()
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const feeLabel = computed(() => {
|
||||
const label: AnyObject = {
|
||||
num: {
|
||||
first: t('firstNum'),
|
||||
continue: t('continueNum')
|
||||
},
|
||||
weight: {
|
||||
first: t('firstWeight'),
|
||||
continue: t('continueWeight')
|
||||
},
|
||||
volume: {
|
||||
first: t('firstVolume'),
|
||||
continue: t('continueVolume')
|
||||
}
|
||||
}
|
||||
return label[formData.fee_type]
|
||||
})
|
||||
|
||||
const freeShippingLabel = computed(() => {
|
||||
const label: AnyObject = {
|
||||
num: t('freeShippingNum'),
|
||||
weight: t('freeShippingWeight'),
|
||||
volume: t('freeShippingVolume')
|
||||
}
|
||||
return label[formData.fee_type]
|
||||
})
|
||||
|
||||
// 运费数据
|
||||
const feeData = ref<AnyObject[]>([
|
||||
{ area_ids: [0], fee_area_names: '全国', snum: 1, sprice: 0, xnum: 1, xprice: 0 }
|
||||
])
|
||||
// 包邮区域数据
|
||||
const freeShippingData = ref<AnyObject[]>([])
|
||||
// 不配送区域
|
||||
const noDeliveryData = ref<AnyObject[]>([])
|
||||
|
||||
/**
|
||||
* 添加地区
|
||||
* @param type
|
||||
*/
|
||||
const addArea = (type: string) => {
|
||||
switch (type) {
|
||||
case 'fee':
|
||||
feeData.value.push({ area_ids: [], fee_area_names: '', snum: 1, sprice: 0, xnum: 1, xprice: 0 })
|
||||
break
|
||||
case 'free_shipping':
|
||||
freeShippingData.value.push({ area_ids: [], free_shipping_area_names: '', free_shipping_num: 0, free_shipping_price: 0 })
|
||||
break
|
||||
case 'no_delivery':
|
||||
noDeliveryData.value.push({ area_ids: [], no_delivery_area_names: '' })
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*删除地区
|
||||
* @param type
|
||||
* @param index
|
||||
*/
|
||||
const delArea = (type: string, index: number) => {
|
||||
switch (type) {
|
||||
case 'fee':
|
||||
feeData.value.splice(index, 1)
|
||||
break
|
||||
case 'free_shipping':
|
||||
freeShippingData.value.splice(index, 1)
|
||||
break
|
||||
case 'no_delivery':
|
||||
noDeliveryData.value.splice(index, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 选中的区域
|
||||
let selectedArea: number[] = []
|
||||
// 禁止选择的区域
|
||||
const disabledArea = ref <Array<string|number>>([])
|
||||
|
||||
let currSelect = { type: '', index: 0 }
|
||||
|
||||
const selectArea = (type: string, index: number) => {
|
||||
currSelect = { type, index }
|
||||
|
||||
let data: AnyObject[] = []
|
||||
switch (type) {
|
||||
case 'fee':
|
||||
data = feeData.value
|
||||
break
|
||||
case 'free_shipping':
|
||||
data = freeShippingData.value
|
||||
break
|
||||
case 'no_delivery':
|
||||
data = noDeliveryData.value
|
||||
break
|
||||
}
|
||||
selectedArea = data[index].area_ids
|
||||
disabledArea.value = []
|
||||
data.forEach((item, $index) => {
|
||||
if (index != $index) disabledArea.value.push(...item.area_ids)
|
||||
})
|
||||
showSelectAreaDialog.value = true
|
||||
}
|
||||
|
||||
const areaTreeData = computed(() => {
|
||||
areaTree.value.forEach(province => {
|
||||
// 确保 province 存在且有 child 数组,避免 undefined.child 报错
|
||||
if (province && Array.isArray(province.child)) {
|
||||
province.child.forEach((city: any) => {
|
||||
city.disabled = disabledArea.value?.includes(city.id) || false;
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
return areaTree.value
|
||||
})
|
||||
|
||||
const areaTreeRef = ref<InstanceType<typeof ElTree>>()
|
||||
const confirmSelectArea = () => {
|
||||
const nodes = areaTreeRef.value!.getCheckedNodes(false, false)
|
||||
const areaIds: number[] = []
|
||||
const areaNames: string[] = []
|
||||
|
||||
nodes.forEach(item => {
|
||||
if (item.level == 2) {
|
||||
areaIds.push(item.id)
|
||||
areaNames.push(item.name)
|
||||
}
|
||||
})
|
||||
|
||||
switch (currSelect.type) {
|
||||
case 'fee':
|
||||
feeData.value[currSelect.index].area_ids = areaIds
|
||||
feeData.value[currSelect.index].fee_area_names = areaNames.toString()
|
||||
break
|
||||
case 'free_shipping':
|
||||
freeShippingData.value[currSelect.index].area_ids = areaIds
|
||||
freeShippingData.value[currSelect.index].free_shipping_area_names = areaNames.toString()
|
||||
break
|
||||
case 'no_delivery':
|
||||
noDeliveryData.value[currSelect.index].area_ids = areaIds
|
||||
noDeliveryData.value[currSelect.index].no_delivery_area_names = areaNames.toString()
|
||||
break
|
||||
}
|
||||
showSelectAreaDialog.value = false
|
||||
}
|
||||
|
||||
const showSelectOpened = () => {
|
||||
areaTreeRef.value!.setCheckedKeys(selectedArea, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认
|
||||
* @param formEl
|
||||
*/
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (loading.value || !formEl) return
|
||||
const save = formData.template_id ? editShippingTemplate : addShippingTemplate
|
||||
|
||||
await formEl.validate(async (valid) => {
|
||||
if (valid) {
|
||||
if (formData.is_free_shipping && freeShippingData.value.length == 0) {
|
||||
ElMessage.error(t('freeShippingPlaceholder'))
|
||||
return
|
||||
}
|
||||
if (formData.no_delivery && noDeliveryData.value.length == 0) {
|
||||
ElMessage.error('noDeliveryPlaceholder')
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
|
||||
const data:AnyObject = {
|
||||
template_id: formData.template_id,
|
||||
template_name: formData.template_name,
|
||||
fee_type: formData.fee_type,
|
||||
no_delivery: formData.no_delivery,
|
||||
is_free_shipping: formData.is_free_shipping
|
||||
}
|
||||
const area: AnyObject = {}
|
||||
|
||||
feeData.value.forEach(item => {
|
||||
item.area_ids.forEach((city: number) => {
|
||||
area['city_' + city] = { city_id: city, fee_area_ids: item.area_ids.toString(), fee_area_names: item.fee_area_names, snum: item.snum, sprice: item.sprice, xnum: item.xnum, xprice: item.xprice }
|
||||
})
|
||||
})
|
||||
freeShippingData.value.forEach(item => {
|
||||
item.area_ids.forEach((city: number) => {
|
||||
if (area['city_' + city]) {
|
||||
Object.assign(area['city_' + city], { free_shipping_area_ids: item.area_ids.toString(), free_shipping_area_names: item.free_shipping_area_names, free_shipping_num: item.free_shipping_num, free_shipping_price: item.free_shipping_price })
|
||||
} else {
|
||||
area['city_' + city] = { city_id: city, free_shipping_area_ids: item.area_ids.toString(), free_shipping_area_names: item.free_shipping_area_names, free_shipping_num: item.free_shipping_num, free_shipping_price: item.free_shipping_price }
|
||||
}
|
||||
})
|
||||
})
|
||||
noDeliveryData.value.forEach(item => {
|
||||
item.area_ids.forEach((city: number) => {
|
||||
if (area['city_' + city]) {
|
||||
Object.assign(area['city_' + city], { no_delivery_area_ids: item.area_ids.toString(), no_delivery_area_names: item.no_delivery_area_names })
|
||||
} else {
|
||||
area['city_' + city] = { city_id: city, no_delivery_area_ids: item.area_ids.toString(), no_delivery_area_names: item.no_delivery_area_names }
|
||||
}
|
||||
})
|
||||
})
|
||||
data.area = Object.values(area)
|
||||
save(data).then(() => {
|
||||
loading.value = false
|
||||
router.push({ path: '/shop/order/shipping/template' })
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
router.push({ path: '/shop/order/shipping/template' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tree-node.is-expanded>.el-tree-node__children) {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
:deep(.area-input .el-input__wrapper) {
|
||||
box-shadow: none !important;
|
||||
padding: 0 !important;
|
||||
background: none;
|
||||
|
||||
input {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('selectStyle')" class="flex">
|
||||
<span class="text-primary flex-1 cursor-pointer"
|
||||
@click="showCouponStyle">{{ diyStore.editComponent.styleName }}</span>
|
||||
<el-icon @click="showCouponStyle" class="cursor-pointer">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-dialog v-model="showCouponDialog" :title="t('selectStyle')" width="500px">
|
||||
<div class="flex flex-wrap">
|
||||
<template v-for="(item,index) in couponStyleList" :key="index">
|
||||
<div :class="{ 'border-primary': selectCouponStyle.value == item.value }"
|
||||
@click="changeCouponStyle(item)"
|
||||
class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] m-[6px] cursor-pointer border bg-gray-50">
|
||||
<img :src="img(item.url)" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showCouponDialog = false">{{ t('cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirmCouponStyle">{{ t('confirm') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('couponContent') }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
|
||||
<el-form-item :label="t('couponTitle')">
|
||||
<el-input v-model.trim="diyStore.editComponent.couponTitle" clearable :maxlength="diyStore.editComponent.style == 'style-3' ? 4 : 8" show-word-limit />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('couponSubTitle')">
|
||||
<el-input v-model.trim="diyStore.editComponent.couponSubTitle" clearable :maxlength="diyStore.editComponent.style == 'style-3' ? 7 : 10" show-word-limit />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('couponData') }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
|
||||
<el-form-item :label="t('selectCoupon')">
|
||||
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio label="all">{{ t('allSources') }}</el-radio>
|
||||
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('manualSelectionSources')" v-if="diyStore.editComponent.source == 'custom'">
|
||||
<coupon-select-popup ref="couponSelectPopupRef" v-model="diyStore.editComponent.couponIds" :min="1" :max="20" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('couponNum')" v-if="diyStore.editComponent.source == 'all'">
|
||||
<el-slider show-input v-model="diyStore.editComponent.num" :min="1" max="20" size="small"
|
||||
class="goods-coupon-slider" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('couponBtnText')" v-if="diyStore.editComponent.style != 'style-4'">
|
||||
<el-input v-model.trim="diyStore.editComponent.btnText" clearable maxlength="5" show-word-limit />
|
||||
</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.style == 'style-4'">
|
||||
<h3 class="mb-[10px]">{{ t("couponTitleStyle") }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
<el-form-item :label="t('couponTitleColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.titleColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('couponSubTitleColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.subTitleColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.editComponent.style == 'style-4'">
|
||||
<h3 class="mb-[10px]">{{ t("couponItemStyle") }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
<el-form-item :label="t('couponMoney')">
|
||||
<el-color-picker v-model="diyStore.editComponent.couponItem.moneyColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('textColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.couponItem.textColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('subTextColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.couponItem.subTextColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('listFrameColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.couponItem.bgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.couponItem.aroundRadius" 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 { img } from '@/utils/common'
|
||||
import { ref, reactive } from 'vue'
|
||||
import couponSelectPopup from '@/addon/shop/views/goods/components/coupon-select-popup.vue'
|
||||
|
||||
const diyStore = useDiyStore()
|
||||
diyStore.editComponent.ignore = ['componentBgColor', 'componentBgUrl'] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
|
||||
if (diyStore.value[index].source == 'custom') {
|
||||
if (diyStore.value[index].couponIds.length == 0) {
|
||||
res.code = false
|
||||
res.message = t('couponPlaceholder')
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
if (diyStore.value[index].btnText == '') {
|
||||
res.code = false
|
||||
res.message = t('couponBtnTextPlaceholder')
|
||||
return res
|
||||
}
|
||||
|
||||
if (diyStore.value[index].couponTitle == '') {
|
||||
res.code = false
|
||||
res.message = t('couponTitlePlaceholder')
|
||||
return res
|
||||
}
|
||||
|
||||
if (diyStore.value[index].couponSubTitle == '') {
|
||||
res.code = false
|
||||
res.message = t('couponSubTitlePlaceholder')
|
||||
return res
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
const selectCouponStyle = reactive({
|
||||
title: diyStore.editComponent.styleName,
|
||||
value: diyStore.editComponent.style
|
||||
})
|
||||
|
||||
// 风格样式
|
||||
const showCouponDialog = ref(false)
|
||||
|
||||
const showCouponStyle = () => {
|
||||
showCouponDialog.value = true
|
||||
selectCouponStyle.title = diyStore.editComponent.styleName
|
||||
selectCouponStyle.value = diyStore.editComponent.style
|
||||
}
|
||||
|
||||
const couponStyleList = reactive([
|
||||
{
|
||||
url: 'addon/shop/diy/goods_coupon/style-1.png',
|
||||
title: '风格1',
|
||||
value: 'style-1'
|
||||
},
|
||||
{
|
||||
url: 'addon/shop/diy/goods_coupon/style-2.png',
|
||||
title: '风格2',
|
||||
value: 'style-2'
|
||||
},
|
||||
{
|
||||
url: 'addon/shop/diy/goods_coupon/style-3.png',
|
||||
title: '风格3',
|
||||
value: 'style-3'
|
||||
},
|
||||
{
|
||||
url: 'addon/shop/diy/goods_coupon/style-4.png',
|
||||
title: '风格4',
|
||||
value: 'style-4'
|
||||
}
|
||||
])
|
||||
|
||||
const changeCouponStyle = (item: any) => {
|
||||
selectCouponStyle.title = item.title
|
||||
selectCouponStyle.value = item.value
|
||||
}
|
||||
|
||||
const confirmCouponStyle = () => {
|
||||
diyStore.editComponent.styleName = selectCouponStyle.title
|
||||
diyStore.editComponent.style = selectCouponStyle.value
|
||||
if (diyStore.editComponent.style == 'style-3') {
|
||||
if (diyStore.editComponent.couponTitle && diyStore.editComponent.couponTitle.length > 4) {
|
||||
diyStore.editComponent.couponTitle = diyStore.editComponent.couponTitle.substring(0, 4)
|
||||
}
|
||||
if (diyStore.editComponent.couponSubTitle && diyStore.editComponent.couponSubTitle.length > 7) {
|
||||
diyStore.editComponent.couponSubTitle = diyStore.editComponent.couponSubTitle.substring(0, 7)
|
||||
}
|
||||
}
|
||||
initStyleFn()
|
||||
showCouponDialog.value = false
|
||||
}
|
||||
|
||||
const initStyleFn = () => {
|
||||
const index = diyStore.editComponent.ignore.indexOf('componentBgColor')
|
||||
if (diyStore.editComponent.style == 'style-4' && index != -1) {
|
||||
diyStore.editComponent.ignore.splice(index, 1)
|
||||
diyStore.editComponent.titleColor = '#ffffff'
|
||||
diyStore.editComponent.subTitleColor = '#ffffff'
|
||||
|
||||
diyStore.editComponent.couponItem.moneyColor = '#fa191d'
|
||||
diyStore.editComponent.couponItem.textColor = '#333333'
|
||||
diyStore.editComponent.couponItem.subTextColor = '#999999'
|
||||
diyStore.editComponent.couponItem.bgColor = '#ffffff'
|
||||
diyStore.editComponent.couponItem.aroundRadius = 10
|
||||
diyStore.editComponent.componentStartBgColor = '#fa191d'
|
||||
} else if (diyStore.editComponent.style != 'style-4' && index == -1) {
|
||||
diyStore.editComponent.ignore.push('componentBgColor')
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.goods-coupon-slider {
|
||||
.el-slider__input {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,370 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
||||
<div class="flex items-center mb-[18px] rounded overflow-hidden">
|
||||
<span
|
||||
class="iconfont iconzuoyoutuwenpc border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-1' }"
|
||||
@click="styleChangeFn('style-1')"></span>
|
||||
|
||||
<span
|
||||
class="iconfont iconshangxiatuwenpc border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-2' }"
|
||||
@click="styleChangeFn('style-2')"></span>
|
||||
<span
|
||||
class="iconfont iconliebiaopc border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-3' }"
|
||||
@click="styleChangeFn('style-3')"></span>
|
||||
</div>
|
||||
</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('sortWay')">
|
||||
<el-radio-group v-model="diyStore.editComponent.sortWay">
|
||||
<el-radio label="default">{{ t('default') }}</el-radio>
|
||||
<el-radio label="sale_num">{{ t('sales') }}</el-radio>
|
||||
<el-radio label="price">{{ t('price') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio label="all">{{ t('goodsSelectPopupAllGoods') }}</el-radio>
|
||||
<el-radio label="category">{{ t('selectCategory') }}</el-radio>
|
||||
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('selectCategory')" v-if="diyStore.editComponent.source == 'category'">
|
||||
<div class="flex items-center w-full">
|
||||
<div class="cursor-pointer ml-auto" @click="categoryShowDialogOpen">
|
||||
<span class="text-[var(--el-color-primary)]">{{ diyStore.editComponent.goods_category_name }}</span>
|
||||
<span class="iconfont iconxiangyoujiantou"></span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNum')" v-if="diyStore.editComponent.source == 'all' || diyStore.editComponent.source == 'category'">
|
||||
<el-slider class="goods-list-slider" show-input v-model="diyStore.editComponent.num" :min="1" max="20" size="small" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('customGoods')" v-if="diyStore.editComponent.source == 'custom'">
|
||||
<goods-select-popup ref="goodsSelectPopupRef" v-model="diyStore.editComponent.goods_ids" :min="1" :max="99" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-dialog v-model="categoryShowDialog" :title="t('goodsCategoryTitle')" width="750px" :destroy-on-close="true" :close-on-click-modal="false">
|
||||
<el-table :data="categoryTable.data" ref="categoryTableRef" size="large"
|
||||
v-loading="categoryTable.loading"
|
||||
height="450px" @selection-change="handleSelectionChange" row-key="category_id"
|
||||
:expand-row-keys="expand_category_ids"
|
||||
:tree-props="{ hasChildren: 'hasChildren', children: 'child_list' }">
|
||||
<template #empty>
|
||||
<span>{{ !categoryTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column :label="t('categoryName')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span class="order-2">{{ row.category_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('categoryImage')" width="170" align="left">
|
||||
<template #default="{ row }">
|
||||
<div class="h-[30px]">
|
||||
<el-image class="w-[30px] h-[30px] " :src="img(row.image)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex items-center justify-end mt-[15px]">
|
||||
<el-button type="primary" @click="saveCategoryId">{{ t('confirm') }}</el-button>
|
||||
<el-button @click="categoryShowDialog = false">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t("goodsBuyBtn") }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsBtnIsShow')">
|
||||
<el-switch v-model="diyStore.editComponent.btnStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsCartIncident')" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<el-radio-group v-model="diyStore.editComponent.btnStyle.cartEvent">
|
||||
<el-radio label="detail">{{ t('goodsDetail') }}</el-radio>
|
||||
<el-radio v-if="diyStore.editComponent.style != 'style-3'" label="cart">{{ t('goodsAddCart') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsBtnStyle')" class="!items-center" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<div class="flex">
|
||||
<template v-for="(item,index) in btnStyleList">
|
||||
<div v-if=" item.isShow == true"
|
||||
class="cursor-pointer flex items-center justify-center border-[1px] border-solid border-transparent rounded-[6px] py-[5px] px-[8px] mr-[10px]"
|
||||
:class="{'!border-[var(--el-color-primary)]': diyStore.editComponent.btnStyle.style == item.value}">
|
||||
<div v-if="item.type == 'icon'"
|
||||
:class="['nc-iconfont !text-[25px] text-[var(--el-color-primary)]', item.title]" @click="changeBtnStyle(item)"></div>
|
||||
<div v-if="item.type == 'button'"
|
||||
class="leading-[1] text-[12px] px-[10px] py-[8px] text-[#fff] rounded-[20px] bg-[var(--el-color-primary)]"
|
||||
@click="changeBtnStyle(item)">{{ item.title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsBtnText')"
|
||||
v-if="diyStore.editComponent.btnStyle.control && diyStore.editComponent.btnStyle.style == 'button'">
|
||||
<el-input v-model.trim="diyStore.editComponent.btnStyle.text"
|
||||
:placeholder="t('goodsBtnTextPlaceholder')" clearable maxlength="4" show-word-limit />
|
||||
</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]">
|
||||
<el-form-item :label="t('goodsSelectPopupGoodsName')" v-if="diyStore.editComponent.goodsNameStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.goodsNameStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsPriceColor')" v-if="diyStore.editComponent.priceStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.priceStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSaleNum')" v-if="diyStore.editComponent.saleStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.saleStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsLabel')" v-if="diyStore.editComponent.labelStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.labelStyle.control" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('goodsStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsBgColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.elementBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNameColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsNameStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
<div class="mr-[20px]"></div>
|
||||
<el-radio-group v-model="diyStore.editComponent.goodsNameStyle.fontWeight">
|
||||
<el-radio :label="'normal'">{{ t('fontWeightNormal') }}</el-radio>
|
||||
<el-radio :label="'bold'">{{ t('fontWeightBold') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('imageRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.imgElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsPriceColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.priceStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSaleColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.saleStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.topElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bottomRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.bottomElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<h3 class="mb-[10px]">{{ t("goodsBuyBtn") }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsIsBold')" v-if="diyStore.editComponent.btnStyle.style == 'button'">
|
||||
<el-switch v-model="diyStore.editComponent.btnStyle.fontWeight" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsTextColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.btnStyle.textColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('listFrameColor')">
|
||||
<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('goodsRounded')" v-if="diyStore.editComponent.btnStyle.style == 'button'">
|
||||
<el-slider v-model="diyStore.editComponent.btnStyle.aroundRadius" 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 { getCategoryTree } from '@/addon/shop/api/goods'
|
||||
import { t } from '@/lang'
|
||||
import { img } from '@/utils/common'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { ElTable } from 'element-plus'
|
||||
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].source == 'category') {
|
||||
if (diyStore.value[index].goods_category == '') {
|
||||
res.code = false
|
||||
res.message = t('goodsCategoryPlaceholder')
|
||||
}
|
||||
} else if (diyStore.value[index].source == 'custom') {
|
||||
if (diyStore.value[index].goods_ids.length == 0) {
|
||||
res.code = false
|
||||
res.message = t('goodsPlaceholder')
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const categoryShowDialog = ref(false)
|
||||
|
||||
const categoryTable = reactive({
|
||||
loading: true,
|
||||
data: []
|
||||
})
|
||||
onMounted(() => {
|
||||
loadCategoryList()
|
||||
btnStyleList.forEach((item, index, arr) => {
|
||||
if (item.type == 'button') {
|
||||
if (diyStore.editComponent.style == 'style-3') {
|
||||
item.isShow = false
|
||||
} else {
|
||||
item.isShow = true
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const styleChangeFn = (style) => {
|
||||
btnStyleList.forEach((item, index, arr) => {
|
||||
if (item.type == 'button') {
|
||||
if (style == 'style-3') {
|
||||
item.isShow = false
|
||||
} else {
|
||||
item.isShow = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (style == 'style-3') {
|
||||
diyStore.editComponent.btnStyle.style = btnStyleList[1].value
|
||||
diyStore.editComponent.btnStyle.cartEvent = 'detail'
|
||||
|
||||
diyStore.editComponent.saleStyle.isShow = false
|
||||
diyStore.editComponent.labelStyle.isShow = false
|
||||
} else {
|
||||
diyStore.editComponent.btnStyle.style = btnStyleList[0].value
|
||||
|
||||
diyStore.editComponent.saleStyle.isShow = true
|
||||
diyStore.editComponent.labelStyle.isShow = true
|
||||
}
|
||||
diyStore.editComponent.style = style
|
||||
}
|
||||
|
||||
const btnStyleList = reactive([
|
||||
{
|
||||
isShow: true,
|
||||
type: 'button',
|
||||
title: diyStore.editComponent.btnStyle.text,
|
||||
value: 'button'
|
||||
},
|
||||
{
|
||||
isShow: true,
|
||||
type: 'icon',
|
||||
title: 'nc-icon-jiahaoV6xx',
|
||||
value: 'nc-icon-jiahaoV6xx'
|
||||
},
|
||||
{
|
||||
isShow: true,
|
||||
type: 'icon',
|
||||
title: 'nc-icon-gouwuche1',
|
||||
value: 'nc-icon-gouwuche1'
|
||||
}
|
||||
])
|
||||
|
||||
const changeBtnStyle = (item: any) => {
|
||||
diyStore.editComponent.btnStyle.style = item.value
|
||||
}
|
||||
|
||||
const categoryTableRef = ref<InstanceType<typeof ElTable>>()
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
*/
|
||||
let currCategoryData: any = null
|
||||
const loadCategoryList = () => {
|
||||
categoryTable.loading = true
|
||||
|
||||
getCategoryTree().then(res => {
|
||||
categoryTable.loading = false
|
||||
categoryTable.data = res.data
|
||||
}).catch(() => {
|
||||
categoryTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
// 选择商品分类
|
||||
const handleSelectionChange = (val: string | any[]) => {
|
||||
let data = ''
|
||||
if (val) data = val[val.length - 1]
|
||||
if (val.length > 1) categoryTableRef.value!.clearSelection()
|
||||
if (data) categoryTableRef.value!.toggleRowSelection(data, true)
|
||||
currCategoryData = data
|
||||
}
|
||||
|
||||
const saveCategoryId = () => {
|
||||
diyStore.editComponent.goods_category = currCategoryData.category_id
|
||||
diyStore.editComponent.goods_category_name = currCategoryData.category_name
|
||||
categoryShowDialog.value = false
|
||||
}
|
||||
|
||||
const categoryShowDialogOpen = () => {
|
||||
categoryShowDialog.value = true
|
||||
nextTick(() => {
|
||||
setRowSelection()
|
||||
})
|
||||
}
|
||||
|
||||
// 分类数据选中回填,设置展开行
|
||||
const expand_category_ids = ref<Array<any>>([])
|
||||
const setRowSelection = () => {
|
||||
expand_category_ids.value = []
|
||||
categoryTable.data.forEach((el: any) => {
|
||||
if (diyStore.editComponent.goods_category == el.category_id) {
|
||||
categoryTableRef.value!.toggleRowSelection(el, true)
|
||||
} else if (el.child_list && el.child_list.length) {
|
||||
el.child_list.forEach((v: any) => {
|
||||
if (diyStore.editComponent.goods_category == v.category_id) {
|
||||
expand_category_ids.value.push(el.category_id.toString())
|
||||
categoryTableRef.value!.toggleRowSelection(v, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.goods-list-slider {
|
||||
.el-slider__input {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,654 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('styleLabel')">
|
||||
<el-radio-group v-model="diyStore.editComponent.headStyle">
|
||||
<el-radio label="style-1">{{ t('headStyle1') }}</el-radio>
|
||||
<el-radio label="style-2">{{ t('headStyle2') }}</el-radio>
|
||||
<el-radio label="style-3">{{ t('headStyle3') }}</el-radio>
|
||||
<el-radio label="style-4">{{ t('headStyle4') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('manyGoodsListAroundRadius')" v-show="diyStore.editComponent.headStyle == 'style-3'">
|
||||
<el-slider v-model="diyStore.editComponent.aroundRadius" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('goodsSet') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('sortWay')">
|
||||
<el-radio-group v-model="diyStore.editComponent.sortWay">
|
||||
<el-radio label="default">{{ t('default') }}</el-radio>
|
||||
<el-radio label="sale_num">{{ t('sales') }}</el-radio>
|
||||
<el-radio label="price">{{ t('price') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNum')">
|
||||
<el-slider show-input class="diy-nav-slider" v-model="diyStore.editComponent.num" :min="1" max="20" size="small" />
|
||||
</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]">
|
||||
<el-form-item :label="t('dataSources')">
|
||||
<el-radio-group v-model="diyStore.editComponent.source">
|
||||
<el-radio label="custom">{{ t('manyGoodsListSourceDiy') }}</el-radio>
|
||||
<el-radio label="goods_category">{{ t('manyGoodsListSourceCategory') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsCategoryTitle')" v-show="diyStore.editComponent.source == 'goods_category'">
|
||||
<el-input v-model.trim="diyStore.editComponent.goods_category_name" :placeholder="t('selectCategory')" readonly class="select-diy-page-input" @click="firstCategoryShowDialogOpen()">
|
||||
<template #suffix>
|
||||
<div @click.stop="clearCategory">
|
||||
<el-icon v-if="diyStore.editComponent.goods_category_name">
|
||||
<Close />
|
||||
</el-icon>
|
||||
<el-icon v-else>
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<div v-show="diyStore.editComponent.source == 'custom'">
|
||||
|
||||
<p class="text-sm text-gray-400 mb-[10px]">{{ t('dragMouseAdjustOrder') }}</p>
|
||||
|
||||
<div ref="goodsBoxRef">
|
||||
<div v-for="(item,index) in diyStore.editComponent.list" :key="item.id"
|
||||
class="item-wrap p-[10px] pb-0 relative border border-dashed border-gray-300 mb-[16px]">
|
||||
|
||||
<el-form-item :label="t('manyGoodsListCategoryName')">
|
||||
<el-input v-model.trim="item.title" clearable maxlength="4" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('manyGoodsListSubTitle')" v-show="diyStore.editComponent.headStyle == 'style-1'">
|
||||
<el-input v-model.trim="item.desc" clearable maxlength="5" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio-group v-model="item.source">
|
||||
<el-radio label="all">{{ t('goodsSelectPopupAllGoods') }}</el-radio>
|
||||
<el-radio label="category">{{ t('selectCategory') }}</el-radio>
|
||||
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('selectCategory')" v-if="item.source == 'category'">
|
||||
<div class="flex items-center w-full">
|
||||
<div class="cursor-pointer ml-auto" @click="categoryShowDialogOpen(index)">
|
||||
<span class="text-[var(--el-color-primary)]">{{ item.goods_category_name }}</span>
|
||||
<span class="iconfont iconxiangyoujiantou"></span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('customGoods')" v-if="item.source == 'custom'">
|
||||
<goods-select-popup ref="goodsSelectPopupRef" v-model="item.goods_ids" :min="1" :max="99" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('image')" v-show="diyStore.editComponent.headStyle == 'style-3'">
|
||||
<upload-image v-model="item.imageUrl" :limit="1" />
|
||||
</el-form-item>
|
||||
|
||||
<div class="del absolute cursor-pointer z-[2] top-[-8px] right-[-8px]"
|
||||
v-show="diyStore.editComponent.list.length > 1"
|
||||
@click="diyStore.editComponent.list.splice(index,1)">
|
||||
<icon name="element CircleCloseFilled" color="#bbb" size="20px" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button class="w-full" @click="addItem">{{ t('manyGoodsLisAddItem') }}</el-button>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
<!-- 选择一级商品分类弹出框 -->
|
||||
<el-dialog v-model="firstCategoryShowDialog" :title="t('goodsCategoryTitle')" width="750px" :destroy-on-close="true" :close-on-click-modal="false">
|
||||
<el-table :data="firstCategoryTable.data" ref="firstCategoryTableRef" size="large"
|
||||
v-loading="firstCategoryTable.loading" height="450px"
|
||||
@current-change="handleCurrentCategoryChange" row-key="category_id" highlight-current-row>
|
||||
<template #empty>
|
||||
<span>{{ !firstCategoryTable.loading ? t('emptyData') : '' }}</span>
|
||||
</template>
|
||||
<el-table-column :label="t('categoryName')" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span class="order-2">{{ row.category_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('categoryImage')" width="170" align="left">
|
||||
<template #default="{ row }">
|
||||
<div class="h-[30px]">
|
||||
<el-image class="w-[30px] h-[30px] " :src="img(row.image)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex items-center justify-end mt-[15px]">
|
||||
<el-button type="primary" @click="saveFirstCategoryId">{{ t('confirm') }}</el-button>
|
||||
<el-button @click="firstCategoryShowDialog = false">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="categoryShowDialog" :title="t('goodsCategoryTitle')" width="750px" :destroy-on-close="true" :close-on-click-modal="false">
|
||||
<div class="table w-[100%] mt-[15px]" v-loading="categoryTable.loading">
|
||||
<div class="table-head flex items-center bg-[#f5f7f9] py-[10px] text-[14px]" :style="{ paddingRight: scrollBarWidth + 'px' }">
|
||||
<div class="w-[6%]"></div>
|
||||
<div class="w-[10%]">
|
||||
<!-- <el-checkbox v-model="staircheckAll" :indeterminate="isStairIndeterminate" @change="handleCheckAllChange" /> -->
|
||||
</div>
|
||||
<div class="w-[50%]">{{ t('categoryName') }}</div>
|
||||
<div class="w-[34%] h-[30px] leading-[30px]">{{ t('categoryImage') }}</div>
|
||||
</div>
|
||||
<div class="table-body max-h-[500px] overflow-y-auto" ref="tableBodyRef">
|
||||
<!-- 遍历一级分类 -->
|
||||
<div v-for="(row, rowIndex) in categoryTable.data" :key="rowIndex" class="flex flex-col">
|
||||
<div class="flex items-center border-solid border-[#e5e7eb] py-[10px] border-b-[1px]">
|
||||
<!-- 图标:展开/收起子级 -->
|
||||
<div v-if="row.child_list && row.child_list.length" class="w-[6%] cursor-pointer text-center !text-[10px]" @click="secondLevelArrowChange(row)" :class="{ 'iconfont iconxiangyoujiantou': row.child_list.length, 'arrow-show': row.isShow }"></div>
|
||||
<div v-else class="w-[6%]"></div>
|
||||
<!-- 一级分类复选框 -->
|
||||
<div class="w-[10%]">
|
||||
<el-checkbox v-model="row.secondLevelCheckAll" :indeterminate="row.isSecondLevelIndeterminate" @change="handleCheckboxChange($event, row)" />
|
||||
</div>
|
||||
<!-- 一级分类名称 -->
|
||||
<div class="ml-2 flex flex-col items-start w-[50%]">
|
||||
<span :title="row.category_name" class="multi-hidden leading-[1.4] mr-5 text-[14px] text-[#666]">
|
||||
{{ row.category_name }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 一级分类图片 -->
|
||||
<div class="flex items-center cursor-pointer w-[34%]">
|
||||
<div class="min-w-[30px] h-[30px] flex items-center justify-center">
|
||||
<el-image v-if="row.img" class="w-[30px] h-[30px]" :src="img(row.img)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<img v-else class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" fit="contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 子级分类 -->
|
||||
<div v-show="row.child_list && row.isShow">
|
||||
<div v-for="(item, index) in row.child_list" :key="index" class="flex items-center py-[10px] border-solid border-b-[1px]" :class="{ 'hidden': !row.isShow, 'border-[#e5e7eb]': index == (row.child_list.length - 1) }">
|
||||
<div class="w-[9%]"></div>
|
||||
<!-- 子级分类复选框 -->
|
||||
<div class="w-[7%]">
|
||||
<el-checkbox v-model="item.threeLevelCheckAll" @change="handleCheckboxChange($event, item, row)" />
|
||||
</div>
|
||||
<!-- 子级分类名称 -->
|
||||
<div class="ml-2 flex flex-col items-start w-[50%]">
|
||||
<span :title="item.category_name" class="multi-hidden leading-[1.4] mr-5 text-[14px] text-[#666]">
|
||||
{{ item.category_name }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- 子级分类图片 -->
|
||||
<div class="flex items-center cursor-pointer w-[34%]">
|
||||
<div class="min-w-[30px] h-[30px] flex items-center justify-center">
|
||||
<el-image v-if="row.img" class="w-[30px] h-[30px]" :src="img(row.img)" fit="contain">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<img class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<img v-else class="w-[30px] h-[30px]" src="@/addon/shop/assets/category_default.png" fit="contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!categoryTable.data.length && !categoryTable.loading" class="h-[60px] flex items-center justify-center border-solid border-[#e5e7eb] py-[12px] border-b-[1px]">{{ t('emptyData') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-end mt-[15px]">
|
||||
<el-button type="primary" @click="saveCategoryId">{{ t('confirm') }}</el-button>
|
||||
<el-button @click="categoryShowDialog = false">{{ t('cancel') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap mt-[20px]">
|
||||
<h3 class="mb-[10px]">{{ t("goodsBuyBtn") }}</h3>
|
||||
<el-form label-width="90px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsBtnIsShow')">
|
||||
<el-switch v-model="diyStore.editComponent.btnStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsCartIncident')" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<el-radio-group v-model="diyStore.editComponent.btnStyle.cartEvent">
|
||||
<el-radio label="detail">{{ t('goodsDetail') }}</el-radio>
|
||||
<el-radio label="cart">{{ t('goodsAddCart') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsBtnStyle')" class="!items-center" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<div class="flex">
|
||||
<template v-for="(item,index) in btnStyleList">
|
||||
<div v-if=" item.isShow == true"
|
||||
class="cursor-pointer flex items-center justify-center border-[1px] border-solid border-transparent rounded-[6px] py-[5px] px-[8px] mr-[10px]"
|
||||
:class="{'!border-[var(--el-color-primary)]': diyStore.editComponent.btnStyle.style == item.value}">
|
||||
<div v-if="item.type == 'icon'"
|
||||
:class="['nc-iconfont !text-[25px] text-[var(--el-color-primary)]', item.title]" @click="changeBtnStyle(item)"></div>
|
||||
<div v-if="item.type == 'button'"
|
||||
class="leading-[1] text-[12px] px-[10px] py-[8px] text-[#fff] rounded-[20px] bg-[var(--el-color-primary)]"
|
||||
@click="changeBtnStyle(item)">{{ item.title }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsBtnText')" v-if="diyStore.editComponent.btnStyle.control && diyStore.editComponent.btnStyle.style == 'button'">
|
||||
<el-input v-model.trim="diyStore.editComponent.btnStyle.text"
|
||||
:placeholder="t('goodsBtnTextPlaceholder')" clearable maxlength="4" show-word-limit />
|
||||
</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]">
|
||||
<el-form-item :label="t('goodsSelectPopupGoodsName')" v-if="diyStore.editComponent.goodsNameStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.goodsNameStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsPriceColor')" v-if="diyStore.editComponent.priceStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.priceStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSaleNum')" v-if="diyStore.editComponent.saleStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.saleStyle.control" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsLabel')" v-if="diyStore.editComponent.labelStyle.isShow">
|
||||
<el-switch v-model="diyStore.editComponent.labelStyle.control" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('goodsStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsBgColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.elementBgColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNameColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsNameStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
<div class="mr-[20px]"></div>
|
||||
<el-radio-group v-model="diyStore.editComponent.goodsNameStyle.fontWeight">
|
||||
<el-radio :label="'normal'">{{ t('fontWeightNormal') }}</el-radio>
|
||||
<el-radio :label="'bold'">{{ t('fontWeightBold') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('imageRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.imgElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsPriceColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.priceStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSaleColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.saleStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.topElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bottomRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.bottomElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="edit-attr-item-wrap" v-if="diyStore.editComponent.btnStyle.control">
|
||||
<h3 class="mb-[10px]">{{ t("goodsBuyBtn") }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsTextColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.btnStyle.textColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('listFrameColor')">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- 组件样式 -->
|
||||
<slot name="style"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { t } from '@/lang'
|
||||
import { img } from '@/utils/common'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { ElTable } from 'element-plus'
|
||||
import { range } from 'lodash-es'
|
||||
import Sortable from 'sortablejs'
|
||||
import { getCategoryTree, getCategoryList } from '@/addon/shop/api/goods'
|
||||
import goodsSelectPopup from '@/addon/shop/views/goods/components/goods-select-popup.vue'
|
||||
|
||||
const diyStore: any = useDiyStore()
|
||||
diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
|
||||
if (diyStore.value[index].source == 'custom') {
|
||||
|
||||
diyStore.value[index].list.forEach((item: any) => {
|
||||
if (item.source === 'category') {
|
||||
if (item.goods_category == '') {
|
||||
res.code = false
|
||||
res.message = t('goodsCategoryPlaceholder')
|
||||
return res
|
||||
}
|
||||
} else if (item.source == 'custom') {
|
||||
if (item.goods_ids.length == 0) {
|
||||
res.code = false
|
||||
res.message = t('goodsPlaceholder')
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (diyStore.value[index].source == 'goods_category') {
|
||||
if (diyStore.value[index].goods_category == '') {
|
||||
res.code = false
|
||||
res.message = t('goodsCategoryPlaceholder')
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
diyStore.editComponent.list.forEach((item: any) => {
|
||||
if (!item.id) item.id = diyStore.generateRandom()
|
||||
})
|
||||
|
||||
// 一级商品分类
|
||||
const firstCategoryShowDialog = ref(false)
|
||||
|
||||
const firstCategoryTable = reactive({
|
||||
loading: true,
|
||||
data: [],
|
||||
searchParam: {
|
||||
level: 1
|
||||
}
|
||||
})
|
||||
|
||||
const firstCategoryTableRef = ref<InstanceType<typeof ElTable>>()
|
||||
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
*/
|
||||
const loadCategoryList = () => {
|
||||
firstCategoryTable.loading = true
|
||||
|
||||
getCategoryList({
|
||||
...firstCategoryTable.searchParam
|
||||
}).then(res => {
|
||||
firstCategoryTable.loading = false
|
||||
firstCategoryTable.data = res.data
|
||||
}).catch(() => {
|
||||
firstCategoryTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const saveFirstCategoryId = () => {
|
||||
diyStore.editComponent.goods_category = currFirstCategory.category_id
|
||||
diyStore.editComponent.goods_category_name = currFirstCategory.category_name;
|
||||
firstCategoryShowDialog.value = false
|
||||
}
|
||||
|
||||
const firstCategoryShowDialogOpen = () => {
|
||||
firstCategoryShowDialog.value = true
|
||||
if (currFirstCategory) {
|
||||
setTimeout(() => {
|
||||
firstCategoryTableRef.value!.setCurrentRow(currFirstCategory)
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
const btnStyleList = reactive([
|
||||
{
|
||||
isShow: true,
|
||||
type: 'button',
|
||||
title: diyStore.editComponent.btnStyle.text,
|
||||
value: 'button'
|
||||
},
|
||||
{
|
||||
isShow: true,
|
||||
type: 'icon',
|
||||
title: 'nc-icon-jiahaoV6xx',
|
||||
value: 'nc-icon-jiahaoV6xx'
|
||||
},
|
||||
{
|
||||
isShow: true,
|
||||
type: 'icon',
|
||||
title: 'nc-icon-gouwuche1',
|
||||
value: 'nc-icon-gouwuche1'
|
||||
}
|
||||
])
|
||||
diyStore.editComponent.btnStyle.style = 'nc-icon-jiahaoV6xx';
|
||||
|
||||
const changeBtnStyle = (item: any) => {
|
||||
diyStore.editComponent.btnStyle.style = item.value
|
||||
}
|
||||
|
||||
const clearCategory = () => {
|
||||
diyStore.editComponent.goods_category = ''
|
||||
diyStore.editComponent.goods_category_name = '';
|
||||
}
|
||||
|
||||
// 选择商品分类
|
||||
let currFirstCategory: any = {}
|
||||
const handleCurrentCategoryChange = (val: string | any[]) => {
|
||||
currFirstCategory = val
|
||||
}
|
||||
|
||||
// 商品分类树结构
|
||||
const categoryShowDialog = ref(false)
|
||||
|
||||
const goodsBoxRef = ref()
|
||||
|
||||
const categoryTable = reactive({
|
||||
loading: true,
|
||||
data: []
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadCategoryTree()
|
||||
|
||||
loadCategoryList()
|
||||
|
||||
nextTick(() => {
|
||||
const sortable = Sortable.create(goodsBoxRef.value, {
|
||||
group: 'item-wrap',
|
||||
animation: 200,
|
||||
onEnd: event => {
|
||||
const temp = diyStore.editComponent.list[event.oldIndex!]
|
||||
diyStore.editComponent.list.splice(event.oldIndex!, 1)
|
||||
diyStore.editComponent.list.splice(event.newIndex!, 0, temp)
|
||||
sortable.sort(
|
||||
range(diyStore.editComponent.list.length).map(value => {
|
||||
return value.toString()
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
window.addEventListener("resize", getScrollBarWidth);
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
*/
|
||||
// let currCategoryData: any = null
|
||||
const loadCategoryTree = () => {
|
||||
categoryTable.loading = true
|
||||
|
||||
getCategoryTree().then(res => {
|
||||
categoryTable.loading = false
|
||||
categoryTable.data = res.data
|
||||
categoryTable.data.forEach((item: any) => {
|
||||
// 初始化一级分类的字段
|
||||
item.isShow = false; // 控制子级是否展开
|
||||
item.isSecondLevelIndeterminate = false; // 一级分类不确定状态
|
||||
item.secondLevelCheckAll = false; // 一级分类复选框状态
|
||||
|
||||
// 如果有子分类(child_list),初始化子分类的字段
|
||||
if (item.child_list && item.child_list.length) {
|
||||
item.child_list.forEach((childItem: any) => {
|
||||
childItem.threeLevelCheckAll = false // 子分类复选框状态
|
||||
})
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
categoryTable.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const addItem = () => {
|
||||
diyStore.editComponent.list.push({
|
||||
id: diyStore.generateRandom(),
|
||||
title: "分类",
|
||||
desc: "分类描述",
|
||||
source: "all",
|
||||
goods_category: '',
|
||||
goods_category_name: '请选择',
|
||||
goods_ids: [],
|
||||
imageUrl: ''
|
||||
})
|
||||
}
|
||||
|
||||
const scrollBarWidth = ref(0);
|
||||
const tableBodyRef = ref(null);
|
||||
|
||||
const getScrollBarWidth = () => {
|
||||
nextTick(() => {
|
||||
if (tableBodyRef.value) {
|
||||
scrollBarWidth.value = tableBodyRef.value.offsetWidth - tableBodyRef.value.clientWidth;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择商品分类
|
||||
let selectIndex = 0; // 当前选择的下标
|
||||
const selectedCategories = ref({});
|
||||
// 方法:切换子级展开/收起
|
||||
const secondLevelArrowChange = (row:any) => {
|
||||
row.isShow = !row.isShow;
|
||||
nextTick(() => getScrollBarWidth());
|
||||
};
|
||||
|
||||
const saveCategoryId = () => {
|
||||
const selected = selectedCategories.value[selectIndex];
|
||||
if (!selected || !selected.category_id) { // 确保 `category_id` 存在
|
||||
ElMessage({
|
||||
type: 'warning',
|
||||
message: t('请选择分类'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
diyStore.editComponent.list[selectIndex].goods_category = selectedCategories.value[selectIndex].category_id
|
||||
diyStore.editComponent.list[selectIndex].goods_category_name = selectedCategories.value[selectIndex].category_name;
|
||||
categoryShowDialog.value = false
|
||||
}
|
||||
|
||||
const clearAllSelections = () => {
|
||||
categoryTable.data.forEach((row: any) => {
|
||||
row.secondLevelCheckAll = false;
|
||||
if (row.child_list) {
|
||||
row.child_list.forEach((child: any) => {
|
||||
child.threeLevelCheckAll = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const categoryShowDialogOpen = (index:any) => {
|
||||
selectIndex = index;
|
||||
clearAllSelections();
|
||||
|
||||
// 设置 isShow 状态
|
||||
categoryTable.data.forEach((row: any) => {
|
||||
row.isShow = false; // 默认所有分类都是合住的
|
||||
});
|
||||
// 确保 `selectedCategories.value[selectIndex]` 存在
|
||||
if (!selectedCategories.value[selectIndex]) {
|
||||
selectedCategories.value[selectIndex] = {}; // 初始化为空对象
|
||||
}
|
||||
// 回显已选中的分类
|
||||
nextTick(() => {
|
||||
const selectedCategory = diyStore.editComponent.list[selectIndex];
|
||||
// 初始化 selectedCategories.value[selectIndex]
|
||||
if (!selectedCategories.value[selectIndex]) {
|
||||
selectedCategories.value[selectIndex] = {}; // 初始化为空对象
|
||||
selectedCategories.value[selectIndex].category_id = selectedCategory.goods_category;
|
||||
selectedCategories.value[selectIndex].category_name = selectedCategory.goods_category_name;
|
||||
}
|
||||
|
||||
|
||||
if (selectedCategory) {
|
||||
categoryTable.data.forEach((row: any) => {
|
||||
if (row.category_id === selectedCategory.goods_category) {
|
||||
row.secondLevelCheckAll = true;
|
||||
row.isShow = true; // 展开选中的一级分类
|
||||
}
|
||||
if (row.child_list) {
|
||||
row.child_list.forEach((child: any) => {
|
||||
if (child.category_id === selectedCategory.goods_category) {
|
||||
child.threeLevelCheckAll = true;
|
||||
row.isShow = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
nextTick(() => getScrollBarWidth());
|
||||
categoryShowDialog.value = true;
|
||||
}
|
||||
|
||||
// 处理复选框变化
|
||||
const handleCheckboxChange = (checked: any, target: any, parentRow: any) => {
|
||||
clearAllSelections(); // 清空所有复选框的选中状态
|
||||
if (checked) {
|
||||
// 设置当前选中的分类
|
||||
if (parentRow) {
|
||||
// 如果是子分类
|
||||
target.threeLevelCheckAll = checked;
|
||||
selectedCategories.value[selectIndex] = target;
|
||||
parentRow.isShow = true; // 展开父级分类
|
||||
} else {
|
||||
// 如果是一级分类
|
||||
target.secondLevelCheckAll = checked;
|
||||
selectedCategories.value[selectIndex] = target;
|
||||
target.isShow = true; // 展开选中的一级分类
|
||||
}
|
||||
} else {
|
||||
// 取消勾选时,清空选中的分类 ID
|
||||
delete selectedCategories.value[selectIndex];
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.arrow-show {
|
||||
transform: rotate(90deg) !important; /* 提高优先级 */
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
<!-- <div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('selectStyle') }}</h3>
|
||||
<div class="flex items-center mb-[18px] rounded overflow-hidden">
|
||||
<span
|
||||
class="iconfont icongudingzhanshi border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-1' }"
|
||||
@click="diyStore.editComponent.style = 'style-1'"></span>
|
||||
<span
|
||||
class="iconfont icontuwendaohang3 border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-2' }"
|
||||
@click="diyStore.editComponent.style = 'style-2'"></span>
|
||||
<span
|
||||
class="iconfont iconshangpinliebiaohengxianghuadong border-[1px] border-solid border-[#eee] cursor-pointer flex-1 flex items-center justify-center py-[5px]"
|
||||
:class="{ 'border-[var(--el-color-primary)] text-[var(--el-color-primary)]': diyStore.editComponent.style == 'style-3' }"
|
||||
@click="diyStore.editComponent.style = 'style-3'"></span>
|
||||
</div>
|
||||
</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('sortWay')">
|
||||
<el-radio-group v-model="diyStore.editComponent.sortWay">
|
||||
<el-radio label="total_order_num">{{ t('default') }}</el-radio>
|
||||
<el-radio label="total_exchange_num">{{ t('sales') }}</el-radio>
|
||||
<el-radio label="price">{{ t('price') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
|
||||
<el-radio label="all">{{ t('goodsSelectPopupAllGoods') }}</el-radio>
|
||||
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item :label="t('selectCategory')" v-if="diyStore.editComponent.source == 'category'">
|
||||
<div class="flex items-center w-full">
|
||||
<div class="cursor-pointer ml-auto" @click="categoryShowDialogOpen">
|
||||
<span class="text-[var(--el-color-primary)]">{{ diyStore.editComponent.goods_category_name }}</span>
|
||||
<span class="iconfont iconxiangyoujiantou"></span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNum')" v-if="diyStore.editComponent.source == 'all' || diyStore.editComponent.source == 'category'">
|
||||
<div class="flex items-center w-full ml-[5px]">
|
||||
<el-slider class="flex-1" v-model="diyStore.editComponent.num" :min="1" max="20" size="small" />
|
||||
<span class="ml-[15px]">{{ diyStore.editComponent.num }}</span>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
<el-form-item :label="t('customGoods')" v-if="diyStore.editComponent.source == 'custom'">
|
||||
<el-button type="primary" @click="goodsSelectPopupRef.show(diyStore.editComponent.goods_ids)">
|
||||
{{ t('goodsSelectPopupSelectGoodsButton') }}
|
||||
</el-button>
|
||||
<div class="inline-block ml-[10px] text-[14px]"
|
||||
v-show="diyStore.editComponent.goods_ids.length">
|
||||
<span>{{ t('goodsSelectPopupSelect') }}</span>
|
||||
<span class="text-primary mx-[2px]">{{ diyStore.editComponent.goods_ids.length }}</span>
|
||||
<span>{{ t('goodsSelectPopupPiece') }}</span>
|
||||
</div>
|
||||
<goods-select-popup ref="goodsSelectPopupRef" :min="1" @select="goodsSelect" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-if="diyStore.editTab == 'style'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('goodsStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('goodsNameColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.goodsNameStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
<div class="mr-[20px]"></div>
|
||||
<el-radio-group v-model="diyStore.editComponent.goodsNameStyle.fontWeight">
|
||||
<el-radio :label="'normal'">{{ t('fontWeightNormal') }}</el-radio>
|
||||
<el-radio :label="'bold'">{{ t('fontWeightBold') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('imageRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.imgElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsNumColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.saleStyle.color" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('goodsPriceColor')">
|
||||
<el-color-picker v-model="diyStore.editComponent.priceStyle.mainColor" show-alpha :predefine="diyStore.predefineColors" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('topRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.topElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('bottomRounded')">
|
||||
<el-slider v-model="diyStore.editComponent.bottomElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 组件样式 -->
|
||||
<slot name="style"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
import { ref, reactive } from 'vue'
|
||||
import goodsSelectPopup from '@/addon/shop/views/marketing/exchange/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].source == 'category') {
|
||||
if (diyStore.value[index].goods_category == '') {
|
||||
res.code = false
|
||||
res.message = t('goodsCategoryPlaceholder')
|
||||
}
|
||||
} else if (diyStore.value[index].source == 'custom') {
|
||||
if (diyStore.value[index].goods_ids.length == 0) {
|
||||
res.code = false
|
||||
res.message = t('goodsPlaceholder')
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
const goodsSelectPopupRef = ref()
|
||||
const goodsSelect = (val: any) => {
|
||||
diyStore.editComponent.goods_ids = val.map((el: any) => el.id)
|
||||
}
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<!-- 内容 -->
|
||||
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
|
||||
<div class="edit-attr-item-wrap">
|
||||
<h3 class="mb-[10px]">{{ t('memberStyle') }}</h3>
|
||||
<el-form label-width="80px" class="px-[10px]">
|
||||
<el-form-item :label="t('bgUrl')">
|
||||
<upload-image v-model="diyStore.editComponent.bgUrl" :limit="1" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 样式 -->
|
||||
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
|
||||
<!-- 组件样式 -->
|
||||
<slot name="style"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { t } from '@/lang'
|
||||
import useDiyStore from '@/stores/modules/diy'
|
||||
|
||||
const diyStore: any = useDiyStore()
|
||||
diyStore.editComponent.ignore = ['componentBgColor', 'componentBgUrl'] // 忽略公共属性
|
||||
|
||||
// 组件验证
|
||||
diyStore.editComponent.verify = (index: number) => {
|
||||
const res = { code: true, message: '' }
|
||||
return res
|
||||
}
|
||||
|
||||
defineExpose({})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||