Browse Source

修改地区选择组件

yuhongzhe
王泽彦 11 months ago
parent
commit
1167d9dbd5
  1. 8
      admin/.env.development
  2. 8
      admin/.env.production
  3. 3
      admin/.gitignore
  4. 3
      admin/auto-imports.d.ts
  5. 17
      admin/package.json
  6. 24
      admin/src/App.vue
  7. 106
      admin/src/addon/shop/api/delivery.ts
  8. 60
      admin/src/addon/shop/api/electronic_sheet.ts
  9. 325
      admin/src/addon/shop/api/goods.ts
  10. 231
      admin/src/addon/shop/api/marketing.ts
  11. 77
      admin/src/addon/shop/api/order.ts
  12. 12
      admin/src/addon/shop/api/shop.ts
  13. 25
      admin/src/addon/shop/api/shop_address.ts
  14. 8
      admin/src/addon/shop/api/stat.ts
  15. 68
      admin/src/addon/shop/lang/zh-cn/address.edit.json
  16. 2
      admin/src/addon/shop/lang/zh-cn/address.list.json
  17. 58
      admin/src/addon/shop/lang/zh-cn/common.json
  18. 38
      admin/src/addon/shop/lang/zh-cn/delivery.company.json
  19. 85
      admin/src/addon/shop/lang/zh-cn/delivery.company_edit.json
  20. 20
      admin/src/addon/shop/lang/zh-cn/delivery.config.json
  21. 2
      admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet.json
  22. 2
      admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet_config.json
  23. 2
      admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet_edit.json
  24. 108
      admin/src/addon/shop/lang/zh-cn/delivery.local.json
  25. 38
      admin/src/addon/shop/lang/zh-cn/delivery.search.json
  26. 16
      admin/src/addon/shop/lang/zh-cn/delivery.staff.json
  27. 34
      admin/src/addon/shop/lang/zh-cn/delivery.store.json
  28. 74
      admin/src/addon/shop/lang/zh-cn/delivery.store_edit.json
  29. 22
      admin/src/addon/shop/lang/zh-cn/delivery.template.json
  30. 76
      admin/src/addon/shop/lang/zh-cn/delivery.template_edit.json
  31. 4
      admin/src/addon/shop/lang/zh-cn/goods.attr.json
  32. 2
      admin/src/addon/shop/lang/zh-cn/goods.attr_edit.json
  33. 28
      admin/src/addon/shop/lang/zh-cn/goods.brand_list.json
  34. 50
      admin/src/addon/shop/lang/zh-cn/goods.category.json
  35. 52
      admin/src/addon/shop/lang/zh-cn/goods.category_config.json
  36. 96
      admin/src/addon/shop/lang/zh-cn/goods.evaluate.json
  37. 72
      admin/src/addon/shop/lang/zh-cn/goods.evaluate_edit.json
  38. 2
      admin/src/addon/shop/lang/zh-cn/goods.label_group_list.json
  39. 2
      admin/src/addon/shop/lang/zh-cn/goods.label_list.json
  40. 13
      admin/src/addon/shop/lang/zh-cn/goods.list.json
  41. 30
      admin/src/addon/shop/lang/zh-cn/goods.real_edit.json
  42. 18
      admin/src/addon/shop/lang/zh-cn/goods.service.json
  43. 30
      admin/src/addon/shop/lang/zh-cn/goods.virtual_edit.json
  44. 38
      admin/src/addon/shop/lang/zh-cn/index.index.json
  45. 82
      admin/src/addon/shop/lang/zh-cn/marketing.coupon.add.json
  46. 82
      admin/src/addon/shop/lang/zh-cn/marketing.coupon.edit.json
  47. 90
      admin/src/addon/shop/lang/zh-cn/marketing.coupon.list.json
  48. 72
      admin/src/addon/shop/lang/zh-cn/marketing.discount.add.json
  49. 14
      admin/src/addon/shop/lang/zh-cn/marketing.discount.config.json
  50. 2
      admin/src/addon/shop/lang/zh-cn/marketing.discount.detail.json
  51. 72
      admin/src/addon/shop/lang/zh-cn/marketing.discount.edit.json
  52. 98
      admin/src/addon/shop/lang/zh-cn/marketing.discount.list.json
  53. 124
      admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_add.json
  54. 123
      admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_edit.json
  55. 52
      admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_list.json
  56. 106
      admin/src/addon/shop/lang/zh-cn/marketing.exchange.order_list.json
  57. 72
      admin/src/addon/shop/lang/zh-cn/marketing.manjian.detail.json
  58. 2
      admin/src/addon/shop/lang/zh-cn/marketing.manjian.edit.json
  59. 88
      admin/src/addon/shop/lang/zh-cn/marketing.newcomer.config.json
  60. 110
      admin/src/addon/shop/lang/zh-cn/marketing.newcomer.order_list.json
  61. 48
      admin/src/addon/shop/lang/zh-cn/order.batch_delivery.json
  62. 76
      admin/src/addon/shop/lang/zh-cn/order.config.json
  63. 2
      admin/src/addon/shop/lang/zh-cn/order.detail.json
  64. 78
      admin/src/addon/shop/lang/zh-cn/order.invoice.json
  65. 210
      admin/src/addon/shop/lang/zh-cn/order.refund.json
  66. 2
      admin/src/addon/shop/lang/zh-cn/order.refund_detail.json
  67. 72
      admin/src/addon/shop/lang/zh-cn/stat.goods.json
  68. 726
      admin/src/addon/shop/views/address/edit.vue
  69. 275
      admin/src/addon/shop/views/address/list.vue
  70. 281
      admin/src/addon/shop/views/delivery/company.vue
  71. 626
      admin/src/addon/shop/views/delivery/company_edit.vue
  72. 171
      admin/src/addon/shop/views/delivery/components/delivery-personnel-edit.vue
  73. 248
      admin/src/addon/shop/views/delivery/config.vue
  74. 350
      admin/src/addon/shop/views/delivery/electronic_sheet.vue
  75. 341
      admin/src/addon/shop/views/delivery/electronic_sheet_config.vue
  76. 626
      admin/src/addon/shop/views/delivery/electronic_sheet_edit.vue
  77. 773
      admin/src/addon/shop/views/delivery/local.vue
  78. 260
      admin/src/addon/shop/views/delivery/search.vue
  79. 228
      admin/src/addon/shop/views/delivery/staff.vue
  80. 288
      admin/src/addon/shop/views/delivery/store.vue
  81. 688
      admin/src/addon/shop/views/delivery/store_edit.vue
  82. 256
      admin/src/addon/shop/views/delivery/template.vue
  83. 937
      admin/src/addon/shop/views/delivery/template_edit.vue
  84. 494
      admin/src/addon/shop/views/diy/components/edit-goods-coupon.vue
  85. 742
      admin/src/addon/shop/views/diy/components/edit-goods-list.vue
  86. 1054
      admin/src/addon/shop/views/diy/components/edit-many-goods-list.vue
  87. 211
      admin/src/addon/shop/views/diy/components/edit-shop-exchange-goods.vue
  88. 41
      admin/src/addon/shop/views/diy/components/edit-shop-exchange-info.vue
  89. 281
      admin/src/addon/shop/views/diy/components/edit-shop-goods-ranking.vue
  90. 388
      admin/src/addon/shop/views/diy/components/edit-shop-goods-recommend.vue
  91. 71
      admin/src/addon/shop/views/diy/components/edit-shop-member-info.vue
  92. 609
      admin/src/addon/shop/views/diy/components/edit-shop-newcomer.vue
  93. 205
      admin/src/addon/shop/views/diy/components/edit-shop-order-info.vue
  94. 43
      admin/src/addon/shop/views/diy/components/edit-shop-search.vue
  95. 639
      admin/src/addon/shop/views/diy/components/edit-single-recommend.vue
  96. 444
      admin/src/addon/shop/views/goods/attr.vue
  97. 862
      admin/src/addon/shop/views/goods/attr_edit.vue
  98. 328
      admin/src/addon/shop/views/goods/brand_list.vue
  99. 399
      admin/src/addon/shop/views/goods/category.vue
  100. 439
      admin/src/addon/shop/views/goods/category_config.vue

8
admin/.env.development

@ -0,0 +1,8 @@
# api请求地址
VITE_APP_BASE_URL='http://146.56.228.75:20024/adminapi/'
# 图片服务器地址
VITE_IMG_DOMAIN=''
# 请求时header中token的参数名
VITE_REQUEST_HEADER_TOKEN_KEY='token'

8
admin/.env.production

@ -0,0 +1,8 @@
# api请求地址
VITE_APP_BASE_URL='http://146.56.228.75:20024/adminapi/'
# 图片服务器地址
VITE_IMG_DOMAIN=''
# 请求时header中token的参数名
VITE_REQUEST_HEADER_TOKEN_KEY='token'

3
admin/.gitignore

@ -22,6 +22,3 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.env.development
.env.production

3
admin/auto-imports.d.ts

@ -1,6 +1,5 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElNotification: typeof import('element-plus/es')['ElNotification']
}

17
admin/package.json

@ -6,10 +6,7 @@
"scripts": {
"dev": "vite",
"build": "vite build && node publish.cjs",
"preview": "vite preview",
"lint": "eslint .",
"lint:fix": "eslint . --ext .ts --ext .vue --ext .js --fix",
"format": "prettier --write src/**/*.{ts,vue,js,json}"
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "2.0.10",
@ -41,25 +38,21 @@
"@tailwindcss/line-clamp": "0.4.2",
"@types/qrcode": "1.5.0",
"@types/sortablejs": "1.15.0",
"@typescript-eslint/eslint-plugin": "^8.32.1",
"@typescript-eslint/parser": "^8.32.1",
"@typescript-eslint/eslint-plugin": "5.53.0",
"@vitejs/plugin-vue": "4.0.0",
"autoprefixer": "10.4.13",
"eslint": "^9.26.0",
"eslint-config-prettier": "^10.1.5",
"eslint": "8.34.0",
"eslint-config-standard-with-typescript": "34.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "15.6.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-vue": "^10.1.0",
"eslint-plugin-vue": "9.9.0",
"postcss": "8.4.21",
"prettier": "^3.5.3",
"tailwindcss": "3.2.4",
"typescript": "4.9.5",
"unplugin-auto-import": "0.13.0",
"unplugin-vue-components": "0.23.0",
"vite": "4.1.0",
"vue-eslint-parser": "^10.1.3",
"vue-tsc": "1.0.24"
}
}
}

24
admin/src/App.vue

@ -1,7 +1,7 @@
<template>
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
</template>
<script lang="ts" setup>
@ -22,20 +22,16 @@ const locale = computed(() => (systemStore.lang === 'zh-cn' ? zhCn : en))
const toggleDark = useToggle(useDark())
watch(
route,
() => {
useAppStore().$patch((state) => {
state.route = route
watch(route, () => {
useAppStore().$patch(state => {
state.route = route
})
},
{ immediate: true }
)
}, { immediate: true })
onMounted(() => {
//
toggleDark(systemStore.dark)
setThemeColor(systemStore.theme, systemStore.dark ? 'dark' : 'light')
//
toggleDark(systemStore.dark)
setThemeColor(systemStore.theme, systemStore.dark ? 'dark' : 'light')
})
</script>

106
admin/src/addon/shop/api/delivery.ts

@ -7,7 +7,7 @@ import request from '@/utils/request'
* @returns
*/
export function getCompanyPageList(params: Record<string, any>) {
return request.get(`shop/delivery/company`, { params })
return request.get(`shop/delivery/company`, { params })
}
/**
@ -16,7 +16,7 @@ export function getCompanyPageList(params: Record<string, any>) {
* @returns
*/
export function getCompanyList(params: Record<string, any>) {
return request.get(`shop/delivery/company/list`, { params })
return request.get(`shop/delivery/company/list`, { params })
}
/**
@ -25,7 +25,7 @@ export function getCompanyList(params: Record<string, any>) {
* @returns
*/
export function getCompanyInfo(company_id: number) {
return request.get(`shop/delivery/company/${company_id}`)
return request.get(`shop/delivery/company/${ company_id }`);
}
/**
@ -34,10 +34,7 @@ export function getCompanyInfo(company_id: number) {
* @returns
*/
export function addCompany(params: Record<string, any>) {
return request.post('shop/delivery/company', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/delivery/company', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -46,10 +43,10 @@ export function addCompany(params: Record<string, any>) {
* @returns
*/
export function editCompany(params: Record<string, any>) {
return request.put(`shop/delivery/company/${params.company_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/delivery/company/${ params.company_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -58,12 +55,10 @@ export function editCompany(params: Record<string, any>) {
* @returns
*/
export function deleteCompany(company_id: number) {
return request.delete(`shop/delivery/company/${company_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/delivery/company/${ company_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/********************************* 运费模版 ***************************************/
/**
*
@ -71,7 +66,7 @@ export function deleteCompany(company_id: number) {
* @returns
*/
export function getShippingTemplatePageList(params: Record<string, any>) {
return request.get(`shop/shipping/template`, { params })
return request.get(`shop/shipping/template`, { params })
}
/**
@ -80,7 +75,7 @@ export function getShippingTemplatePageList(params: Record<string, any>) {
* @returns
*/
export function getShippingTemplateList(params: Record<string, any>) {
return request.get(`shop/shipping/template/list`, { params })
return request.get(`shop/shipping/template/list`, { params })
}
/**
@ -89,7 +84,7 @@ export function getShippingTemplateList(params: Record<string, any>) {
* @returns
*/
export function getShippingTemplateInfo(template_id: number) {
return request.get(`shop/shipping/template/${template_id}`)
return request.get(`shop/shipping/template/${ template_id }`);
}
/**
@ -98,10 +93,7 @@ export function getShippingTemplateInfo(template_id: number) {
* @returns
*/
export function addShippingTemplate(params: Record<string, any>) {
return request.post('shop/shipping/template', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/shipping/template', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -110,10 +102,10 @@ export function addShippingTemplate(params: Record<string, any>) {
* @returns
*/
export function editShippingTemplate(params: Record<string, any>) {
return request.put(`shop/shipping/template/${params.template_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/shipping/template/${ params.template_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -122,12 +114,13 @@ export function editShippingTemplate(params: Record<string, any>) {
* @returns
*/
export function deleteShippingTemplate(template_id: number) {
return request.delete(`shop/shipping/template/${template_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/shipping/template/${ template_id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/********************************* 自提门店 ***************************************/
/**
*
@ -135,7 +128,7 @@ export function deleteShippingTemplate(template_id: number) {
* @returns
*/
export function getStoreList(params: Record<string, any>) {
return request.get(`shop/delivery/store`, { params })
return request.get(`shop/delivery/store`, { params })
}
/**
@ -144,7 +137,7 @@ export function getStoreList(params: Record<string, any>) {
* @returns
*/
export function getStoreInfo(store_id: number) {
return request.get(`shop/delivery/store/${store_id}`)
return request.get(`shop/delivery/store/${ store_id }`);
}
/**
@ -153,10 +146,7 @@ export function getStoreInfo(store_id: number) {
* @returns
*/
export function addStore(params: Record<string, any>) {
return request.post('shop/delivery/store', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/delivery/store', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -165,10 +155,10 @@ export function addStore(params: Record<string, any>) {
* @returns
*/
export function editStore(params: Record<string, any>) {
return request.put(`shop/delivery/store/${params.store_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/delivery/store/${ params.store_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -177,10 +167,7 @@ export function editStore(params: Record<string, any>) {
* @returns
*/
export function deleteStore(store_id: number) {
return request.delete(`shop/delivery/store/${store_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/delivery/store/${ store_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/********************************* 物流查询 ***************************************/
@ -190,10 +177,7 @@ export function deleteStore(store_id: number) {
* @returns
*/
export function setDeliverySearch(params: Record<string, any>) {
return request.post('shop/delivery/search', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/delivery/search', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -201,7 +185,7 @@ export function setDeliverySearch(params: Record<string, any>) {
* @returns
*/
export function getDeliverySearch() {
return request.get('shop/delivery/search')
return request.get('shop/delivery/search')
}
/**
@ -209,7 +193,7 @@ export function getDeliverySearch() {
* @returns
*/
export function getShopDeliveryList() {
return request.get('shop/delivery/deliveryList')
return request.get('shop/delivery/deliveryList')
}
/**
@ -218,7 +202,7 @@ export function getShopDeliveryList() {
* @returns
*/
export function setShopDeliveryConfig(params: Record<string, any>) {
return request.put(`shop/delivery/setConfig`, params)
return request.put(`shop/delivery/setConfig`, params)
}
/**
@ -227,7 +211,7 @@ export function setShopDeliveryConfig(params: Record<string, any>) {
* @returns
*/
export function getShopDelivery(params: Record<string, any>) {
return request.get('shop/delivery/staff', { params })
return request.get('shop/delivery/staff', { params })
}
/**
@ -236,7 +220,7 @@ export function getShopDelivery(params: Record<string, any>) {
* @returns
*/
export function getShopDeliverInfo(staff_id: number) {
return request.get(`shop/delivery/staff/${staff_id}`)
return request.get(`shop/delivery/staff/${ staff_id }`);
}
/**
@ -245,9 +229,7 @@ export function getShopDeliverInfo(staff_id: number) {
* @returns
*/
export function addShopDeliver(params: Record<string, any>) {
return request.post('shop/delivery/staff', params, {
showSuccessMessage: true,
})
return request.post('shop/delivery/staff', params, { showSuccessMessage: true })
}
/**
@ -256,9 +238,7 @@ export function addShopDeliver(params: Record<string, any>) {
* @returns
*/
export function editShopDeliver(params: Record<string, any>) {
return request.put(`shop/delivery/staff/${params.deliver_id}`, params, {
showSuccessMessage: true,
})
return request.put(`shop/delivery/staff/${ params.deliver_id }`, params, { showSuccessMessage: true })
}
/**
@ -267,7 +247,7 @@ export function editShopDeliver(params: Record<string, any>) {
* @returns
*/
export function deleteShopDeliver(staff_id: number) {
return request.delete(`shop/delivery/staff/${staff_id}`)
return request.delete(`shop/delivery/staff/${ staff_id }`)
}
/**
@ -275,7 +255,7 @@ export function deleteShopDeliver(staff_id: number) {
* @returns
*/
export function getLocal() {
return request.get('shop/local')
return request.get('shop/local');
}
/**
@ -284,5 +264,5 @@ export function getLocal() {
* @returns
*/
export function setLocal(params: Record<string, any>) {
return request.put('shop/local', params, { showSuccessMessage: true })
}
return request.put('shop/local', params, { showSuccessMessage: true })
}

60
admin/src/addon/shop/api/electronic_sheet.ts

@ -6,7 +6,7 @@ import request from '@/utils/request'
* @returns
*/
export function getElectronicSheetPageList(params: Record<string, any>) {
return request.get(`shop/electronic_sheet`, { params })
return request.get(`shop/electronic_sheet`, { params })
}
/**
@ -15,7 +15,7 @@ export function getElectronicSheetPageList(params: Record<string, any>) {
* @returns
*/
export function getElectronicSheetList(params: Record<string, any>) {
return request.get(`shop/electronic_sheet/list`, { params })
return request.get(`shop/electronic_sheet/list`, { params })
}
/**
@ -24,7 +24,7 @@ export function getElectronicSheetList(params: Record<string, any>) {
* @returns
*/
export function getElectronicSheetInfo(id: number) {
return request.get(`shop/electronic_sheet/${id}`)
return request.get(`shop/electronic_sheet/${ id }`);
}
/**
@ -33,10 +33,10 @@ export function getElectronicSheetInfo(id: number) {
* @returns
*/
export function addElectronicSheet(params: Record<string, any>) {
return request.post('shop/electronic_sheet', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/electronic_sheet', params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -45,10 +45,10 @@ export function addElectronicSheet(params: Record<string, any>) {
* @returns
*/
export function editElectronicSheet(params: Record<string, any>) {
return request.put(`shop/electronic_sheet/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/electronic_sheet/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -57,10 +57,10 @@ export function editElectronicSheet(params: Record<string, any>) {
* @returns
*/
export function deleteElectronicSheet(id: number) {
return request.delete(`shop/electronic_sheet/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/electronic_sheet/${ id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -69,10 +69,10 @@ export function deleteElectronicSheet(id: number) {
* @returns
*/
export function setDefaultElectronicSheet(params: Record<string, any>) {
return request.put(`shop/electronic_sheet/setDefault/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/electronic_sheet/setDefault/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -81,10 +81,10 @@ export function setDefaultElectronicSheet(params: Record<string, any>) {
* @returns
*/
export function setElectronicSheetConfig(params: Record<string, any>) {
return request.post('shop/electronic_sheet/config', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/electronic_sheet/config', params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -92,7 +92,7 @@ export function setElectronicSheetConfig(params: Record<string, any>) {
* @returns
*/
export function getElectronicSheetConfig() {
return request.get(`shop/electronic_sheet/config`)
return request.get(`shop/electronic_sheet/config`)
}
/**
@ -100,7 +100,7 @@ export function getElectronicSheetConfig() {
* @returns
*/
export function getElectronicSheetPayType() {
return request.get(`shop/electronic_sheet/paytype`)
return request.get(`shop/electronic_sheet/paytype`)
}
/**
@ -109,8 +109,8 @@ export function getElectronicSheetPayType() {
* @returns
*/
export function printElectronicSheet(params: Record<string, any>) {
return request.post('shop/electronic_sheet/print', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
}
return request.post('shop/electronic_sheet/print', params, {
showErrorMessage: true,
showSuccessMessage: true
})
}

325
admin/src/addon/shop/api/goods.ts

@ -6,7 +6,7 @@ import request from '@/utils/request'
* @returns
*/
export function getGoodsPageList(params: Record<string, any>) {
return request.get(`shop/goods`, { params })
return request.get(`shop/goods`, { params })
}
/**
@ -15,7 +15,7 @@ export function getGoodsPageList(params: Record<string, any>) {
* @returns
*/
export function getGoodsInfo(goods_id: number) {
return request.get(`shop/goods/${goods_id}`)
return request.get(`shop/goods/${ goods_id }`);
}
/**
@ -24,10 +24,7 @@ export function getGoodsInfo(goods_id: number) {
* @returns
*/
export function addGoods(params: Record<string, any>) {
return request.post('shop/goods', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -35,10 +32,7 @@ export function addGoods(params: Record<string, any>) {
* @param params
*/
export function editGoods(params: Record<string, any>) {
return request.put(`shop/goods/${params.goods_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/${ params.goods_id }`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -46,7 +40,7 @@ export function editGoods(params: Record<string, any>) {
* @param params
*/
export function getGoodsInit(params: Record<string, any>) {
return request.get(`shop/goods/init`, { params })
return request.get(`shop/goods/init`, { params });
}
/**
@ -55,10 +49,7 @@ export function getGoodsInit(params: Record<string, any>) {
* @returns
*/
export function addVirtualGoods(params: Record<string, any>) {
return request.post('shop/goods/virtual', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/virtual', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -66,10 +57,10 @@ export function addVirtualGoods(params: Record<string, any>) {
* @param params
*/
export function editVirtualGoods(params: Record<string, any>) {
return request.put(`shop/goods/virtual/${params.goods_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/virtual/${ params.goods_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -77,7 +68,7 @@ export function editVirtualGoods(params: Record<string, any>) {
* @param params
*/
export function getVirtualGoodsInit(params: Record<string, any>) {
return request.get(`shop/goods/virtual/init`, { params })
return request.get(`shop/goods/virtual/init`, { params });
}
/**
@ -86,10 +77,7 @@ export function getVirtualGoodsInit(params: Record<string, any>) {
* @returns
*/
export function deleteGoods(params: Record<string, any>) {
return request.put(`shop/goods/delete`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/delete`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -98,7 +86,7 @@ export function deleteGoods(params: Record<string, any>) {
* @returns
*/
export function getRecycleGoodsPageList(params: Record<string, any>) {
return request.get(`shop/goods/recycle`, { params })
return request.get(`shop/goods/recycle`, { params })
}
/**
@ -107,10 +95,7 @@ export function getRecycleGoodsPageList(params: Record<string, any>) {
* @returns
*/
export function recycleGoods(params: Record<string, any>) {
return request.put(`shop/goods/recycle`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/recycle`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -118,7 +103,7 @@ export function recycleGoods(params: Record<string, any>) {
* @param params
*/
export function editGoodsSort(params: Record<string, any>) {
return request.put(`shop/goods/sort`, params, { showSuccessMessage: true })
return request.put(`shop/goods/sort`, params, { showSuccessMessage: true })
}
/**
@ -126,7 +111,7 @@ export function editGoodsSort(params: Record<string, any>) {
* @param params
*/
export function editGoodsStatus(params: Record<string, any>) {
return request.put(`shop/goods/status`, params, { showSuccessMessage: true })
return request.put(`shop/goods/status`, params, { showSuccessMessage: true })
}
/**
@ -134,9 +119,7 @@ export function editGoodsStatus(params: Record<string, any>) {
* @param params
*/
export function copyGoods(params: Record<string, any>) {
return request.put(`shop/goods/copy/${params.goods_id}`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/copy/${ params.goods_id }`, params, { showSuccessMessage: true })
}
/**
@ -145,7 +128,7 @@ export function copyGoods(params: Record<string, any>) {
* @returns
*/
export function getGoodsSelectPageList(params: Record<string, any>) {
return request.get(`shop/goods/select`, { params })
return request.get(`shop/goods/select`, { params })
}
/**
@ -154,7 +137,7 @@ export function getGoodsSelectPageList(params: Record<string, any>) {
* @returns
*/
export function getGoodsSkuList(params: Record<string, any>) {
return request.get(`shop/goods/sku`, { params })
return request.get(`shop/goods/sku`, { params })
}
/**
@ -163,7 +146,7 @@ export function getGoodsSkuList(params: Record<string, any>) {
* @returns
*/
export function getGoodsSkuNoPageList(params: Record<string, any>) {
return request.get(`shop/goods/selectgoodssku`, { params })
return request.get(`shop/goods/selectgoodssku`, { params })
}
/**
@ -171,7 +154,7 @@ export function getGoodsSkuNoPageList(params: Record<string, any>) {
* @returns
*/
export function getActiveGoodsCount(params: Record<string, any>) {
return request.get(`shop/goods/active/count`, { params })
return request.get(`shop/goods/active/count`, { params })
}
/**
@ -180,9 +163,7 @@ export function getActiveGoodsCount(params: Record<string, any>) {
* @returns
*/
export function editGoodsListStock(params: Record<string, any>) {
return request.put(`shop/goods/sku/stock`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/sku/stock`, params, { showSuccessMessage: true })
}
/**
@ -191,9 +172,7 @@ export function editGoodsListStock(params: Record<string, any>) {
* @returns
*/
export function editGoodsListPrice(params: Record<string, any>) {
return request.put(`shop/goods/sku/price`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/sku/price`, params, { showSuccessMessage: true })
}
/**
@ -202,9 +181,7 @@ export function editGoodsListPrice(params: Record<string, any>) {
* @returns
*/
export function editGoodsListMemberPrice(params: Record<string, any>) {
return request.put(`shop/goods/sku/member_price`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/sku/member_price`, params, { showSuccessMessage: true })
}
/**
@ -212,7 +189,7 @@ export function editGoodsListMemberPrice(params: Record<string, any>) {
* @returns
*/
export function getGoodsType() {
return request.get(`shop/goods/type`)
return request.get(`shop/goods/type`);
}
/**
@ -221,7 +198,7 @@ export function getGoodsType() {
* @returns
*/
export function getLabelPageList(params: Record<string, any>) {
return request.get(`shop/goods/label`, { params })
return request.get(`shop/goods/label`, { params })
}
/**
@ -230,7 +207,7 @@ export function getLabelPageList(params: Record<string, any>) {
* @returns
*/
export function getLabelList(params: Record<string, any>) {
return request.get(`shop/goods/label/list`, { params })
return request.get(`shop/goods/label/list`, { params })
}
/**
@ -239,7 +216,7 @@ export function getLabelList(params: Record<string, any>) {
* @returns
*/
export function getLabelInfo(label_id: number) {
return request.get(`shop/goods/label/${label_id}`)
return request.get(`shop/goods/label/${ label_id }`);
}
/**
@ -248,10 +225,7 @@ export function getLabelInfo(label_id: number) {
* @returns
*/
export function addLabel(params: Record<string, any>) {
return request.post('shop/goods/label', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/label', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -260,10 +234,10 @@ export function addLabel(params: Record<string, any>) {
* @returns
*/
export function editLabel(params: Record<string, any>) {
return request.put(`shop/goods/label/${params.label_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/label/${ params.label_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -271,9 +245,7 @@ export function editLabel(params: Record<string, any>) {
* @param params
*/
export function modifyLabelStatus(params: Record<string, any>) {
return request.put(`shop/goods/label/status`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/label/status`, params, { showSuccessMessage: true })
}
/**
@ -282,10 +254,7 @@ export function modifyLabelStatus(params: Record<string, any>) {
* @returns
*/
export function deleteLabel(label_id: number) {
return request.delete(`shop/goods/label/${label_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/label/${ label_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -293,9 +262,7 @@ export function deleteLabel(label_id: number) {
* @param params
*/
export function modifyLabelSort(params: Record<string, any>) {
return request.put(`shop/goods/label/sort`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/label/sort`, params, { showSuccessMessage: true })
}
/**
@ -304,7 +271,7 @@ export function modifyLabelSort(params: Record<string, any>) {
* @returns
*/
export function getLabelGroupPageList(params: Record<string, any>) {
return request.get(`shop/goods/label/group`, { params })
return request.get(`shop/goods/label/group`, { params })
}
/**
@ -313,7 +280,7 @@ export function getLabelGroupPageList(params: Record<string, any>) {
* @returns
*/
export function getLabelGroupList(params: Record<string, any>) {
return request.get(`shop/goods/label/group/list`, { params })
return request.get(`shop/goods/label/group/list`, { params })
}
/**
@ -322,7 +289,7 @@ export function getLabelGroupList(params: Record<string, any>) {
* @returns
*/
export function getLabelGroupInfo(label_id: number) {
return request.get(`shop/goods/label/group/${label_id}`)
return request.get(`shop/goods/label/group/${ label_id }`);
}
/**
@ -331,10 +298,7 @@ export function getLabelGroupInfo(label_id: number) {
* @returns
*/
export function addLabelGroup(params: Record<string, any>) {
return request.post('shop/goods/label/group', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/label/group', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -343,10 +307,10 @@ export function addLabelGroup(params: Record<string, any>) {
* @returns
*/
export function editLabelGroup(params: Record<string, any>) {
return request.put(`shop/goods/label/group/${params.group_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/label/group/${ params.group_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -355,10 +319,7 @@ export function editLabelGroup(params: Record<string, any>) {
* @returns
*/
export function deleteLabelGroup(group_id: number) {
return request.delete(`shop/goods/label/group/${group_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/label/group/${ group_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -366,9 +327,7 @@ export function deleteLabelGroup(group_id: number) {
* @param params
*/
export function modifyLabelGroupSort(params: Record<string, any>) {
return request.put(`shop/goods/label/group/sort`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/label/group/sort`, params, { showSuccessMessage: true })
}
/**
@ -377,7 +336,7 @@ export function modifyLabelGroupSort(params: Record<string, any>) {
* @returns
*/
export function getBrandPageList(params: Record<string, any>) {
return request.get(`shop/goods/brand`, { params })
return request.get(`shop/goods/brand`, { params })
}
/**
@ -386,7 +345,7 @@ export function getBrandPageList(params: Record<string, any>) {
* @returns
*/
export function getBrandList(params: Record<string, any>) {
return request.get(`shop/goods/brand/list`, { params })
return request.get(`shop/goods/brand/list`, { params })
}
/**
@ -395,7 +354,7 @@ export function getBrandList(params: Record<string, any>) {
* @returns
*/
export function getBrandInfo(brand_id: number) {
return request.get(`shop/goods/brand/${brand_id}`)
return request.get(`shop/goods/brand/${ brand_id }`);
}
/**
@ -404,10 +363,7 @@ export function getBrandInfo(brand_id: number) {
* @returns
*/
export function addBrand(params: Record<string, any>) {
return request.post('shop/goods/brand', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/brand', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -416,10 +372,10 @@ export function addBrand(params: Record<string, any>) {
* @returns
*/
export function editBrand(params: Record<string, any>) {
return request.put(`shop/goods/brand/${params.brand_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/brand/${ params.brand_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -427,9 +383,7 @@ export function editBrand(params: Record<string, any>) {
* @param params
*/
export function modifyBrandSort(params: Record<string, any>) {
return request.put(`shop/goods/brand/sort`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/brand/sort`, params, { showSuccessMessage: true })
}
/**
@ -438,10 +392,7 @@ export function modifyBrandSort(params: Record<string, any>) {
* @returns
*/
export function deleteBrand(brand_id: number) {
return request.delete(`shop/goods/brand/${brand_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/brand/${ brand_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -450,7 +401,7 @@ export function deleteBrand(brand_id: number) {
* @returns
*/
export function getServePageList(params: Record<string, any>) {
return request.get(`shop/goods/service`, { params })
return request.get(`shop/goods/service`, { params })
}
/**
@ -459,7 +410,7 @@ export function getServePageList(params: Record<string, any>) {
* @returns
*/
export function getServeList(params: Record<string, any>) {
return request.get(`shop/goods/service/list`, { params })
return request.get(`shop/goods/service/list`, { params })
}
/**
@ -468,7 +419,7 @@ export function getServeList(params: Record<string, any>) {
* @returns
*/
export function getServeInfo(service_id: number) {
return request.get(`shop/goods/service/${service_id}`)
return request.get(`shop/goods/service/${ service_id }`);
}
/**
@ -477,10 +428,7 @@ export function getServeInfo(service_id: number) {
* @returns
*/
export function addServe(params: Record<string, any>) {
return request.post('shop/goods/service', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/service', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -489,10 +437,10 @@ export function addServe(params: Record<string, any>) {
* @returns
*/
export function editServe(params: Record<string, any>) {
return request.put(`shop/goods/service/${params.service_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/service/${ params.service_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -501,10 +449,7 @@ export function editServe(params: Record<string, any>) {
* @returns
*/
export function deleteServe(service_id: number) {
return request.delete(`shop/goods/service/${service_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/service/${ service_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -512,7 +457,7 @@ export function deleteServe(service_id: number) {
* @returns
*/
export function getCategoryTree() {
return request.get(`shop/goods/tree`)
return request.get(`shop/goods/tree`)
}
/**
@ -521,7 +466,7 @@ export function getCategoryTree() {
* @returns
*/
export function getCategoryList(params: Record<string, any>) {
return request.get(`shop/goods/category`, { params })
return request.get(`shop/goods/category`, { params })
}
/**
@ -530,7 +475,7 @@ export function getCategoryList(params: Record<string, any>) {
* @returns
*/
export function getCategoryInfo(category_id: number) {
return request.get(`shop/goods/category/${category_id}`)
return request.get(`shop/goods/category/${ category_id }`);
}
/**
@ -539,10 +484,7 @@ export function getCategoryInfo(category_id: number) {
* @returns
*/
export function addCategory(params: Record<string, any>) {
return request.post('shop/goods/category', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/category', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -551,10 +493,10 @@ export function addCategory(params: Record<string, any>) {
* @returns
*/
export function editCategory(params: Record<string, any>) {
return request.put(`shop/goods/category/${params.category_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/category/${ params.category_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -563,10 +505,7 @@ export function editCategory(params: Record<string, any>) {
* @returns
*/
export function deleteCategory(category_id: number) {
return request.delete(`shop/goods/category/${category_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/category/${ category_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -575,10 +514,7 @@ export function deleteCategory(category_id: number) {
* @returns
*/
export function updateCategory(params: Record<string, any>) {
return request.post(`shop/goods/category/update`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post(`shop/goods/category/update`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -587,10 +523,7 @@ export function updateCategory(params: Record<string, any>) {
* @returns
*/
export function setCategoryConfig(params: Record<string, any>) {
return request.post(`shop/goods/category/config`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post(`shop/goods/category/config`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -598,7 +531,7 @@ export function setCategoryConfig(params: Record<string, any>) {
* @returns
*/
export function getCategoryConfig() {
return request.get(`shop/goods/category/config`)
return request.get(`shop/goods/category/config`);
}
/**
@ -606,7 +539,7 @@ export function getCategoryConfig() {
* @returns
*/
export function getCategoryTreeComponents() {
return request.get(`shop/goods/category/components`)
return request.get(`shop/goods/category/components`)
}
/**
@ -615,7 +548,7 @@ export function getCategoryTreeComponents() {
* @returns
*/
export function getSupplierList(params: Record<string, any>) {
return request.get(`shop_supplier/supplier/list`, { params })
return request.get(`shop_supplier/supplier/list`, { params })
}
/**
@ -624,7 +557,7 @@ export function getSupplierList(params: Record<string, any>) {
* @returns
*/
export function getEvaluateList(params: Record<string, any>) {
return request.get(`shop/goods/evaluate`, { params })
return request.get(`shop/goods/evaluate`, { params })
}
/**
@ -633,10 +566,7 @@ export function getEvaluateList(params: Record<string, any>) {
* @returns
*/
export function addEvaluate(params: Record<string, any>) {
return request.post('shop/goods/evaluate', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/evaluate', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -645,10 +575,7 @@ export function addEvaluate(params: Record<string, any>) {
* @returns
*/
export function deleteEvaluate(evaluate_id: number) {
return request.delete(`shop/goods/evaluate/${evaluate_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/evaluate/${ evaluate_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -657,10 +584,10 @@ export function deleteEvaluate(evaluate_id: number) {
* @returns
*/
export function adoptEvaluate(evaluate_id: number) {
return request.put(`shop/goods/evaluate/adopt/${evaluate_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/evaluate/adopt/${ evaluate_id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -669,10 +596,10 @@ export function adoptEvaluate(evaluate_id: number) {
* @returns
*/
export function refuseEvaluate(evaluate_id: number) {
return request.put(`shop/goods/evaluate/refuse/${evaluate_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/evaluate/refuse/${ evaluate_id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -681,14 +608,10 @@ export function refuseEvaluate(evaluate_id: number) {
* @returns
*/
export function replyEvaluate(params: Record<string, any>) {
return request.put(
`shop/goods/evaluate/reply/${params.evaluate_id}`,
params,
{
showErrorMessage: true,
showSuccessMessage: true,
}
)
return request.put(`shop/goods/evaluate/reply/${ params.evaluate_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -697,10 +620,10 @@ export function replyEvaluate(params: Record<string, any>) {
* @returns
*/
export function toppingEvaluate(evaluate_id: number) {
return request.put(`shop/goods/evaluate/topping/${evaluate_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/evaluate/topping/${ evaluate_id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -709,10 +632,10 @@ export function toppingEvaluate(evaluate_id: number) {
* @returns
*/
export function cancelToppingEvaluate(evaluate_id: number) {
return request.put(`shop/goods/evaluate/cancel_topping/${evaluate_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/evaluate/cancel_topping/${ evaluate_id }`, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -721,7 +644,7 @@ export function cancelToppingEvaluate(evaluate_id: number) {
* @returns
*/
export function getAttrPageList(params: Record<string, any>) {
return request.get(`shop/goods/attr`, { params })
return request.get(`shop/goods/attr`, { params })
}
/**
@ -730,7 +653,7 @@ export function getAttrPageList(params: Record<string, any>) {
* @returns
*/
export function getAttrList(params: Record<string, any>) {
return request.get(`shop/goods/attr/list`, { params })
return request.get(`shop/goods/attr/list`, { params })
}
/**
@ -739,7 +662,7 @@ export function getAttrList(params: Record<string, any>) {
* @returns
*/
export function getAttrInfo(attr_id: number) {
return request.get(`shop/goods/attr/${attr_id}`)
return request.get(`shop/goods/attr/${ attr_id }`);
}
/**
@ -748,10 +671,7 @@ export function getAttrInfo(attr_id: number) {
* @returns
*/
export function addAttr(params: Record<string, any>) {
return request.post('shop/goods/attr', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/goods/attr', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -760,10 +680,10 @@ export function addAttr(params: Record<string, any>) {
* @returns
*/
export function editAttr(params: Record<string, any>) {
return request.put(`shop/goods/attr/${params.attr_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/attr/${ params.attr_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -772,10 +692,7 @@ export function editAttr(params: Record<string, any>) {
* @returns
*/
export function deleteAttr(attr_id: number) {
return request.delete(`shop/goods/attr/${attr_id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/goods/attr/${ attr_id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -783,9 +700,7 @@ export function deleteAttr(attr_id: number) {
* @param params
*/
export function modifyAttrSort(params: Record<string, any>) {
return request.put(`shop/goods/attr/sort`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/attr/sort`, params, { showSuccessMessage: true })
}
/**
@ -793,9 +708,7 @@ export function modifyAttrSort(params: Record<string, any>) {
* @param params
*/
export function modifyAttrName(params: Record<string, any>) {
return request.put(`shop/goods/attr/attr_name`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/attr/attr_name`, params, { showSuccessMessage: true })
}
/**
@ -803,9 +716,7 @@ export function modifyAttrName(params: Record<string, any>) {
* @param params
*/
export function modifyAttrValue(params: Record<string, any>) {
return request.put(`shop/goods/attr/attr_value`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/attr/attr_value`, params, { showSuccessMessage: true })
}
/**
@ -813,7 +724,7 @@ export function modifyAttrValue(params: Record<string, any>) {
* @returns
*/
export function getGoodsBatchSetDict() {
return request.get(`shop/goods/batchSet/dict`)
return request.get(`shop/goods/batchSet/dict`)
}
/**
@ -821,7 +732,5 @@ export function getGoodsBatchSetDict() {
* @param params
*/
export function goodsBatchSet(params: Record<string, any>) {
return request.put(`shop/goods/batchSet`, params, {
showSuccessMessage: true,
})
}
return request.put(`shop/goods/batchSet`, params, { showSuccessMessage: true })
}

231
admin/src/addon/shop/api/marketing.ts

@ -6,7 +6,7 @@ import request from '@/utils/request'
* @returns
*/
export function getMarketingIndex(params: Record<string, any>) {
return request.get(`shop/marketing`, { params })
return request.get(`shop/marketing`, { params })
}
/**
@ -15,7 +15,7 @@ export function getMarketingIndex(params: Record<string, any>) {
* @returns
*/
export function getGoodsCategoryList(params: Record<string, any>) {
return request.get(`shop/goods/coupon/init`, { params })
return request.get(`shop/goods/coupon/init`, { params })
}
/**
@ -24,10 +24,7 @@ export function getGoodsCategoryList(params: Record<string, any>) {
* @returns
*/
export function addCoupon(params: Record<string, any>) {
return request.post(`shop/goods/coupon`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post(`shop/goods/coupon`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -35,7 +32,7 @@ export function addCoupon(params: Record<string, any>) {
* @returns
*/
export function getCouponStatusList() {
return request.get(`shop/goods/coupon/status`)
return request.get(`shop/goods/coupon/status`)
}
/**
@ -44,7 +41,7 @@ export function getCouponStatusList() {
* @returns
*/
export function getCouponList(params: Record<string, any>) {
return request.get(`shop/goods/coupon`, { params })
return request.get(`shop/goods/coupon`, { params })
}
/**
@ -53,7 +50,7 @@ export function getCouponList(params: Record<string, any>) {
* @returns
*/
export function getCouponSelectList(params: Record<string, any>) {
return request.get(`shop/goods/coupon/select`, { params })
return request.get(`shop/goods/coupon/select`, { params })
}
/**
@ -62,7 +59,7 @@ export function getCouponSelectList(params: Record<string, any>) {
* @returns
*/
export function getCouponRecords(params: Record<string, any>) {
return request.get(`shop/goods/coupon/records`, { params })
return request.get(`shop/goods/coupon/records`, { params });
}
/**
@ -71,7 +68,7 @@ export function getCouponRecords(params: Record<string, any>) {
* @returns
*/
export function getCouponInfo(id: number) {
return request.get(`shop/goods/coupon/detail/${id}`)
return request.get(`shop/goods/coupon/detail/${ id }`);
}
/**
@ -80,9 +77,7 @@ export function getCouponInfo(id: number) {
* @returns
*/
export function editCouponStatus(params: Record<string, any>) {
return request.put(`shop/goods/coupon/setstatus/${params.status}`, params, {
showSuccessMessage: true,
})
return request.put(`shop/goods/coupon/setstatus/${ params.status }`, params, { showSuccessMessage: true })
}
/**
@ -91,10 +86,10 @@ export function editCouponStatus(params: Record<string, any>) {
* @returns
*/
export function editCoupon(params: Record<string, any>) {
return request.put(`shop/goods/coupon/edit/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/coupon/edit/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -103,7 +98,7 @@ export function editCoupon(params: Record<string, any>) {
* @returns
*/
export function deleteCoupon(id: number) {
return request.delete(`shop/goods/coupon/${id}`, { showSuccessMessage: true })
return request.delete(`shop/goods/coupon/${ id }`, { showSuccessMessage: true })
}
/**
@ -112,9 +107,7 @@ export function deleteCoupon(id: number) {
* @returns
*/
export function closeCoupon(id: number) {
return request.put(`shop/goods/coupon/invalid/${id}`, {
showSuccessMessage: true,
})
return request.put(`shop/goods/coupon/invalid/${ id }`, { showSuccessMessage: true })
}
/**
@ -123,7 +116,7 @@ export function closeCoupon(id: number) {
* @returns
*/
export function getSelectedCouponList(params: Record<string, any>) {
return request.get(`shop/goods/coupon/selected`, { params })
return request.get(`shop/goods/coupon/selected`, { params })
}
/************ 限时折扣 ****************/
@ -133,7 +126,7 @@ export function getSelectedCouponList(params: Record<string, any>) {
* @returns
*/
export function getActiveDiscountPageList(params: Record<string, any>) {
return request.get(`shop/active/discount`, { params })
return request.get(`shop/active/discount`, { params })
}
/**
@ -141,7 +134,7 @@ export function getActiveDiscountPageList(params: Record<string, any>) {
* @returns
*/
export function getActiveDiscountStatusList() {
return request.get(`shop/active/status`)
return request.get(`shop/active/status`)
}
/**
@ -150,7 +143,7 @@ export function getActiveDiscountStatusList() {
* @returns
*/
export function getActiveDiscountInfo(active_id: number) {
return request.get(`shop/active/discount/${active_id}`)
return request.get(`shop/active/discount/${ active_id }`);
}
/**
@ -159,10 +152,7 @@ export function getActiveDiscountInfo(active_id: number) {
* @returns
*/
export function addActiveDiscount(params: Record<string, any>) {
return request.post('shop/active/discount', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/active/discount', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -171,10 +161,10 @@ export function addActiveDiscount(params: Record<string, any>) {
* @returns
*/
export function editActiveDiscount(params: Record<string, any>) {
return request.put(`shop/active/discount/${params.active_id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/active/discount/${ params.active_id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -183,14 +173,10 @@ export function editActiveDiscount(params: Record<string, any>) {
* @returns
*/
export function closeActiveDiscount(active_id: number) {
return request.put(
`shop/active/discount/close/${active_id}`,
{},
{
showErrorMessage: true,
showSuccessMessage: true,
}
)
return request.put(`shop/active/discount/close/${ active_id }`, {}, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -199,9 +185,7 @@ export function closeActiveDiscount(active_id: number) {
* @returns
*/
export function deleteActiveDiscount(active_id: number) {
return request.delete(`shop/active/discount/${active_id}`, {
showSuccessMessage: true,
})
return request.delete(`shop/active/discount/${ active_id }`, { showSuccessMessage: true })
}
/**
@ -210,9 +194,7 @@ export function deleteActiveDiscount(active_id: number) {
* @returns
*/
export function getActiveDiscountGoodsPageList(params: Record<string, any>) {
return request.get(`shop/active/discount/goods/${params.active_id}`, {
params,
})
return request.get(`shop/active/discount/goods/${ params.active_id }`, { params })
}
/**
@ -221,9 +203,7 @@ export function getActiveDiscountGoodsPageList(params: Record<string, any>) {
* @returns
*/
export function getActiveDiscountOrderPageList(params: Record<string, any>) {
return request.get(`shop/active/discount/order/${params.active_id}`, {
params,
})
return request.get(`shop/active/discount/order/${ params.active_id }`, { params })
}
/**
@ -232,9 +212,7 @@ export function getActiveDiscountOrderPageList(params: Record<string, any>) {
* @returns
*/
export function getActiveDiscountMemberPageList(params: Record<string, any>) {
return request.get(`shop/active/discount/member/${params.active_id}`, {
params,
})
return request.get(`shop/active/discount/member/${ params.active_id }`, { params })
}
/**
@ -242,7 +220,7 @@ export function getActiveDiscountMemberPageList(params: Record<string, any>) {
* @returns
*/
export function getActiveDiscountConfig() {
return request.get(`shop/active/discount/config`)
return request.get(`shop/active/discount/config`);
}
/**
@ -251,10 +229,10 @@ export function getActiveDiscountConfig() {
* @returns
*/
export function editActiveDiscountConfig(params: Record<string, any>) {
return request.put(`shop/active/discount/config`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/active/discount/config`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/********** 积分商品 ***********/
@ -265,7 +243,7 @@ export function editActiveDiscountConfig(params: Record<string, any>) {
* @returns
*/
export function getActiveExchangePageList(params: Record<string, any>) {
return request.get(`shop/active/exchange`, { params })
return request.get(`shop/active/exchange`, { params })
}
/**
@ -274,7 +252,7 @@ export function getActiveExchangePageList(params: Record<string, any>) {
* @returns
*/
export function getActiveExchangeInfo(id: number) {
return request.get(`shop/active/exchange/${id}`)
return request.get(`shop/active/exchange/${ id }`);
}
/**
@ -283,10 +261,7 @@ export function getActiveExchangeInfo(id: number) {
* @returns
*/
export function addActiveExchange(params: Record<string, any>) {
return request.post('shop/active/exchange', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/active/exchange', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -295,10 +270,10 @@ export function addActiveExchange(params: Record<string, any>) {
* @returns
*/
export function editActiveExchange(params: Record<string, any>) {
return request.put(`shop/active/exchange/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/active/exchange/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -307,10 +282,10 @@ export function editActiveExchange(params: Record<string, any>) {
* @returns
*/
export function editActiveExchangeStatus(params: Record<string, any>) {
return request.put(`shop/active/exchange/status/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/active/exchange/status/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -319,9 +294,7 @@ export function editActiveExchangeStatus(params: Record<string, any>) {
* @returns
*/
export function deleteActiveExchange(id: number) {
return request.delete(`shop/active/exchange/${id}`, {
showSuccessMessage: true,
})
return request.delete(`shop/active/exchange/${ id }`, { showSuccessMessage: true })
}
/**
@ -329,7 +302,7 @@ export function deleteActiveExchange(id: number) {
* @returns
*/
export function getActiveExchangeStatus() {
return request.get(`shop/active/exchange/status`)
return request.get(`shop/active/exchange/status`)
}
/************ 新人专享 ****************/
@ -339,7 +312,7 @@ export function getActiveExchangeStatus() {
* @returns
*/
export function getActiveNewcomerConfig() {
return request.get(`shop/active/newcomer/config`)
return request.get(`shop/active/newcomer/config`);
}
/**
@ -348,10 +321,10 @@ export function getActiveNewcomerConfig() {
* @returns
*/
export function editActiveNewcomerConfig(params: Record<string, any>) {
return request.put(`shop/active/newcomer/config`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/active/newcomer/config`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -360,7 +333,7 @@ export function editActiveNewcomerConfig(params: Record<string, any>) {
* @returns
*/
export function getNewcomerGoodsList(params: Record<string, any>) {
return request.get('shop/active/newcomer/goods/select', { params })
return request.get('shop/active/newcomer/goods/select', { params })
}
/**
@ -369,7 +342,7 @@ export function getNewcomerGoodsList(params: Record<string, any>) {
* @returns
*/
export function getNewcomerSelectGoodsList(params: Record<string, any>) {
return request.get('shop/active/newcomer/goods/selectgoodssku', { params })
return request.get('shop/active/newcomer/goods/selectgoodssku', { params })
}
/************ 商品榜单 ****************/
@ -380,10 +353,7 @@ export function getNewcomerSelectGoodsList(params: Record<string, any>) {
* @returns
*/
export function setRankConfig(params: Record<string, any>) {
return request.post('shop/good/rank/config', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/good/rank/config', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -391,7 +361,7 @@ export function setRankConfig(params: Record<string, any>) {
* @returns
*/
export function getRankConfig() {
return request.get(`shop/good/rank/config`)
return request.get(`shop/good/rank/config`)
}
/**
@ -400,7 +370,7 @@ export function getRankConfig() {
* @returns
*/
export function getRankPageList(params: Record<string, any>) {
return request.get(`shop/good/rank`, { params })
return request.get(`shop/good/rank`, { params })
}
/**
@ -408,7 +378,7 @@ export function getRankPageList(params: Record<string, any>) {
* @returns
*/
export function optionData() {
return request.get(`shop/good/rank/dict`)
return request.get(`shop/good/rank/dict`)
}
/**
@ -417,7 +387,7 @@ export function optionData() {
* @returns
*/
export function getRankInfo(rank_id: number) {
return request.get(`shop/good/rank/${rank_id}`)
return request.get(`shop/good/rank/${ rank_id }`);
}
/**
@ -426,10 +396,7 @@ export function getRankInfo(rank_id: number) {
* @returns
*/
export function addGoodRank(params: Record<string, any>) {
return request.post('shop/good/rank', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/good/rank', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -438,10 +405,10 @@ export function addGoodRank(params: Record<string, any>) {
* @returns
*/
export function editGoodRank(params: Record<string, any>) {
return request.put(`shop/good/rank/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/good/rank/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -450,10 +417,10 @@ export function editGoodRank(params: Record<string, any>) {
* @returns
*/
export function editRankStatus(params: Record<string, any>) {
return request.put(`shop/goods/rank/status`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/goods/rank/status`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -462,7 +429,7 @@ export function editRankStatus(params: Record<string, any>) {
* @returns
*/
export function deleteGoodRank(id: number) {
return request.delete(`shop/good/rank/${id}`, { showSuccessMessage: true })
return request.delete(`shop/good/rank/${ id }`, { showSuccessMessage: true })
}
/**
@ -471,9 +438,7 @@ export function deleteGoodRank(id: number) {
* @returns
*/
export function batchDelete(params: Record<string, any>) {
return request.put(`shop/good/rank/batchDelete`, params, {
showSuccessMessage: true,
})
return request.put(`shop/good/rank/batchDelete`, params, { showSuccessMessage: true })
}
/**
@ -482,9 +447,7 @@ export function batchDelete(params: Record<string, any>) {
* @returns
*/
export function modifyGoodsRankSort(params: Record<string, any>) {
return request.put(`shop/good/rank/sort`, params, {
showSuccessMessage: true,
})
return request.put(`shop/good/rank/sort`, params, { showSuccessMessage: true })
}
/**
@ -493,7 +456,7 @@ export function modifyGoodsRankSort(params: Record<string, any>) {
* @returns
*/
export function getSelectRankPageList(params: Record<string, any>) {
return request.get(`shop/good/rank/select`, { params })
return request.get(`shop/good/rank/select`, { params })
}
/************ 满减 ****************/
@ -504,7 +467,7 @@ export function getSelectRankPageList(params: Record<string, any>) {
* @returns
*/
export function getManjianList(params: Record<string, any>) {
return request.get(`shop/manjian`, { params })
return request.get(`shop/manjian`, { params })
}
/**
@ -512,7 +475,7 @@ export function getManjianList(params: Record<string, any>) {
* @returns
*/
export function getManjianStatusList() {
return request.get(`shop/manjian/status`)
return request.get(`shop/manjian/status`)
}
/**
@ -521,7 +484,7 @@ export function getManjianStatusList() {
* @returns
*/
export function addManjian(params: Record<string, any>) {
return request.post('shop/manjian', params)
return request.post('shop/manjian', params)
}
/**
@ -530,7 +493,7 @@ export function addManjian(params: Record<string, any>) {
* @returns
*/
export function editManjian(params: Record<string, any>) {
return request.put(`shop/manjian/${params.id}`, params)
return request.put(`shop/manjian/${ params.id }`, params)
}
/**
@ -539,7 +502,7 @@ export function editManjian(params: Record<string, any>) {
* @returns
*/
export function getManjianInfo(params: Record<string, any>) {
return request.get(`shop/manjian/init`, { params })
return request.get(`shop/manjian/init`, { params });
}
/**
@ -548,7 +511,7 @@ export function getManjianInfo(params: Record<string, any>) {
* @returns
*/
export function goodsCheck(params: Record<string, any>) {
return request.post('shop/manjian/goods/check', params)
return request.post('shop/manjian/goods/check', params)
}
/**
@ -557,7 +520,7 @@ export function goodsCheck(params: Record<string, any>) {
* @returns
*/
export function getManjianMemberPageList(params: Record<string, any>) {
return request.get(`shop/manjian/member/${params.id}`, { params })
return request.get(`shop/manjian/member/${ params.id }`, { params })
}
/**
@ -566,14 +529,10 @@ export function getManjianMemberPageList(params: Record<string, any>) {
* @returns
*/
export function closeManjian(manjian_id: number) {
return request.put(
`shop/manjian/close/${manjian_id}`,
{},
{
showErrorMessage: true,
showSuccessMessage: true,
}
)
return request.put(`shop/manjian/close/${ manjian_id }`, {}, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
@ -582,7 +541,7 @@ export function closeManjian(manjian_id: number) {
* @returns
*/
export function getGoodsSelectByReplaceBuy(params: Record<string, any>) {
return request.get(`shop/goods/buy/goods/select`, { params })
return request.get(`shop/goods/buy/goods/select`, { params })
}
/**
@ -591,7 +550,7 @@ export function getGoodsSelectByReplaceBuy(params: Record<string, any>) {
* @returns
*/
export function getGoodsSelectedByReplaceBuy(params: Record<string, any>) {
return request.get(`shop/goods/buy/goods/selected`, { params })
return request.get(`shop/goods/buy/goods/selected`, { params })
}
/**
@ -600,7 +559,7 @@ export function getGoodsSelectedByReplaceBuy(params: Record<string, any>) {
* @returns
*/
export function getGoodsSkuInfo(params: Record<string, any>) {
return request.get(`shop/goods/buy/sku/select`, { params })
return request.get(`shop/goods/buy/sku/select`, { params })
}
/*
@ -609,9 +568,7 @@ export function getGoodsSkuInfo(params: Record<string, any>) {
* @returns
*/
export function deleteManjian(manjian_id: number) {
return request.delete(`shop/manjian/${manjian_id}`, {
showSuccessMessage: true,
})
return request.delete(`shop/manjian/${ manjian_id }`, { showSuccessMessage: true })
}
/**
@ -620,9 +577,7 @@ export function deleteManjian(manjian_id: number) {
* @returns
*/
export function batchDeleteManjian(params: Record<string, any>) {
return request.put(`shop/manjian/goods/batchDelete`, params, {
showSuccessMessage: true,
})
return request.put(`shop/manjian/goods/batchDelete`, params, { showSuccessMessage: true })
}
/**
@ -631,7 +586,5 @@ export function batchDeleteManjian(params: Record<string, any>) {
* @returns
*/
export function batchCloseMajian(params: Record<string, any>) {
return request.put(`shop/manjian/goods/batchClose`, params, {
showSuccessMessage: true,
})
return request.put(`shop/manjian/goods/batchClose`, params, { showSuccessMessage: true })
}

77
admin/src/addon/shop/api/order.ts

@ -5,7 +5,7 @@ import request from '@/utils/request'
* @returns
*/
export function getConfig() {
return request.get('shop/order/config')
return request.get('shop/order/config')
}
/**
@ -13,7 +13,7 @@ export function getConfig() {
* @returns
*/
export function setConfig(param: any) {
return request.post('shop/order/config', param, { showSuccessMessage: true })
return request.post('shop/order/config', param, { showSuccessMessage: true })
}
/**
@ -21,7 +21,7 @@ export function setConfig(param: any) {
* @returns
*/
export function getOrderList(params: Record<string, any>) {
return request.get('shop/order/list', { params })
return request.get('shop/order/list', { params })
}
/**
@ -29,7 +29,7 @@ export function getOrderList(params: Record<string, any>) {
* @returns
*/
export function getOrderDetail(order_id: number) {
return request.get(`shop/order/detail/${order_id}`)
return request.get(`shop/order/detail/${ order_id }`)
}
/**
@ -37,7 +37,7 @@ export function getOrderDetail(order_id: number) {
* @return
*/
export function getOrderStatus() {
return request.get(`shop/order/status`)
return request.get(`shop/order/status`)
}
/**
@ -45,7 +45,7 @@ export function getOrderStatus() {
* @return
*/
export function getOrderType() {
return request.get(`shop/order/type`)
return request.get(`shop/order/type`)
}
/**
@ -53,7 +53,7 @@ export function getOrderType() {
* @return
*/
export function orderClose(order_id: number) {
return request.put(`shop/order/close/${order_id}`)
return request.put(`shop/order/close/${ order_id }`)
}
/**
@ -61,7 +61,7 @@ export function orderClose(order_id: number) {
* @return
*/
export function getOrderDeliveryType(params: Record<string, any>) {
return request.get(`shop/order/delivery_type`, { params })
return request.get(`shop/order/delivery_type`, { params })
}
/**
@ -69,7 +69,7 @@ export function getOrderDeliveryType(params: Record<string, any>) {
* @return
*/
export function orderDelivery(params: Record<string, any>) {
return request.put(`shop/order/delivery`, params)
return request.put(`shop/order/delivery`, params)
}
/**
@ -77,7 +77,7 @@ export function orderDelivery(params: Record<string, any>) {
* @return
*/
export function setShopRemark(params: Record<string, any>) {
return request.put(`shop/order/shop_remark`, params)
return request.put(`shop/order/shop_remark`, params)
}
/**
@ -85,7 +85,7 @@ export function setShopRemark(params: Record<string, any>) {
* @return
*/
export function orderFinish(order_id: number) {
return request.put(`shop/order/finish/${order_id}`)
return request.put(`shop/order/finish/${ order_id }`)
}
/**
@ -93,7 +93,7 @@ export function orderFinish(order_id: number) {
* @return
*/
export function deliveryPackage(params: Record<string, any>) {
return request.get(`shop/order/delivery/package`, { params })
return request.get(`shop/order/delivery/package`, { params })
}
/**
@ -101,7 +101,7 @@ export function deliveryPackage(params: Record<string, any>) {
* @return
*/
export function deliveryPackageList(params: Record<string, any>) {
return request.get(`shop/order/delivery/package/list`, { params })
return request.get(`shop/order/delivery/package/list`, { params })
}
/**
@ -110,14 +110,14 @@ export function deliveryPackageList(params: Record<string, any>) {
* @return
*/
export function orderRefund(params: Record<string, any>) {
return request.get(`shop/order/refund`, { params })
return request.get(`shop/order/refund`, { params })
}
/**
* 退
*/
export function orderRefundDetail(refund_id: number) {
return request.get(`shop/order/refund/${refund_id}`)
return request.get(`shop/order/refund/${ refund_id }`)
}
/**
@ -125,10 +125,7 @@ export function orderRefundDetail(refund_id: number) {
* @return
*/
export function auditRefund(params: Record<string, any>) {
return request.put(
`shop/order/refund/audit/${params.order_refund_no}`,
params
)
return request.put(`shop/order/refund/audit/${ params.order_refund_no }`, params)
}
/**
@ -136,61 +133,56 @@ export function auditRefund(params: Record<string, any>) {
* @return
*/
export function refundDelivery(params: Record<string, any>) {
return request.put(
`shop/order/refund/delivery/${params.order_refund_no}`,
params
)
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 })
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,
})
return request.post(`shop/order/refund/active`, params, { showSuccessMessage: true })
}
/**
*
*/
export function getInvoiceList(params: Record<string, any>) {
return request.get(`shop/invoice`, { params })
return request.get(`shop/invoice`, { params })
}
/**
*
*/
export function getInvoiceDetail(id: number) {
return request.get(`shop/invoice/${id}`)
return request.get(`shop/invoice/${ id }`)
}
/**
*
*/
export function setInvoice(id: number, params: Record<string, any>) {
return request.put(`shop/invoice/${id}`, params, { showSuccessMessage: true })
return request.put(`shop/invoice/${ id }`, params, { showSuccessMessage: true })
}
/**
*
*/
export function getOrderPayType() {
return request.get(`shop/order/pay/type`)
return request.get(`shop/order/pay/type`)
}
/**
*
*/
export function getOrderFrom() {
return request.get(`shop/order/from`)
return request.get(`shop/order/from`)
}
/**
@ -198,9 +190,7 @@ export function getOrderFrom() {
* @return
*/
export function orderEditPrice(params: Record<string, any>) {
return request.put(`shop/order/edit_price`, params, {
showSuccessMessage: true,
})
return request.put(`shop/order/edit_price`, params, { showSuccessMessage: true })
}
/**
@ -208,7 +198,7 @@ export function orderEditPrice(params: Record<string, any>) {
* @return
*/
export function getOrderEditAddress(params: Record<string, any>) {
return request.get(`shop/order/edit_delivery`, { params })
return request.get(`shop/order/edit_delivery`, { params })
}
/**
@ -216,7 +206,7 @@ export function getOrderEditAddress(params: Record<string, any>) {
* @return
*/
export function getDeliveryList() {
return request.get(`shop/delivery/store/list`)
return request.get(`shop/delivery/store/list`)
}
/**
@ -224,7 +214,7 @@ export function getDeliveryList() {
* @return
*/
export function orderEditAddress(params: Record<string, any>) {
return request.put(`shop/order/edit_delivery`, params)
return request.put(`shop/order/edit_delivery`, params)
}
/**
@ -232,7 +222,7 @@ export function orderEditAddress(params: Record<string, any>) {
* @return
*/
export function getOrderBatchDeliveryList(params: Record<string, any>) {
return request.get(`shop/order_batch_delivery`, { params })
return request.get(`shop/order_batch_delivery`, { params })
}
/**
@ -240,10 +230,7 @@ export function getOrderBatchDeliveryList(params: Record<string, any>) {
* @return
*/
export function addBatchOrderDelivery(params: Record<string, any>) {
return request.put(
`shop/order_batch_delivery/add_batch_order_delivery`,
params
)
return request.put(`shop/order_batch_delivery/add_batch_order_delivery`, params)
}
/**
@ -251,7 +238,7 @@ export function addBatchOrderDelivery(params: Record<string, any>) {
* @return
*/
export function getOrderBatchDeliveryState() {
return request.get(`shop/order_batch_delivery/get_status`)
return request.get(`shop/order_batch_delivery/get_status`)
}
/**
@ -259,5 +246,5 @@ export function getOrderBatchDeliveryState() {
* @return
*/
export function getOrderBatchDeliveryType() {
return request.get(`shop/order_batch_delivery/get_type`)
return request.get(`shop/order_batch_delivery/get_type`)
}

12
admin/src/addon/shop/api/shop.ts

@ -4,40 +4,40 @@ import request from '@/utils/request'
*
*/
export function getShopCountList() {
return request.get(`shop/stat/total`)
return request.get(`shop/stat/total`)
}
/**
*
*/
export function getShopTodayCountList() {
return request.get(`shop/stat/today`)
return request.get(`shop/stat/today`)
}
/**
*
*/
export function getShopYesterdayCountList() {
return request.get(`shop/stat/yesterday`)
return request.get(`shop/stat/yesterday`)
}
/**
*
*/
export function getShopStat() {
return request.get(`shop/stat`)
return request.get(`shop/stat`)
}
/**
*
*/
export function getShopOrderStat() {
return request.get(`shop/stat/order`)
return request.get(`shop/stat/order`)
}
/**
*
*/
export function getShopGoodsStat() {
return request.get(`shop/stat/goods`)
return request.get(`shop/stat/goods`)
}

25
admin/src/addon/shop/api/shop_address.ts

@ -6,7 +6,7 @@ import request from '@/utils/request'
* @returns
*/
export function getShopAddressList(params: Record<string, any>) {
return request.get(`shop/shop_address`, { params })
return request.get(`shop/shop_address`, { params })
}
/**
@ -15,7 +15,7 @@ export function getShopAddressList(params: Record<string, any>) {
* @returns
*/
export function getShopAddressInfo(id: number) {
return request.get(`shop/shop_address/${id}`)
return request.get(`shop/shop_address/${ id }`);
}
/**
@ -24,10 +24,7 @@ export function getShopAddressInfo(id: number) {
* @returns
*/
export function addShopAddress(params: Record<string, any>) {
return request.post('shop/shop_address', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('shop/shop_address', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -36,10 +33,7 @@ export function addShopAddress(params: Record<string, any>) {
* @returns
*/
export function editShopAddress(params: Record<string, any>) {
return request.put(`shop/shop_address/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`shop/shop_address/${ params.id }`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -48,10 +42,7 @@ export function editShopAddress(params: Record<string, any>) {
* @returns
*/
export function deleteShopAddress(id: number) {
return request.delete(`shop/shop_address/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`shop/shop_address/${ id }`, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -59,7 +50,7 @@ export function deleteShopAddress(id: number) {
* @returns
*/
export function getShopDefaultDeliveryAddressInfo() {
return request.get('shop/shop_address/default/delivery')
return request.get('shop/shop_address/default/delivery');
}
/**
@ -67,5 +58,5 @@ export function getShopDefaultDeliveryAddressInfo() {
* @returns
*/
export function getOrderRefundAddress() {
return request.get('shop/order/refund/address')
}
return request.get('shop/order/refund/address');
}

8
admin/src/addon/shop/api/stat.ts

@ -4,7 +4,7 @@ import request from '@/utils/request'
* @returns
*/
export function getGoodsStatisticsBasic(params: Record<string, any>) {
return request.get('shop/goods/statistics/basic', { params })
return request.get('shop/goods/statistics/basic', { params })
}
/**
@ -12,13 +12,13 @@ export function getGoodsStatisticsBasic(params: Record<string, any>) {
* @returns
*/
export function getGoodsStatisticsTrend(params: Record<string, any>) {
return request.get('shop/goods/statistics/trend', { params })
return request.get('shop/goods/statistics/trend', { params })
}
/**
*
*/
export function getGoodsStatisticsType() {
return request.get(`shop/goods/statistics/type`)
return request.get(`shop/goods/statistics/type`)
}
/**
@ -26,5 +26,5 @@ export function getGoodsStatisticsType() {
* @returns
*/
export function getGoodsStatisticsRank(params: Record<string, any>) {
return request.get('shop/goods/statistics/rank', { params })
return request.get('shop/goods/statistics/rank', { params })
}

68
admin/src/addon/shop/lang/zh-cn/address.edit.json

@ -1,35 +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": "至少需设置一项类型"
}
"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": "至少需设置一项类型"
}

2
admin/src/addon/shop/lang/zh-cn/address.list.json

@ -22,4 +22,4 @@
"deliveryAddress": "发货地址",
"refundAddress": "收货地址",
"default": "默认"
}
}

58
admin/src/addon/shop/lang/zh-cn/common.json

@ -88,41 +88,41 @@
"goodsSearchSet": "搜索设置",
"goodsSearchText": "搜索内容",
"goodsSearchTextPlaceholder": "请输入搜索内容",
"shopMemberInfoComponentUidTextColor": "编号颜色",
"shopMemberInfoComponentAccount": "账号信息",
"shopGoodsRecommendComponentTag": "标签",
"shopGoodsRecommendComponentTagcolor": "标签颜色",
"shopGoodsRecommendComponentTagPlaceholder": "请输入标签内容",
"shopGoodsRecommendComponentButtonBorderColor": "按钮边框颜色",
"carouselStyle": "轮播样式",
"recommendIndicatorStyle": "指示器设置",
"recommendIndicatorColor": "常规颜色",
"recommendIndicatorActiveColor": "选中颜色",
"activeCubeBlockContent": "板块内容",
"bgImage": "背景图片",
"rankingTitleIcon": "图标",
"rankSelect": "榜单选择",
"rankName": "榜单名称",
"rankNamePlaceholder": "请输入榜单名称",
"showGoodsNum": "榜单商品数量",
"goodsSourceName": "商品来源",
"ruleTypeName": "排序规则",
"rankTypeName": "排行周期",
"shopMemberInfoComponentUidTextColor":"编号颜色",
"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": "下圆角",
"rankingTitleImage":"头部图片" ,
"rankingSubTitle":"副标题",
"rankingSubTitleTextColor":"副标题颜色",
"rankTextColor":"名称颜色",
"rankingSubTitleLink":"副标题链接",
"listFrameColor":"背景颜色",
"topRounded":"上圆角",
"bottomRounded":"下圆角",
"rankingStyle": "板块样式",
"styleRecommend": "风格推荐",
"countDownStyle": "倒计时样式",
"newcomerNumberColor": "数字颜色",
"newcomerNumberBg": "数字背景色",
"newcomerOtherColor": "文字颜色"
}
}

38
admin/src/addon/shop/lang/zh-cn/delivery.company.json

@ -1,20 +1,20 @@
{
"companyId": "",
"companyIdPlaceholder": "请输入",
"companyName": "名称",
"companyNamePlaceholder": "请输入物流公司名称",
"logo": "LOGO",
"logoPlaceholder": "请输入物流公司logo",
"url": "网址",
"urlPlaceholder": "请输入物流公司网址",
"expressNoPlaceholder": "请输入物流公司编号",
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
"expressNoKd100": "快递100编码",
"expressNoKd100Placeholder": "请输入快递100编码",
"addCompany": "添加物流公司",
"updateCompany": "编辑物流公司",
"electronicSheetSwitchName": "是否支持电子面单",
"expressNoElectronicSheet": "电子面单编号",
"expressNo": "物流跟踪编号",
"companyDeleteTips": "确定要删除该数据吗?"
}
"companyId":"",
"companyIdPlaceholder":"请输入",
"companyName":"名称",
"companyNamePlaceholder":"请输入物流公司名称",
"logo":"LOGO",
"logoPlaceholder":"请输入物流公司logo",
"url":"网址",
"urlPlaceholder":"请输入物流公司网址",
"expressNoPlaceholder":"请输入物流公司编号",
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
"expressNoKd100":"快递100编码",
"expressNoKd100Placeholder":"请输入快递100编码",
"addCompany":"添加物流公司",
"updateCompany":"编辑物流公司",
"electronicSheetSwitchName": "是否支持电子面单",
"expressNoElectronicSheet":"电子面单编号",
"expressNo":"物流跟踪编号",
"companyDeleteTips":"确定要删除该数据吗?"
}

85
admin/src/addon/shop/lang/zh-cn/delivery.company_edit.json

@ -1,43 +1,44 @@
{
"companyId": "",
"companyIdPlaceholder": "请输入",
"companyName": "名称",
"companyNamePlaceholder": "请输入物流公司名称",
"logo": "LOGO",
"logoPlaceholder": "请输入物流公司logo",
"url": "网址",
"urlPlaceholder": "请输入物流公司网址",
"expressNo": "物流跟踪编号",
"expressNoPlaceholder": "请输入物流公司编号",
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
"expressNoKd100": "快递100编码",
"expressNoKd100Placeholder": "请输入快递100编码",
"addCompany": "添加物流公司",
"updateCompany": "编辑物流公司",
"expressNoElectronicSheet": "电子面单编号",
"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": "点击查看"
}
"companyId":"",
"companyIdPlaceholder":"请输入",
"companyName":"名称",
"companyNamePlaceholder":"请输入物流公司名称",
"logo":"LOGO",
"logoPlaceholder":"请输入物流公司logo",
"url":"网址",
"urlPlaceholder":"请输入物流公司网址",
"expressNo":"物流跟踪编号",
"expressNoPlaceholder":"请输入物流公司编号",
"expressNoTips": "物流公司编号作用于物流查询,请根据物流跟踪对应配置设置编号",
"expressNoKd100":"快递100编码",
"expressNoKd100Placeholder":"请输入快递100编码",
"addCompany":"添加物流公司",
"updateCompany":"编辑物流公司",
"expressNoElectronicSheet":"电子面单编号",
"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": "点击查看"
}

20
admin/src/addon/shop/lang/zh-cn/delivery.config.json

@ -1,11 +1,11 @@
{
"store": "启动门店自提后,买家可选择自提点提货。",
"express": "启用物流配送后,买家下单可以选择快递发货。",
"local_delivery": "启用同城配送后,在配送范围内的买家可以选择同城配送。",
"deliveryStaff": "配送员",
"deliveryCompany": "物流公司",
"deliveryTemplate": "运费模版",
"deliverySearch": "物流跟踪",
"deliveryStore": "自提点",
"localConfig": "同城配送设置"
}
"store":"启动门店自提后,买家可选择自提点提货。",
"express":"启用物流配送后,买家下单可以选择快递发货。",
"local_delivery":"启用同城配送后,在配送范围内的买家可以选择同城配送。",
"deliveryStaff":"配送员",
"deliveryCompany":"物流公司",
"deliveryTemplate":"运费模版",
"deliverySearch":"物流跟踪",
"deliveryStore":"自提点",
"localConfig": "同城配送设置"
}

2
admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet.json

@ -14,4 +14,4 @@
"setDefault": "设为默认",
"electronicSheetDeleteTips": "确定要删除该数据吗?",
"electronicSheetSetDefaultTips": "确定要设置为默认模版吗?"
}
}

2
admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet_config.json

@ -18,4 +18,4 @@
"serverPort2Placeholder": "请输入服务器端口2",
"httpsPort": "HTTPS端口",
"httpsPortPlaceholder": "请输入HTTPS端口"
}
}

2
admin/src/addon/shop/lang/zh-cn/delivery.electronic_sheet_edit.json

@ -31,4 +31,4 @@
"examine": "点击查看",
"customerNameTips": "快递鸟电子面单账号申请",
"customerNameTips1": "电子面单账号对照表"
}
}

108
admin/src/addon/shop/lang/zh-cn/delivery.local.json

@ -1,55 +1,55 @@
{
"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": "取货地址已变更请注意是否需重新调整配送区域"
}
"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": "取货地址已变更请注意是否需重新调整配送区域"
}

38
admin/src/addon/shop/lang/zh-cn/delivery.search.json

@ -1,20 +1,20 @@
{
"prompt": "提示",
"promptTips1-1": "请到快递鸟官网申请",
"promptTips1-2": "快递鸟接口:目前只支持“申通,圆通、百世,极兔”免费查询。",
"promptTips2": "请到快递100官网申请",
"interfaceType": "接口类型",
"kdn": "快递鸟",
"kd100": "快递100",
"kdnEBusinessIDPlaceholder": "请输入快递鸟EBusinessID",
"kdnEBusinessIDTips": "快递鸟电商ID",
"kdnAppKeyPlaceholder": "请输入快递鸟AppKey",
"kdnAppKeyTips": "快递鸟分配的电商加密私钥",
"isPayEdition": "快递鸟套餐",
"free": "免费",
"pay": "付费",
"kd100AppKeyPlaceholder": "请输入快递100AppKey",
"kd100AppKeyTips": "快递100应用密钥",
"kd100CustomerPlaceholder": "请输入快递100Customer",
"kd100CustomerTips": "快递100分配给的公司编号"
}
"prompt": "提示",
"promptTips1-1": "请到快递鸟官网申请",
"promptTips1-2": "快递鸟接口:目前只支持“申通,圆通、百世,极兔”免费查询。",
"promptTips2": "请到快递100官网申请",
"interfaceType": "接口类型",
"kdn": "快递鸟",
"kd100": "快递100",
"kdnEBusinessIDPlaceholder": "请输入快递鸟EBusinessID",
"kdnEBusinessIDTips": "快递鸟电商ID",
"kdnAppKeyPlaceholder": "请输入快递鸟AppKey",
"kdnAppKeyTips": "快递鸟分配的电商加密私钥",
"isPayEdition": "快递鸟套餐",
"free": "免费",
"pay": "付费",
"kd100AppKeyPlaceholder": "请输入快递100AppKey",
"kd100AppKeyTips": "快递100应用密钥",
"kd100CustomerPlaceholder": "请输入快递100Customer",
"kd100CustomerTips": "快递100分配给的公司编号"
}

16
admin/src/addon/shop/lang/zh-cn/delivery.staff.json

@ -1,9 +1,9 @@
{
"addDeliveryPersonnel": "添加配送员",
"updateDeliver": "编辑配送员",
"deliverName": "配送员名称",
"deliverMobile": "配送员手机号",
"deliverNamePlaceholder": "请输入配送员名称",
"deliverMobilePlaceholder": "请输入配送员手机号",
"deliverDeleteTips": "确定要删除该数据吗?"
}
"addDeliveryPersonnel":"添加配送员",
"updateDeliver":"编辑配送员",
"deliverName":"配送员名称",
"deliverMobile":"配送员手机号",
"deliverNamePlaceholder":"请输入配送员名称",
"deliverMobilePlaceholder":"请输入配送员手机号",
"deliverDeleteTips":"确定要删除该数据吗?"
}

34
admin/src/addon/shop/lang/zh-cn/delivery.store.json

@ -1,18 +1,18 @@
{
"storeId": "",
"storeName": "自提点信息",
"storeNamePlaceholder": "请输入自提点名称",
"storeLogo": "自提点logo",
"storeMobile": "联系电话",
"address": "详细地址",
"fullAddress": "联系地址",
"longitude": "经度",
"latitude": "纬度",
"tradeTime": "营业时间",
"createTime": "添加时间",
"createTimePlaceholder": "请输入添加时间",
"addStore": "添加自提点",
"updateStore": "编辑自提点",
"storeDeleteTips": "确定要删除该数据吗?",
"storeInfo": "自提点信息"
}
"storeId":"",
"storeName":"自提点信息",
"storeNamePlaceholder":"请输入自提点名称",
"storeLogo":"自提点logo",
"storeMobile":"联系电话",
"address":"详细地址",
"fullAddress":"联系地址",
"longitude":"经度",
"latitude":"纬度",
"tradeTime":"营业时间",
"createTime":"添加时间",
"createTimePlaceholder":"请输入添加时间",
"addStore":"添加自提点",
"updateStore":"编辑自提点",
"storeDeleteTips":"确定要删除该数据吗?",
"storeInfo": "自提点信息"
}

74
admin/src/addon/shop/lang/zh-cn/delivery.store_edit.json

@ -1,38 +1,38 @@
{
"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": "请输入自提点详细地址"
}
"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": "请输入自提点详细地址"
}

22
admin/src/addon/shop/lang/zh-cn/delivery.template.json

@ -1,12 +1,12 @@
{
"templateName": "运费模板名称",
"templateNamePlaceholder": "请输入运费模板名称",
"createTime": "创建时间",
"addTemplate": "添加运费模板",
"updateTemplate": "编辑运费模板",
"templateDeleteTips": "确定要删除该模板吗?",
"feeTypeName": "计费类型",
"freeShipping": "指定区域包邮",
"open": "启用",
"close": "关闭"
}
"templateName":"运费模板名称",
"templateNamePlaceholder":"请输入运费模板名称",
"createTime":"创建时间",
"addTemplate":"添加运费模板",
"updateTemplate":"编辑运费模板",
"templateDeleteTips":"确定要删除该模板吗?",
"feeTypeName": "计费类型",
"freeShipping": "指定区域包邮",
"open": "启用",
"close": "关闭"
}

76
admin/src/addon/shop/lang/zh-cn/delivery.template_edit.json

@ -1,39 +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"
}
"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"
}

4
admin/src/addon/shop/lang/zh-cn/goods.attr.json

@ -5,6 +5,6 @@
"addShopGoodsAttr": "添加参数模板",
"updateShopGoodsAttr": "编辑参数模板",
"goodsAttrDeleteTips": "确定要删除该数据吗?",
"sortTips": "排序号格式输入错误",
"sortTips":"排序号格式输入错误",
"manage": "管理"
}
}

2
admin/src/addon/shop/lang/zh-cn/goods.attr_edit.json

@ -15,4 +15,4 @@
"attrValueName": "参数名称",
"addAttrValue": "添加参数",
"attrValueNamePlaceholder": "请输入参数名称"
}
}

28
admin/src/addon/shop/lang/zh-cn/goods.brand_list.json

@ -1,15 +1,15 @@
{
"brandId": "品牌ID",
"brandIdPlaceholder": "请输入品牌ID",
"brandName": "品牌名称",
"brandNamePlaceholder": "请输入品牌名称",
"logo": "品牌logo",
"logoPlaceholder": "请输入品牌logo",
"desc": "品牌介绍",
"descPlaceholder": "请输入品牌介绍",
"sort": "排序",
"sortPlaceholder": "请输入排序",
"addBrand": "添加商品品牌",
"updateBrand": "编辑商品品牌",
"brandDeleteTips": "确定要删除该数据吗?"
}
"brandId":"品牌ID",
"brandIdPlaceholder":"请输入品牌ID",
"brandName":"品牌名称",
"brandNamePlaceholder":"请输入品牌名称",
"logo":"品牌logo",
"logoPlaceholder":"请输入品牌logo",
"desc":"品牌介绍",
"descPlaceholder":"请输入品牌介绍",
"sort":"排序",
"sortPlaceholder":"请输入排序",
"addBrand":"添加商品品牌",
"updateBrand":"编辑商品品牌",
"brandDeleteTips":"确定要删除该数据吗?"
}

50
admin/src/addon/shop/lang/zh-cn/goods.category.json

@ -1,26 +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": "分类设置"
}
"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": "分类设置"
}

52
admin/src/addon/shop/lang/zh-cn/goods.category_config.json

@ -1,27 +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": "分类设置"
}
"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": "分类设置"
}

96
admin/src/addon/shop/lang/zh-cn/goods.evaluate.json

@ -1,49 +1,49 @@
{
"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": "请上传会员头像"
}
"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": "请上传会员头像"
}

72
admin/src/addon/shop/lang/zh-cn/goods.evaluate_edit.json

@ -1,37 +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": "确定要删除该商品评价吗?"
}
"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":"确定要删除该商品评价吗?"
}

2
admin/src/addon/shop/lang/zh-cn/goods.label_group_list.json

@ -9,4 +9,4 @@
"updateLabelGroup": "编辑标签分组",
"sortTips": "排序号格式输入错误",
"labelGroupDeleteTips": "确定要删除该数据吗?"
}
}

2
admin/src/addon/shop/lang/zh-cn/goods.label_list.json

@ -27,4 +27,4 @@
"status": "状态",
"label": "标签",
"createTime": "创建时间"
}
}

13
admin/src/addon/shop/lang/zh-cn/goods.list.json

@ -14,13 +14,13 @@
"startSaleNumTips": "最低销量输入错误",
"endSaleNumPlaceholder": "最高销量",
"endSaleNumTips": "最高销量输入错误",
"shopSaleNumTips": "最低销量不能大于最高销量",
"shopSaleNumTips":"最低销量不能大于最高销量",
"skuPrice": "价格",
"startPricePlaceholder": "最低价格",
"startPriceTips": "最低价格输入错误",
"endPricePlaceholder": "最高价格",
"endPriceTips": "最高价格输入错误",
"shopPriceTips": "最低价格不能大于最高价格",
"shopPriceTips":"最低价格不能大于最高价格",
"statusOn": "销售中",
"statusOff": "仓库中",
"statusAll": "全部商品",
@ -40,7 +40,7 @@
"addGoods": "添加商品",
"statusActionOn": "上架",
"statusActionOff": "下架",
"statusChangeTips": "确定要下架该商品吗?",
"statusChangeTips":"确定要下架该商品吗?",
"spreadGoods": "推广",
"copyGoods": "复制",
@ -105,6 +105,7 @@
"discountHint": "会员折扣说明:按照默认会员等级折扣优惠",
"fixedPriceHint": "会员价说明:指定优惠价格,商品未参与活动时,按照会员价优惠,若商品参与活动,则以活动价为准",
"addGoodsLabel": "添加商品标签",
"addGoodsService": "添加商品服务",
"addGoodsCategory": "添加分类",
@ -132,9 +133,9 @@
"addDeliveryTemplateId": "添加运费模板",
"deliveryType": "配送方式",
"deliveryTypePlaceholder": "请选择配送方式",
"yuan": "元",
"label": "商品标签",
"service": "商品服务",
"yuan":"元",
"label":"商品标签",
"service":"商品服务",
"virtualSaleNum": "虚拟销量",
"goodsBrand": "商品品牌",
"goodsPoster": "商品海报",

30
admin/src/addon/shop/lang/zh-cn/goods.real_edit.json

@ -11,9 +11,9 @@
"subTitlePlaceholder": "请输入副标题",
"subTitleMaxLengthTips": "副标题不能超过80个字符",
"goodsImage": "商品图片",
"goodsImagePlaceholder": "请上传商品图片",
"goodsImagePlaceholder":"请上传商品图片",
"goodsVideo": "商品视频",
"goodsVideoPlaceholder": "请上传商品视频",
"goodsVideoPlaceholder":"请上传商品视频",
"goodsCategory": "商品分类",
"refresh": "刷新",
"addGoodsCategory": "添加分类",
@ -87,21 +87,21 @@
"deliveryTab": "配送设置",
"deliveryType": "配送方式",
"deliveryTypePlaceholder": "请选择配送方式",
"pleaseSelectSku": "请先选择商品规格",
"isLimit": "是否限购",
"isLimitTips": "启用限购后,购买商品时,会对该商品购买量做限制判断。",
"limitType": "限购类型",
"limitTypeTips": "单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
"singleTime": "单次限购",
"singlePerson": "单人限购",
"maxBuy": "限购数量",
"maxBuyPlaceholder": "请输入限购数量",
"pleaseSelectSku":"请先选择商品规格",
"isLimit":"是否限购",
"isLimitTips":"启用限购后,购买商品时,会对该商品购买量做限制判断。",
"limitType":"限购类型",
"limitTypeTips":"单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
"singleTime":"单次限购",
"singlePerson":"单人限购",
"maxBuy":"限购数量",
"maxBuyPlaceholder":"请输入限购数量",
"maxBuyTips": "[限购数量]格式输入错误",
"maxBuyWarnTips": "限购数量超出商品库存时,买家将无法购买该商品",
"maxBuyWarnTips":"限购数量超出商品库存时,买家将无法购买该商品",
"maxBuyNotZeroTips": "限购数量不能小于1",
"minBuy": "起购数量",
"minBuyTips": "起购数量超出商品库存时,买家将无法购买该商品",
"minBuyFormatErrorTips": "[起购数量]格式输入错误",
"minBuy":"起购数量",
"minBuyTips":"起购数量超出商品库存时,买家将无法购买该商品",
"minBuyFormatErrorTips":"[起购数量]格式输入错误",
"minBuyNotZeroTips": "起购数量不能小于0",
"minBuyGreaterThanMaxBuyTips": "起购数量不能大于限购数量",

18
admin/src/addon/shop/lang/zh-cn/goods.service.json

@ -1,10 +1,10 @@
{
"serviceName": "服务名称",
"serviceNamePlaceholder": "请输入服务名称",
"desc": "描述",
"descPlaceholder": "请输入描述",
"addServe": "添加商品服务",
"updateServe": "编辑商品服务",
"serveDeleteTips": "确定要删除该数据吗?",
"imagePlaceholder": "请上传服务图片"
}
"serviceName":"服务名称",
"serviceNamePlaceholder":"请输入服务名称",
"desc":"描述",
"descPlaceholder":"请输入描述",
"addServe":"添加商品服务",
"updateServe":"编辑商品服务",
"serveDeleteTips":"确定要删除该数据吗?",
"imagePlaceholder": "请上传服务图片"
}

30
admin/src/addon/shop/lang/zh-cn/goods.virtual_edit.json

@ -11,9 +11,9 @@
"subTitlePlaceholder": "请输入副标题",
"subTitleMaxLengthTips": "副标题不能超过80个字符",
"goodsImage": "商品图片",
"goodsImagePlaceholder": "请上传商品图片",
"goodsImagePlaceholder":"请上传商品图片",
"goodsVideo": "商品视频",
"goodsVideoPlaceholder": "请上传商品视频",
"goodsVideoPlaceholder":"请上传商品视频",
"goodsCategory": "商品分类",
"refresh": "刷新",
"addGoodsCategory": "添加分类",
@ -81,20 +81,20 @@
"maxAddSpecTips": "最多添加5个规格项",
"pleaseEditSpecPlaceholder": "请编辑规格信息",
"refreshSuccess": "刷新成功",
"isLimit": "是否限购",
"isLimitTips": "启用限购后,购买商品时,会对该商品购买量做限制判断。",
"limitType": "限购类型",
"limitTypeTips": "单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
"singleTime": "单次限购",
"singlePerson": "单人限购",
"maxBuy": "限购数量",
"maxBuyPlaceholder": "请输入限购数量",
"isLimit":"是否限购",
"isLimitTips":"启用限购后,购买商品时,会对该商品购买量做限制判断。",
"limitType":"限购类型",
"limitTypeTips":"单次限购是针对于每次下单不能超过限购数量,单人限购是针对于会员账号购买这个商品的总数不能超过限购数量。",
"singleTime":"单次限购",
"singlePerson":"单人限购",
"maxBuy":"限购数量",
"maxBuyPlaceholder":"请输入限购数量",
"maxBuyTips": "[限购数量]格式输入错误",
"maxBuyWarnTips": "限购数量超出商品库存时,买家将无法购买该商品",
"maxBuyWarnTips":"限购数量超出商品库存时,买家将无法购买该商品",
"maxBuyNotZeroTips": "限购数量不能小于1",
"minBuy": "起购数量",
"minBuyTips": "起购数量超出商品库存时,买家将无法购买该商品",
"minBuyFormatErrorTips": "[起购数量]格式输入错误",
"minBuy":"起购数量",
"minBuyTips":"起购数量超出商品库存时,买家将无法购买该商品",
"minBuyFormatErrorTips":"[起购数量]格式输入错误",
"minBuyNotZeroTips": "起购数量不能小于0",
"minBuyGreaterThanMaxBuyTips": "起购数量不能大于限购数量",
@ -124,6 +124,7 @@
"specValueNameRepeat": "规格值不能重复",
"lackDefaultSpec": "商品缺少默认规格",
"setDeliverGoods": "发货设置",
"autoDeliverGoods": "自动发货",
"handDeliverGoods": "手动发货",
@ -162,4 +163,5 @@
"fixedPriceHint": "会员价说明:指定优惠价格,商品未参与活动时,按照会员价优惠,若商品参与活动,则以活动价为准",
"participateInActiveDisableTips": "商品正在参与营销活动,禁止操作"
}

38
admin/src/addon/shop/lang/zh-cn/index.index.json

@ -1,20 +1,20 @@
{
"realtimeOverview": "实时概况",
"updateTime": "更新时间:",
"todayOrderCount": "今日订单数",
"todayOrderSale": "今日销售额",
"todayAddMemberCount": "今日退款金额",
"todayBrowseCount": "今日浏览量",
"yesterday": "昨日:",
"orderCount": "订单总数",
"salesTotal": "销售总额(元)",
"memberTotal": "退款金额",
"browseTotal": "总浏览量",
"agentMatters": "待办事项",
"waitPayOrder": "待付款订单",
"waitDeliveryOrder": "待发货订单",
"waitTakeOrder": "待收货订单",
"refundOrder": "退款订单",
"saleGoodsNum": "出售商品数量",
"warehouseGoodsNum": "仓库商品数量"
}
"realtimeOverview":"实时概况",
"updateTime":"更新时间:",
"todayOrderCount":"今日订单数",
"todayOrderSale":"今日销售额",
"todayAddMemberCount":"今日退款金额",
"todayBrowseCount":"今日浏览量",
"yesterday":"昨日:",
"orderCount":"订单总数",
"salesTotal":"销售总额(元)",
"memberTotal":"退款金额",
"browseTotal":"总浏览量",
"agentMatters":"待办事项",
"waitPayOrder":"待付款订单",
"waitDeliveryOrder":"待发货订单",
"waitTakeOrder":"待收货订单",
"refundOrder":"退款订单",
"saleGoodsNum":"出售商品数量",
"warehouseGoodsNum":"仓库商品数量"
}

82
admin/src/addon/shop/lang/zh-cn/marketing.coupon.add.json

@ -1,42 +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": "领券截止时间"
}
"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": "领券截止时间"
}

82
admin/src/addon/shop/lang/zh-cn/marketing.coupon.edit.json

@ -1,42 +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": "领券截止时间"
}
"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": "领券截止时间"
}

90
admin/src/addon/shop/lang/zh-cn/marketing.coupon.list.json

@ -1,47 +1,47 @@
{
"addCoupon": "添加优惠券",
"title": "名称",
"titlePlaceholder": "请输入优惠券名称",
"type": "类型",
"price": "面值",
"receiveType": "是否手动领取",
"startTime": "开始时间",
"endTime": "结束时间",
"sumCount": "剩余数量/发放数量",
"remainCount": "已领用/已使用",
"receive": "领取记录",
"edit": "编辑",
"Status": "是否关闭领取",
"threshold": "使用门槛",
"reduction": "满减券",
"noThreshold": "无门槛券",
"couponDeleteTips": "确定要删除该优惠券吗?",
"couponColseTips": "确定要关闭该优惠券吗?关闭后将不可领取,若会员已领取将变为失效",
"validType": "有效期",
"statusName": "状态",
"receiveTypeTime": "领取有效期",
"spreadGoods": "推广",
"close": "关闭",
"couponSpreadTitle": "优惠券推广",
"downloadQrcode": "下载二维码",
"spreadLink": "推广链接",
"receiveUseCount": "已使用",
"addCoupon": "添加优惠券",
"title": "名称",
"titlePlaceholder": "请输入优惠券名称",
"type": "类型",
"price": "面值",
"receiveType": "是否手动领取",
"startTime": "开始时间",
"endTime": "结束时间",
"sumCount": "剩余数量/发放数量",
"remainCount": "已领用/已使用",
"receive": "领取记录",
"edit": "编辑",
"Status": "是否关闭领取",
"threshold": "使用门槛",
"reduction": "满减券",
"noThreshold": "无门槛券",
"couponDeleteTips": "确定要删除该优惠券吗?",
"couponColseTips": "确定要关闭该优惠券吗?关闭后将不可领取,若会员已领取将变为失效",
"validType": "有效期",
"statusName":"状态",
"receiveTypeTime": "领取有效期",
"spreadGoods":"推广",
"close":"关闭",
"couponSpreadTitle":"优惠券推广",
"downloadQrcode": "下载二维码",
"spreadLink": "推广链接",
"receiveUseCount": "已使用",
"collectionCoupon": "领取记录",
"collectionTtitle": "优惠券名称",
"userName": "领用会员",
"collectionReceiveType": "领用方式",
"createTime": "领取时间",
"expireTime": "到期时间",
"status": "当前状态",
"useTime": "使用时间",
"validity": "使用有效期",
"mobile": "手机号",
"memberInfo": "会员信息",
"memberInfoPlaceholder": "请输入会员昵称/手机号",
"collectionSumCount": "发放数量",
"couponInfo": "优惠券基本信息",
"receiveCount": "已领取",
"receiveExpireCount": "已过期",
"showOrder": "查看订单"
}
"collectionCoupon":"领取记录",
"collectionTtitle": "优惠券名称",
"userName": "领用会员",
"collectionReceiveType": "领用方式",
"createTime": "领取时间",
"expireTime": "到期时间",
"status":"当前状态",
"useTime": "使用时间",
"validity":"使用有效期",
"mobile": "手机号",
"memberInfo": "会员信息",
"memberInfoPlaceholder":"请输入会员昵称/手机号",
"collectionSumCount": "发放数量",
"couponInfo": "优惠券基本信息",
"receiveCount":"已领取",
"receiveExpireCount":"已过期",
"showOrder": "查看订单"
}

72
admin/src/addon/shop/lang/zh-cn/marketing.discount.add.json

@ -1,38 +1,38 @@
{
"editDiscount": "添加限时折扣",
"name": "活动名称",
"namePlaceholder": "请输入活动名称",
"nameTip": "活动标题用于在手机或者电脑前端,建议输入长度不要大于5",
"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": "请输入规格折扣设置"
"editDiscount":"添加限时折扣",
"name": "活动名称",
"namePlaceholder":"请输入活动名称",
"nameTip":"活动标题用于在手机或者电脑前端,建议输入长度不要大于5",
"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":"请输入规格折扣设置"
}

14
admin/src/addon/shop/lang/zh-cn/marketing.discount.config.json

@ -1,8 +1,8 @@
{
"headTitle": "顶部广告图",
"image": "图片上传",
"imagePlaceholder": "请上传图片",
"toLink": "跳转链接",
"toLinkPlaceholder": "请输入跳转链接",
"addConfigList": "添加广告图"
}
"headTitle":"顶部广告图",
"image":"图片上传",
"imagePlaceholder":"请上传图片",
"toLink":"跳转链接",
"toLinkPlaceholder":"请输入跳转链接",
"addConfigList":"添加广告图"
}

2
admin/src/addon/shop/lang/zh-cn/marketing.discount.detail.json

@ -34,4 +34,4 @@
"participationNum": "参与次数",
"orderTime": "最后下单时间",
"memberInfo": "会员信息"
}
}

72
admin/src/addon/shop/lang/zh-cn/marketing.discount.edit.json

@ -1,38 +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": "请输入规格折扣设置"
"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":"请输入规格折扣设置"
}

98
admin/src/addon/shop/lang/zh-cn/marketing.discount.list.json

@ -1,50 +1,50 @@
{
"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": "结束时间"
}
"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": "结束时间"
}

124
admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_add.json

@ -1,66 +1,66 @@
{
"addGoods": "添加商品",
"baseInfo": "基础设置",
"goodsType": "商品类型",
"goodsName": "商品名称",
"goodsNamePlaceholder": "请输入商品名称",
"goodsTitle": "副标题",
"goodsTitlePlaceholder": "请输入副标题",
"image": "商品图片",
"imagePlaceholder": "请选择商品图片",
"selectProduct": "选择商品",
"selectGoodsPlaceholder": "请选择商品",
"goodsStatus": "商品状态",
"goodsSelect": "选择商品",
"redemptionSettings": "积分设置",
"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": "每人每单可兑换件数",
"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": "领取有效期",
"couponSelect": "选择优惠券",
"couponSelectPlaceholder": "请选择优惠券",
"couponName": "优惠券名称",
"couponType": "类型",
"couponPrice": "面值",
"sumCount": "总库存",
"threshold": "使用门槛",
"validType": "有效期",
"receiveTypeTime": "领取有效期",
"balance":"兑换余额",
"balancePlaceholder":"请输入兑换余额",
"balanceTips":"[兑换余额]格式错误",
"balanceTipsTwo":"兑换余额不可小于等于0",
"balanceType":"余额类型",
"balance": "兑换余额",
"balancePlaceholder": "请输入兑换余额",
"balanceTips": "[兑换余额]格式错误",
"balanceTipsTwo": "兑换余额不可小于等于0",
"balanceType": "余额类型",
"goodsSkuTitle": "选择商品规格",
"goodsSkuPlaceholder": "请选择商品规格",
"goodsStock": "库存",
"enabled": "设为参与",
"noEnabled": "设为不参与",
"noEnabledTip": "请至少设置一个规格参与",
"goodsDetail": "商品详情"
}
"goodsSkuTitle":"选择商品规格",
"goodsSkuPlaceholder":"请选择商品规格",
"goodsStock":"库存",
"enabled":"设为参与",
"noEnabled":"设为不参与",
"noEnabledTip":"请至少设置一个规格参与",
"goodsDetail":"商品详情"
}

123
admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_edit.json

@ -1,66 +1,67 @@
{
"editGoods": "编辑商品",
"baseInfo": "基础设置",
"goodsType": "商品类型",
"goodsName": "商品名称",
"goodsNamePlaceholder": "请输入商品名称",
"goodsTitle": "副标题",
"goodsTitlePlaceholder": "请输入副标题",
"image": "商品图片",
"imagePlaceholder": "请选择商品图片",
"selectProduct": "选择商品",
"selectGoodsPlaceholder": "请选择商品",
"goodsStatus": "商品状态",
"goodsSelect": "选择商品",
"redemptionSettings": "积分设置",
"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": "每人每单可兑换件数",
"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": "领取有效期",
"couponSelect":"选择优惠券",
"couponSelectPlaceholder":"请选择优惠券",
"couponName":"优惠券名称",
"couponType":"类型",
"couponPrice":"面值",
"sumCount":"总库存",
"threshold": "使用门槛",
"validType": "有效期",
"receiveTypeTime": "领取有效期",
"balance": "兑换余额",
"balancePlaceholder": "请输入兑换余额",
"balanceTips": "[兑换余额]格式错误",
"balanceTipsTwo": "兑换余额不可小于等于0",
"balanceType": "余额类型",
"balance":"兑换余额",
"balancePlaceholder":"请输入兑换余额",
"balanceTips":"[兑换余额]格式错误",
"balanceTipsTwo":"兑换余额不可小于等于0",
"balanceType":"余额类型",
"goodsSkuTitle": "选择商品规格",
"goodsSkuPlaceholder": "请选择商品规格",
"goodsStock": "库存",
"enabled": "设为参与",
"noEnabled": "设为不参与",
"noEnabledTip": "请至少设置一个规格参与",
"goodsDetail": "商品详情"
}
"goodsSkuTitle":"选择商品规格",
"goodsSkuPlaceholder":"请选择商品规格",
"goodsStock":"库存",
"enabled":"设为参与",
"noEnabled":"设为不参与",
"noEnabledTip":"请至少设置一个规格参与",
"goodsDetail":"商品详情"
}

52
admin/src/addon/shop/lang/zh-cn/marketing.exchange.goods_list.json

@ -1,27 +1,27 @@
{
"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": "结束时间"
}
"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":"结束时间"
}

106
admin/src/addon/shop/lang/zh-cn/marketing.exchange.order_list.json

@ -1,55 +1,55 @@
{
"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": "备注信息",
"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": "交易流水号",
"delivery": "订单发货",
"company": "物流公司",
"companyPlaceholder": "请选择物流公司",
"expressNumber": "物流单号",
"expressNumberPlaceholder": "请输入物流单号",
"orderGoodsIdsPlaceholder": "请选择订单项",
"virtualDelivery": "虚拟发货",
"goodsName": "商品名称",
"num": "商品数量",
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
"orderFinishTips": "是否确认用户已经收货?",
"orderGoodsPlaceholder": "请选择要发货的商品",
"deliveryStatusName": "发货状态",
"fromType": "订单来源",
"payType": "支付类型",
"orderInfo": "订单信息",
"refundStatusName": "退款状态",
"outTradeNo": "交易流水号",
"exportOrderType": "导出订单类型",
"shopOrder": "订单数据表",
"shopOrderGoods": "订单商品表",
"point": "积分"
}
"exportOrderType": "导出订单类型",
"shopOrder": "订单数据表",
"shopOrderGoods": "订单商品表",
"point":"积分"
}

72
admin/src/addon/shop/lang/zh-cn/marketing.manjian.detail.json

@ -1,37 +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": "会员信息"
}
"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": "会员信息"
}

2
admin/src/addon/shop/lang/zh-cn/marketing.manjian.edit.json

@ -84,5 +84,5 @@
"limitTipsThree": "必须大于上一层级的优惠门槛",
"ruleTypeTips": "阶梯优惠根据设定的门槛逐级增加优惠,达到特定层级门槛即可享受对应优惠,最高可设5个层级。",
"ruleTypeTipsTwo": "循环优惠指每次达到门槛即获赠一次优惠,无次数上限,需合理设置门槛。",
"goodsOffTips": "该商品已下架"
"goodsOffTips":"该商品已下架"
}

88
admin/src/addon/shop/lang/zh-cn/marketing.newcomer.config.json

@ -1,45 +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": "添加广告图"
}
"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":"添加广告图"
}

110
admin/src/addon/shop/lang/zh-cn/marketing.newcomer.order_list.json

@ -1,57 +1,57 @@
{
"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": "备注信息",
"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": "交易流水号",
"delivery": "订单发货",
"company": "物流公司",
"companyPlaceholder": "请选择物流公司",
"expressNumber": "物流单号",
"expressNumberPlaceholder": "请输入物流单号",
"orderGoodsIdsPlaceholder": "请选择订单项",
"virtualDelivery": "虚拟发货",
"goodsName": "商品名称",
"num": "商品数量",
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
"orderFinishTips": "是否确认用户已经收货?",
"orderGoodsPlaceholder": "请选择要发货的商品",
"deliveryStatusName": "发货状态",
"fromType": "订单来源",
"payType": "支付类型",
"orderInfo": "订单信息",
"refundStatusName": "退款状态",
"outTradeNo": "交易流水号",
"exportOrderType": "导出订单类型",
"shopOrder": "订单数据表",
"shopOrderGoods": "订单商品表",
"point": "积分"
}
"exportOrderType": "导出订单类型",
"shopOrder": "订单数据表",
"shopOrderGoods": "订单商品表",
"point":"积分"
}

48
admin/src/addon/shop/lang/zh-cn/order.batch_delivery.json

@ -1,25 +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": "失败原因"
}
"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": "失败原因"
}

76
admin/src/addon/shop/lang/zh-cn/order.config.json

@ -1,41 +1,41 @@
{
"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": "关闭",
"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": "添加表单"
"diyForm": "万能表单",
"diyFormPlaceholder": "请选择万能表单",
"addDiyForm": "添加表单"
}

2
admin/src/addon/shop/lang/zh-cn/order.detail.json

@ -131,4 +131,4 @@
"refundGoodsNum": "数量",
"refundGoodsPlaceholder": "请选择退款的商品",
"formDetail": "表单详情"
}
}

78
admin/src/addon/shop/lang/zh-cn/order.invoice.json

@ -1,40 +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": "请输入发票凭证"
}
"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":"请输入发票凭证"
}

210
admin/src/addon/shop/lang/zh-cn/order.refund.json

@ -1,106 +1,106 @@
{
"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": "暂无数据"
}
"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": "暂无数据"
}

2
admin/src/addon/shop/lang/zh-cn/order.refund_detail.json

@ -91,4 +91,4 @@
"expressCompany": "物流公司",
"expressRemark": "物流说明",
"orderInfoEmpty": "暂无数据"
}
}

72
admin/src/addon/shop/lang/zh-cn/stat.goods.json

@ -1,37 +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": "收藏数量"
}
"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":"收藏数量"
}

726
admin/src/addon/shop/views/address/edit.vue

@ -1,158 +1,69 @@
<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')"
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')"
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>
<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')" 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')" 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 {
getShopAddressInfo,
addShopAddress,
editShopAddress,
} from '@/addon/shop/api/shop_address'
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'
@ -162,15 +73,15 @@ 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[]
interface areaType{
province: any[],
city: any[],
district: any[]
}
const areaList = reactive<areaType>({
province: [],
city: [],
district: [],
province: [],
city: [],
district: []
})
const provinceRef = ref()
const cityRef = ref()
@ -179,120 +90,116 @@ const districtRef = ref()
/**
* 获取省
*/
getAreaListByPid(0).then((res) => {
areaList.province = res.data
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)
}
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,
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
})
latLngChange(evt.latLng.lat, evt.latLng.lng)
})
latLngChange(center.lat, center.lng)
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,
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)
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.39719,
is_delivery_address: 0,
is_refund_address: 0,
is_default_delivery: 0,
is_default_refund: 0,
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
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)
@ -300,233 +207,208 @@ 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' },
],
}
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) => {
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
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
}
}
}
if (isExist) {
formData.city_id = cityId
return
}
}
formData.city_id = 0
areaChange()
})
formData.city_id = 0
areaChange()
})
} else {
formData.city_id = 0
formData.city_id = 0
}
}
)
})
/**
* 获取区
* 获取区
*/
watch(
() => formData.city_id,
(nval) => {
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
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
}
}
}
if (isExist) {
formData.district_id = districtId
return
}
}
areaChange()
formData.district_id = 0
})
areaChange()
formData.district_id = 0
})
} else {
formData.district_id = 0
formData.district_id = 0
}
}
)
})
watch(
() => formData.district_id,
(nval) => {
watch(() => formData.district_id, (nval) => {
if (nval) {
areaChange()
areaChange()
}
}
)
})
const areaChange = debounce(() => {
setTimeout(() => {
const address = [
formData.province_id ? provinceRef.value.selectedLabel : '',
formData.city_id ? cityRef.value.selectedLabel : '',
formData.district_id ? districtRef.value.selectedLabel : '',
]
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)
setTimeout(() => {
const address = [
formData.province_id ? provinceRef.value.selectedLabel : '',
formData.city_id ? cityRef.value.selectedLabel : '',
formData.district_id ? districtRef.value.selectedLabel : ''
]
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) => {
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
})
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) => {
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
})
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) => {
watch(() => storeArea.district_id, (nval) => {
if (nval) {
formData.district_id = storeArea.district_id
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
const address = [
data.province_id ? provinceRef.value.selectedLabel : '',
data.city_id ? cityRef.value.selectedLabel : '',
data.district_id ? districtRef.value.selectedLabel : '',
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
})
}
})
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
const data = formData
const address = [
data.province_id ? provinceRef.value.selectedLabel : '',
data.city_id ? cityRef.value.selectedLabel : '',
data.district_id ? districtRef.value.selectedLabel : '',
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()
history.back()
}
</script>

275
admin/src/addon/shop/views/address/list.vue

@ -1,144 +1,89 @@
<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>
<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 { 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'
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: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
mobile: '',
full_address: ''
}
})
const searchFormRef = ref<FormInstance>()
@ -147,29 +92,23 @@ 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
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)
loadShopAddressList(getTablePageStorage(shopAddressTable.searchParam).page);
const router = useRouter()
@ -177,39 +116,41 @@ const router = useRouter()
* 添加商家地址库
*/
const addEvent = () => {
router.push('/shop/order/address/edit')
router.push('/shop/order/address/edit')
}
/**
* 编辑商家地址库
* 编辑商家地址库
* @param data
*/
const editEvent = (data: any) => {
router.push('/shop/order/address/edit?id=' + data.id)
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()
})
.catch(() => {})
})
ElMessageBox.confirm(t('shopAddressDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteShopAddress(id).then(() => {
loadShopAddressList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadShopAddressList()
if (!formEl) return
formEl.resetFields()
loadShopAddressList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

281
admin/src/addon/shop/views/delivery/company.vue

@ -1,124 +1,67 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">{{
t('addCompany')
}}</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<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-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="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>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">{{ t('addCompany') }}</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<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-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="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>
@ -128,25 +71,25 @@ import { getCompanyPageList, deleteCompany } from '@/addon/shop/api/delivery'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
import { setTablePageStorage,getTablePageStorage } from "@/utils/common";
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: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
company_name: '',
logo: '',
url: '',
create_time: '',
modify_time: ''
}
})
const searchFormRef = ref<FormInstance>()
@ -155,36 +98,30 @@ 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
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)
loadCompanyList(getTablePageStorage(companyTable.searchParam).page);
/**
* 添加物流公司
*/
const addEvent = () => {
router.push('/shop/order/delivery/company_add')
router.push('/shop/order/delivery/company_add')
}
/**
@ -192,31 +129,33 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
router.push('/shop/order/delivery/company_edit?company_id=' + data.company_id)
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()
})
.catch(() => {})
})
ElMessageBox.confirm(t('companyDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteCompany(id).then(() => {
loadCompanyList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadCompanyList()
if (!formEl) return
formEl.resetFields()
loadCompanyList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

626
admin/src/addon/shop/views/delivery/company_edit.vue

@ -1,281 +1,122 @@
<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="130px"
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('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('expressNoPlaceholder')"
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>
<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="130px" 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('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('expressNoPlaceholder')" 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-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('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 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-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-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-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('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
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 :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-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>
<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-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
>
</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>
<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>
</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 { addCompany, editCompany, getCompanyInfo } from '@/addon/shop/api/delivery'
import { FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { filterNumber } from '@/utils/common'
@ -286,22 +127,22 @@ const pageName = route.meta.title
const loading = ref(true)
const back = () => {
router.push('/shop/order/delivery/company')
router.push('/shop/order/delivery/company')
}
/**
* 表单数据
*/
const initialFormData = {
company_id: '',
company_name: '',
logo: '',
url: '',
express_no: '',
express_no_electronic_sheet: '',
print_style: [],
exp_type: [],
electronic_sheet_switch: 1,
company_id: '',
company_name: '',
logo: '',
url: '',
express_no: '',
express_no_electronic_sheet: "",
print_style: [],
exp_type: [],
electronic_sheet_switch: 1
}
const printStyleMaxLength = ref(10)
@ -310,156 +151,157 @@ 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]
})
}
})
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
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)
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()
}
}
if (!value[i].template_size) {
callback(new Error(t('printStyleSizeTips')))
break
} else if (value[i].template_size) {
sizeArr.push(value[i].template_size)
],
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()
}
}
}
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 addPrintStyleValueEvent = ()=>{
formData.print_style.push({
template_name: '',
template_size: ''
})
}
//
const addExpTypeValueEvent = () => {
formData.exp_type.push({
text: '',
value: '',
})
const addExpTypeValueEvent = ()=>{
formData.exp_type.push({
text: '',
value: ''
})
}
//
const deletePrintStyleValueEvent = (index: any) => {
formData.print_style.splice(index, 1)
const deletePrintStyleValueEvent = (index:any)=>{
formData.print_style.splice(index,1)
}
//
const deleteExpTypeValueEvent = (index: any) => {
formData.exp_type.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
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
})
}
})
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>
<style lang="scss" scoped>
</style>

171
admin/src/addon/shop/views/delivery/components/delivery-personnel-edit.vue

@ -1,64 +1,27 @@
<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>
<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 { addShopDeliver, editShopDeliver, getShopDeliverInfo } from '@/addon/shop/api/delivery'
import { filterNumber } from '@/utils/common'
const showDialog = ref(false)
@ -68,9 +31,9 @@ const loading = ref(false)
* 表单数据
*/
const initialFormData = {
deliver_id: '',
deliver_name: '',
deliver_mobile: '',
deliver_id: '',
deliver_name: '',
deliver_mobile: ''
}
const formData: Record<string, any> = reactive({ ...initialFormData })
@ -78,24 +41,20 @@ 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',
},
],
}
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'])
@ -105,51 +64,49 @@ const emit = defineEmits(['complete'])
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
const save = formData.deliver_id ? editShopDeliver : addShopDeliver
if (loading.value || !formEl) return
const save = formData.deliver_id ? editShopDeliver : addShopDeliver
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
const data = formData
const data = formData
save(data)
.then((res) => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch(() => {
loading.value = false
})
}
})
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]
})
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
loading.value = false
}
defineExpose({
showDialog,
setFormData,
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
.diy-dialog-wrap .el-form-item__label {
height: auto !important;
}
</style>

248
admin/src/addon/shop/views/delivery/config.vue

@ -1,108 +1,53 @@
<template>
<div class="main-container" v-loading="loading">
<div class="flex ml-[18px] justify-between items-center mt-[20px]">
<span class="text-page-title">{{ pageName }}</span>
</div>
<div
class="p-[18px] logistics-body"
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(item)"
/>
</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>
</div>
<div class="main-container" v-loading="loading">
<div class="flex ml-[18px] justify-between items-center mt-[20px]">
<span class="text-page-title">{{ pageName }}</span>
</div>
<div class="p-[18px] logistics-body" 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(item)"/>
</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>
</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 { getShopDeliveryList, setShopDeliveryConfig } from '@/addon/shop/api/delivery'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
@ -110,87 +55,82 @@ const router = useRouter()
const pageName = route.meta.title
const loading = ref(false)
interface TableDataType {
key: string
name: string
status: number
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
loading.value = true
getShopDeliveryList().then(res => {
tableData.value = res.data
loading.value = false
nextTick(() => {
if(rowDrop) rowDrop()
})
}).catch(() => {
loading.value = false
})
}
onMounted(() => {
getShopDeliveryListFn()
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()
},
})
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 activeIndex = ref<number|null>(null)
const inputValue = ref('')
const edit = (index: number) => {
activeIndex.value = index
inputValue.value = toRaw(tableData.value[index].name)
activeIndex.value = index
inputValue.value = toRaw(tableData.value[index].name)
}
const inputBlur = () => {
if (
inputValue.value == '' ||
tableData.value[activeIndex.value].name === inputValue.value
) {
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
inputValue.value = ''
return false
}
tableData.value[activeIndex.value].name = inputValue.value
activeIndex.value = null
update()
update()
}
const update = () => {
setShopDeliveryConfig({
value: tableData.value,
})
setShopDeliveryConfig({
value: tableData.value
})
}
const goRouter = (path: string) => {
router.push({ path })
router.push({ path })
}
</script>
<style lang="scss" scoped>
.main-container {
min-height: calc(100vh - 64px);
}
.main-container {
min-height: calc(100vh - 64px);
}
.text-color {
color: var(--el-color-primary);
}
.text-color {
color: var(--el-color-primary);
}
:deep(.el-card__header) {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
:deep(.el-card__header) {
padding-top: 5px !important;
padding-bottom: 5px !important;
}
</style>

350
admin/src/addon/shop/views/delivery/electronic_sheet.vue

@ -1,216 +1,131 @@
<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>
<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 { 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'
const route = useRoute()
const router = useRouter()
const pageName = route.meta.title
const pageName = route.meta.title;
const tableData = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
template_name: '',
express_company_id: '',
},
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 })
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
})
.catch(() => {
tableData.loading = false
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
}).catch(() => {
tableData.loading = false
})
}
@ -219,16 +134,16 @@ loadList()
const companyList = ref([])
getCompanyList({
electronic_sheet_switch: 1,
}).then((res: any) => {
companyList.value = res.data
electronic_sheet_switch: 1
}).then((res:any)=>{
companyList.value = res.data;
})
/**
* 添加电子面单
*/
const addEvent = () => {
router.push('/shop/delivery/electronic_sheet_add')
router.push('/shop/delivery/electronic_sheet_add')
}
/**
@ -236,43 +151,48 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
router.push('/shop/delivery/electronic_sheet_edit?id=' + data.id)
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()
ElMessageBox.confirm(t('electronicSheetDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteElectronicSheet(id).then(() => {
loadList()
})
})
})
}
/**
* 设置默认电子面单模版
*/
const setDefaultEvent = (id: number) => {
ElMessageBox.confirm(t('electronicSheetSetDefaultTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
setDefaultElectronicSheet({ id }).then(() => {
loadList()
ElMessageBox.confirm(t('electronicSheetSetDefaultTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
setDefaultElectronicSheet({id}).then(() => {
loadList()
})
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadList()
if (!formEl) return
formEl.resetFields()
loadList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

341
admin/src/addon/shop/views/delivery/electronic_sheet_config.vue

@ -1,257 +1,184 @@
<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')"
>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/18000HTTPS推荐端口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>
<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')">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/18000HTTPS推荐端口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'
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 pageName = route.meta.title;
const loading = ref(true)
const handleClick = (path: string) => {
router.push({ path })
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 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]
})
const data = await (await getElectronicSheetConfig()).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
loading.value = false
loading.value = false
}
setFormData()
const kdnEvent = (url: any) => {
window.open(url, '_blank')
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' },
],
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
})
}
})
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;
margin-bottom: 10px !important
}
.input-item-required {
margin-bottom: 20px !important;
margin-bottom: 20px !important
}
.button-size {
font-size: 12px !important;
font-size: 12px !important;
}
.el-radio.el-radio--large {
height: auto !important;
height: auto !important
}
</style>

626
admin/src/addon/shop/views/delivery/electronic_sheet_edit.vue

@ -1,384 +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="20"
/>
<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>
<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="20" />
<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 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)
import { ref, reactive, computed } from 'vue'
import { t } from '@/lang'
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' },
]
}
})
}
}
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
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;
}
if (printStyleList.value.length) {
formData.print_style = printStyleList.value[0].value
} else {
formData.print_style = '' //
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;
}
}
}
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
/**
* 确认
* @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')
}
const back = () => {
router.push('/shop/delivery/electronic_sheet')
}
</script>
<style lang="scss" scoped></style>

773
admin/src/addon/shop/views/delivery/local.vue

@ -1,25 +1,18 @@
<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-group>
</el-form-item>
<!-- <el-form-item :label="t('timeIsOpen')" prop="time_is_open">
<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-group>
</el-form-item>
<!-- <el-form-item :label="t('timeIsOpen')" prop="time_is_open">
<div>
<el-radio-group v-model="formData.time_is_open">
<el-radio :label="1">{{ t('open') }}</el-radio>
@ -47,233 +40,116 @@
</el-checkbox-group>
</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"
@keyup="filterDigit($event)"
/>
</div>
{{ t('feeSettingTextOne') }}
<div class="w-[60px] mx-[5px]">
<el-input
v-model.trim="formData.base_price"
type="text"
@keyup="filterDigit($event)"
/>
</div>
{{ t('feeSettingTextTwo') }}
<div class="w-[60px] mx-[5px]">
<el-input
v-model.number="formData.grad_dist"
type="text"
@keyup="filterDigit($event)"
/>
</div>
{{ t('feeSettingTextThree') }}
<div class="w-[60px] mx-[5px]">
<el-input
v-model.trim="formData.grad_price"
type="text"
@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"
@keyup="filterDigit($event)"
/>
</div>
{{ t('weightFeeTextTwo') }}
<div class="w-[60px] mx-[5px]">
<el-input
v-model.trim="formData.weight_unit"
type="text"
@keyup="filterDigit($event)"
/>
</div>
{{ t('weightFeeTextThree') }}
<div class="w-[60px] mx-[5px]">
<el-input
v-model.trim="formData.weight_price"
type="text"
@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>
<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>
<div class="pb-[18px]">
<el-form-item :label="t('startPrice')" prop="start_price">
<el-input
v-model.trim="formData.area[index].start_price"
type="text"
@keyup="filterDigit($event)"
/>
</el-form-item>
</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" @keyup="filterDigit($event)" />
</div>
{{ t('feeSettingTextOne') }}
<div class="w-[60px] mx-[5px]">
<el-input v-model.trim="formData.base_price" type="text" @keyup="filterDigit($event)"/>
</div>
{{ t('feeSettingTextTwo') }}
<div class="w-[60px] mx-[5px]">
<el-input v-model.number="formData.grad_dist" type="text" @keyup="filterDigit($event)"/>
</div>
{{ t('feeSettingTextThree') }}
<div class="w-[60px] mx-[5px]">
<el-input v-model.trim="formData.grad_price" type="text" @keyup="filterDigit($event)"/>
</div>
{{ t('priceUnit') }}
</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>
</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" @keyup="filterDigit($event)"/>
</div>
{{ t('weightFeeTextTwo') }}
<div class="w-[60px] mx-[5px]">
<el-input v-model.trim="formData.weight_unit" type="text" @keyup="filterDigit($event)"/>
</div>
{{ t('weightFeeTextThree') }}
<div class="w-[60px] mx-[5px]">
<el-input v-model.trim="formData.weight_price" type="text" @keyup="filterDigit($event)" />
</div>
{{ t('priceUnit') }}
</div>
<el-form-item :label="t('areaType')">
<el-radio-group
v-model="formData.area[index].area_type"
@click.stop=""
@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 type="default" plain @click="addArea">{{
t('addDeliveryArea')
}}</el-button>
</div>
</el-scrollbar>
</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" 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" @click.stop="" @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 type="default" 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>
</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>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, onBeforeUnmount, toRaw } from 'vue'
import { ref, computed, onMounted, onBeforeUnmount,toRaw } from 'vue'
import { t } from '@/lang'
import { 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 { createCircle, deleteGeometry, createPolygon, selectGeometry, createMarker } from '@/utils/qqmap'
import { setLocal, getLocal } from '@/addon/shop/api/delivery'
import { FormInstance } from 'element-plus'
import Test from '@/utils/test'
@ -285,170 +161,154 @@ 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
interface addressType{
full_address:string
lat:string
lng:string
}
const defaultDeliveryAddress: any = ref<addressType | null>(null)
const defaultDeliveryAddress:any = ref<addressType|null>(null)
const getDefaultDeliveryAddress = async () => {
await getShopDefaultDeliveryAddressInfo()
.then(({ data }) => {
defaultDeliveryAddress.value = data
})
.catch()
await getShopDefaultDeliveryAddressInfo().then(({ data }) => {
defaultDeliveryAddress.value = data
}).catch()
}
getDefaultDeliveryAddress()
const formData = ref({
center: {
lat: '',
lng: '',
},
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.0,
weight_unit: 0,
weight_price: 0,
area: [
{
area_name: '',
area_type: 'radius',
start_price: 0,
delivery_price: 0,
area_json: {
key: guid(),
},
center: {
lat: '',
lng: ''
},
],
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()
}
}
]
})
//
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')))
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()
}
}
if (Test.require(formData.value.base_price)) {
callback(new Error(t('basePriceRequire')))
],
delivery_type: [
{
validator: (rule: any, value: any, callback: any) => {
if (!formData.value.delivery_type.length) {
callback(new Error(t('deliveryTypeRequire')))
}
callback()
}
}
if (Test.require(formData.value.grad_dist)) {
callback(new Error(t('gradDistRequire')))
],
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'
}
if (Test.require(formData.value.grad_price)) {
callback(new Error(t('gradPriceRequire')))
],
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'
}
}
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_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'
}
]
}
})
getLocal()
.then(({ data }) => {
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(',')
: []
})
.catch(() => {
loading.value = false
})
formData.value.time_week = formData.value.time_week?formData.value.time_week.split(','):[]
}).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)
}
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)
}
})
/**
@ -457,28 +317,23 @@ onMounted(() => {
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
)
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 = new TMap.Map('container', {
center,
zoom: 14
})
createMarker(map)
map.on('tilesloaded', () => {
mapLoading.value = false
})
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)
})
formData.value.area.forEach(item => {
item.area_type == 'radius' ? createCircle(map, item.area_json) : createPolygon(map, item.area_json)
})
}
const currArea = ref<number>(0)
@ -487,100 +342,96 @@ 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)
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 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)
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)
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()
map.destroy()
})
const onSave = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
let areaValidate = true
if (loading.value || !formEl) return
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
await formEl.validate(async (valid) => {
let areaValidate = true
if (valid) {
loading.value = 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
formData.value.center = {
lat: defaultDeliveryAddress.value.lat,
lng: defaultDeliveryAddress.value.lng,
}
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()
setLocal(param)
.then(() => {
loading.value = false
})
.catch(() => {
loading.value = false
})
})
}
})
await formEl.validate(async (valid) => {
const param = deepClone(toRaw(formData.value))
param.time_week = param.time_week.toString()
setLocal(param).then(() => {
loading.value = false
}).catch(() => {
loading.value = false
})
})
}
})
}
const back = () => {
router.push({ path: '/shop/order/delivery' })
router.push({ path: '/shop/order/delivery' })
}
</script>
<style lang="scss" scoped>
.region-list {
border: 1px solid var(--el-border-color-lighter);
z-index: 3;
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);
}
.region-item {
border: 1px solid transparent;
border-bottom-color: var(--el-border-color-lighter);
}
}
#container :deep(div) {
z-index: 2 !important;
#container :deep(div){
z-index: 2 !important;
}
</style>

260
admin/src/addon/shop/views/delivery/search.vue

@ -1,116 +1,76 @@
<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')"
>https://www.kdniao.com</el-button
>
</p>
<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 == 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"
class="items-center"
>
<el-radio-group v-model="formData.kdniao_is_pay">
<el-radio :label="1" size="large">{{ t('free') }}</el-radio>
<el-radio :label="2" size="large">{{ t('pay') }}</el-radio>
</el-radio-group>
</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>
<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')">https://www.kdniao.com</el-button>
</p>
<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 == 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" class="items-center">
<el-radio-group v-model="formData.kdniao_is_pay">
<el-radio :label="1" size="large">{{ t('free') }}</el-radio>
<el-radio :label="2" size="large">{{ t('pay') }}</el-radio>
</el-radio-group>
</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>
@ -127,72 +87,72 @@ 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
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 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]
})
const data = await (await getDeliverySearch()).data
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
loading.value = false
loading.value = false
}
setFormData()
const openEvent = (url: any) => {
window.open(url, '_blank')
const openEvent = (url:any) => {
window.open(url, '_blank')
}
const formRef = ref<FormInstance>()
//
const formRules = reactive<FormRules>({})
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
})
}
})
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;
margin-bottom: 10px !important
}
.button-size {
font-size: 12px !important;
font-size: 12px !important;
}
.el-radio.el-radio--large {
height: auto !important;
height: auto !important
}
</style>

228
admin/src/addon/shop/views/delivery/staff.vue

@ -1,98 +1,57 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addDeliveryPersonnel') }}
</el-button>
</div>
<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('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-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"
/>
</div>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addDeliveryPersonnel') }}
</el-button>
</div>
<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('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-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" />
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
@ -106,36 +65,34 @@ 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: '',
},
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
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
})
.catch(() => {
tableData.loading = false
getShopDelivery({
page: tableData.page,
limit: tableData.limit,
...tableData.searchParam
}).then(res => {
tableData.loading = false
tableData.data = res.data.data
tableData.total = res.data.total
}).catch(() => {
tableData.loading = false
})
}
getShopDeliveryFn()
@ -145,8 +102,8 @@ const editCategoryDialog: Record<string, any> | null = ref(null)
* 添加配送员
*/
const addEvent = () => {
editCategoryDialog.value.setFormData()
editCategoryDialog.value.showDialog = true
editCategoryDialog.value.setFormData()
editCategoryDialog.value.showDialog = true
}
/**
@ -154,29 +111,30 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
editCategoryDialog.value.setFormData(data)
editCategoryDialog.value.showDialog = true
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()
})
.catch(() => {})
})
ElMessageBox.confirm(t('deliverDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteShopDeliver(id).then(() => {
getShopDeliveryFn()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
getShopDeliveryFn()
if (!formEl) return
formEl.resetFields()
getShopDeliveryFn()
}
</script>
<style lang="scss" scoped></style>

288
admin/src/addon/shop/views/delivery/store.vue

@ -1,129 +1,77 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addStore') }}
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<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-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 class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</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>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addStore') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<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-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>
@ -133,21 +81,21 @@ import { getStoreList, deleteStore } from '@/addon/shop/api/delivery'
import { img } from '@/utils/common'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
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: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
store_name: '',
create_time: ''
}
})
const searchFormRef = ref<FormInstance>()
@ -156,29 +104,23 @@ 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
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)
loadStoreList(getTablePageStorage(storeTable.searchParam).page);
const router = useRouter()
@ -186,7 +128,7 @@ const router = useRouter()
* 添加自提门店
*/
const addEvent = () => {
router.push('/shop/order/delivery/store/edit')
router.push('/shop/order/delivery/store/edit')
}
/**
@ -194,31 +136,33 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
router.push('/shop/order/delivery/store/edit?id=' + data.store_id)
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()
})
.catch(() => {})
})
ElMessageBox.confirm(t('storeDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteStore(id).then(() => {
loadStoreList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadStoreList()
if (!formEl) return
formEl.resetFields()
loadStoreList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

688
admin/src/addon/shop/views/delivery/store_edit.vue

@ -1,136 +1,63 @@
<template>
<div class="main-container">
<el-card class="card !border-none mb-[15px]" shadow="never">
<el-page-header
:content="id ? t('updateStore') : t('addStore')"
:icon="ArrowLeft"
@back="back"
/>
</el-card>
<el-card class="box-card !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"
/>
</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"
/>
</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"
/>
</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('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')"
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 class="main-container">
<el-card class="card !border-none mb-[15px]" shadow="never">
<el-page-header :content="id ? t('updateStore') : t('addStore')" :icon="ArrowLeft" @back="back" />
</el-card>
<el-card class="box-card !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" />
</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" />
</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" />
</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('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')" 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>
</div>
</template>
<script lang="ts" setup>
@ -147,15 +74,15 @@ 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[]
interface areaType{
province: any[],
city: any[],
district: any[]
}
const areaList = reactive<areaType>({
province: [],
city: [],
district: [],
province: [],
city: [],
district: []
})
const provinceRef = ref()
const cityRef = ref()
@ -164,26 +91,24 @@ const districtRef = ref()
/**
* 获取省
*/
getAreaListByPid(0).then((res) => {
areaList.province = res.data
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)
}
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)
}
})
/**
@ -193,58 +118,56 @@ 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,
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
})
latLngChange(evt.latLng.lat, evt.latLng.lng)
})
latLngChange(center.lat, center.lng)
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,
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)
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)
})
}
@ -252,34 +175,34 @@ const latLngChange = (lat: number, lng: number) => {
* 表单数据
*/
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.39719,
latitude: 39.908626,
trade_time: '',
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: ''
}
const formData: Record<string, any> = reactive({ ...initialFormData })
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]
})
loading.value = false
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]
})
loading.value = false
}
if (id) setFormData(id)
@ -287,229 +210,198 @@ 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' },
],
}
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' }
]
}
})
/**
* 获取市
*/
watch(
() => formData.province_id,
(nval) => {
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
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
}
}
}
if (isExist) {
formData.city_id = cityId
return
}
}
formData.city_id = 0
areaChange()
})
formData.city_id = 0
areaChange()
})
} else {
formData.city_id = 0
formData.city_id = 0
}
}
)
})
/**
* 获取区
*/
watch(
() => formData.city_id,
(nval) => {
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
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
}
}
}
if (isExist) {
formData.district_id = districtId
return
}
}
areaChange()
formData.district_id = 0
})
areaChange()
formData.district_id = 0
})
} else {
formData.district_id = 0
formData.district_id = 0
}
}
)
})
watch(
() => formData.district_id,
(nval) => {
watch(() => formData.district_id, (nval) => {
if (nval) {
areaChange()
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 : '',
]
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)
setTimeout(() => {
const address = [
formData.province_id ? provinceRef.value.states.selectedLabel : '',
formData.city_id ? cityRef.value.states.selectedLabel : '',
formData.district_id ? districtRef.value.states.selectedLabel : ''
]
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) => {
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
})
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) => {
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
})
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) => {
watch(() => storeArea.district_id, (nval) => {
if (nval) {
formData.district_id = storeArea.district_id
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
;(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('')
const save = id ? editStore : addStore
save(data)
.then((res) => {
loading.value = false
history.back()
})
.catch(() => {
loading.value = false
})
}
})
if (loading.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
const data = 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('')
const save = id ? editStore : addStore
save(data).then(res => {
loading.value = false
history.back()
}).catch(() => {
loading.value = false
})
}
})
}
const back = () => {
history.back()
history.back()
}
</script>

256
admin/src/addon/shop/views/delivery/template.vue

@ -1,137 +1,84 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addTemplate') }}
</el-button>
</div>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<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-card>
<div class="flex justify-between items-center">
<div class="detail-head !m-0">
<div class="left" @click="router.push('/shop/order/delivery')">
<span class="iconfont iconxiangzuojiantou !text-xs"></span>
<span class="ml-[1px]">{{ t('returnToPreviousPage') }}</span>
</div>
<span class="adorn">|</span>
<span class="right">{{ pageName }}</span>
</div>
<el-button type="primary" @click="addEvent">
{{ t('addTemplate') }}
</el-button>
</div>
<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>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<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-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 { getShippingTemplatePageList, deleteShippingTemplate } from '@/addon/shop/api/delivery'
import { ElMessageBox, FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { setTablePageStorage, getTablePageStorage } from '@/utils/common'
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: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
template_name: ''
}
})
const searchFormRef = ref<FormInstance>()
@ -140,35 +87,29 @@ const searchFormRef = ref<FormInstance>()
* 获取运费模板列表
*/
const loadTemplateList = (page: number = 1) => {
templateTable.loading = true
templateTable.page = page
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
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)
loadTemplateList(getTablePageStorage(templateTable.searchParam).page);
/**
* 添加运费模板
*/
const addEvent = () => {
router.push({ path: '/shop/order/shipping/template_edit' })
router.push({ path: '/shop/order/shipping/template_edit' })
}
/**
@ -176,34 +117,33 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
router.push({
path: '/shop/order/shipping/template_edit',
query: { id: data.template_id },
})
router.push({ path: '/shop/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()
})
.catch(() => {})
})
ElMessageBox.confirm(t('templateDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteShippingTemplate(id).then(() => {
loadTemplateList()
}).catch(() => {
})
})
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadTemplateList()
if (!formEl) return
formEl.resetFields()
loadTemplateList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

937
admin/src/addon/shop/views/delivery/template_edit.vue

File diff suppressed because it is too large

494
admin/src/addon/shop/views/diy/components/edit-goods-coupon.vue

@ -1,203 +1,119 @@
<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>
<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>
<!-- 内容 -->
<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>
<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>
@ -211,134 +127,126 @@ import couponSelectPopup from '@/addon/shop/views/goods/components/coupon-select
import { el } from 'element-plus/es/locale'
const diyStore = useDiyStore()
diyStore.editComponent.ignore = ['componentBgColor', 'componentBgUrl'] //
diyStore.editComponent.ignore = ['componentBgColor','componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
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].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].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].couponTitle == '') {
res.code = false
res.message = t('couponTitlePlaceholder')
return res
}
if(diyStore.value[index].couponSubTitle == ''){
res.code = false
res.message = t('couponSubTitlePlaceholder')
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,
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
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',
},
{
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 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)
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
initStyleFn();
showCouponDialog.value = false
}
const initStyleFn = () => {
let 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')
}
const initStyleFn = ()=>{
let 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');
}
}
initStyleFn()
initStyleFn();
defineExpose({})
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>
<style lang="scss">
.goods-coupon-slider {
.el-slider__input {
width: 100px;
}
.goods-coupon-slider {
.el-slider__input {
width: 100px;
}
}
</style>
</style>

742
admin/src/addon/shop/views/diy/components/edit-goods-list.vue

@ -1,372 +1,196 @@
<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>
<!-- 内容 -->
<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>
<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" :close-on-press-escape="false" :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>
<el-dialog
v-model="categoryShowDialog"
:title="t('goodsCategoryTitle')"
width="750px"
:close-on-press-escape="false"
: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>
<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-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>
</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>
</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('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-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="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('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="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('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>
<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>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
@ -374,92 +198,93 @@ 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 { 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()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = [] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
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')
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
return res
}
const categoryShowDialog = ref(false)
const categoryTable = reactive({
loading: true,
data: [],
loading: true,
data: [],
})
onMounted(() => {
loadCategoryList()
loadCategoryList()
})
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
} else {
diyStore.editComponent.btnStyle.style = btnStyleList[0].value
}
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
}else{
diyStore.editComponent.btnStyle.style = btnStyleList[0].value
}
if (style == 'style-3') {
diyStore.editComponent.saleStyle.isShow = false
diyStore.editComponent.labelStyle.isShow = false
} else {
diyStore.editComponent.saleStyle.isShow = true
diyStore.editComponent.labelStyle.isShow = true
}
if(style == "style-3"){
diyStore.editComponent.saleStyle.isShow = false;
diyStore.editComponent.labelStyle.isShow = false;
}else{
diyStore.editComponent.saleStyle.isShow = true;
diyStore.editComponent.labelStyle.isShow = true;
}
diyStore.editComponent.style = style
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',
},
{
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 changeBtnStyle = (item:any) => {
diyStore.editComponent.btnStyle.style = item.value
}
const categoryTableRef = ref<InstanceType<typeof ElTable>>()
@ -468,66 +293,65 @@ const categoryTableRef = ref<InstanceType<typeof ElTable>>()
*/
let currCategoryData: any = null
const loadCategoryList = () => {
categoryTable.loading = true
categoryTable.loading = true
getCategoryTree()
.then((res) => {
categoryTable.loading = false
categoryTable.data = res.data
})
.catch(() => {
categoryTable.loading = false
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
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
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()
})
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)
}
})
}
})
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" scoped></style>
<style lang="scss">
.goods-list-slider {
.el-slider__input {
width: 100px;
}
}
.goods-list-slider {
.el-slider__input {
width: 100px;
}
}
</style>

1054
admin/src/addon/shop/views/diy/components/edit-many-goods-list.vue

File diff suppressed because it is too large

211
admin/src/addon/shop/views/diy/components/edit-shop-exchange-goods.vue

@ -1,8 +1,8 @@
<template>
<div>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<!-- <div class="edit-attr-item-wrap">
<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
@ -19,30 +19,23 @@
@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="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>
@ -56,95 +49,52 @@
<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>
<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('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>
<!-- 样式 -->
<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('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>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</div>
</template>
<script lang="ts" setup>
@ -154,33 +104,34 @@ import useDiyStore from '@/stores/modules/diy'
import { ref, reactive, onMounted } from 'vue'
import goodsSelectPopup from '@/addon/shop/views/marketing/exchange/components/goods-select-popup.vue'
const diyStore: any = useDiyStore()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = [] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
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')
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
return res
}
const goodsSelectPopupRef = ref()
const goodsSelect = (val: any) => {
diyStore.editComponent.goods_ids = val.map((el: any) => el.id)
const goodsSelect = (val:any)=>{
diyStore.editComponent.goods_ids = val.map((el:any)=>el.id)
}
defineExpose({})
</script>
<style lang="scss" scoped></style>

41
admin/src/addon/shop/views/diy/components/edit-shop-exchange-info.vue

@ -1,37 +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="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>
<!-- 样式 -->
<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'] //
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgColor','componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
return res
const res = { code: true, message: '' }
return res
}
defineExpose({})
</script>
<style lang="scss" scoped></style>

281
admin/src/addon/shop/views/diy/components/edit-shop-goods-ranking.vue

@ -1,150 +1,83 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('activeCubeBlockContent') }}</h3>
<el-form label-width="85px" class="px-[10px]">
<div ref="blockBoxRef">
<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('bgImage')">
<upload-image v-model="item.bgUrl" :limit="1" />
</el-form-item>
<el-form-item :label="t('listFrameColor')">
<el-color-picker
v-model="item.listFrame.startColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
<icon
name="iconfont iconmap-connect"
size="20px"
class="block !text-gray-400 mx-[5px]"
/>
<el-color-picker
v-model="item.listFrame.endColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('rankingTitleIcon')">
<upload-image v-model="item.imgUrl" :limit="1" />
</el-form-item>
<el-form-item :label="t('rankName')">
<el-input
v-model="item.text"
clearable
:placeholder="t('rankNamePlaceholder')"
maxlength="8"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('rankTextColor')">
<el-color-picker
v-model="item.textColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('rankingSubTitle')">
<el-input
v-model.trim="item.subTitle.text"
:placeholder="t('activeCubeSubTitlePlaceholder')"
clearable
maxlength="6"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('rankingSubTitleTextColor')">
<el-color-picker
v-model="item.subTitle.textColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('rankingSubTitleLink')">
<diy-link v-model="item.subTitle.link" />
</el-form-item>
<el-form-item :label="t('rankSelectPopupSelectRankButton')">
<el-radio-group
v-model="item.source"
:title="t('rankSelectPopupSelectRankButton')"
>
<el-radio label="default">{{ t('defaultSources') }}</el-radio>
<el-radio label="custom">{{
t('manualSelectionSources')
}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
:label="t('customGoods')"
v-if="item.source == 'custom'"
>
<rank-select-popup
ref="goodsSelectPopupRef"
v-model="diyStore.editComponent.list[index].rankIds"
:max="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 class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('activeCubeBlockContent') }}</h3>
<el-form label-width="85px" class="px-[10px]">
<div ref="blockBoxRef">
<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('bgImage')">
<upload-image v-model="item.bgUrl" :limit="1" />
</el-form-item>
<el-form-item :label="t('listFrameColor')">
<el-color-picker v-model="item.listFrame.startColor" show-alpha :predefine="diyStore.predefineColors" />
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]" />
<el-color-picker v-model="item.listFrame.endColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('rankingTitleIcon')">
<upload-image v-model="item.imgUrl" :limit="1" />
</el-form-item>
<el-form-item :label="t('rankName')">
<el-input v-model="item.text" clearable :placeholder="t('rankNamePlaceholder')" maxlength="8" show-word-limit />
</el-form-item>
<el-form-item :label="t('rankTextColor')">
<el-color-picker v-model="item.textColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('rankingSubTitle')">
<el-input v-model.trim="item.subTitle.text" :placeholder="t('activeCubeSubTitlePlaceholder')" clearable maxlength="6" show-word-limit />
</el-form-item>
<el-form-item :label="t('rankingSubTitleTextColor')">
<el-color-picker v-model="item.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('rankingSubTitleLink')">
<diy-link v-model="item.subTitle.link" />
</el-form-item>
<el-form-item :label="t('rankSelectPopupSelectRankButton')">
<el-radio-group v-model="item.source" :title="t('rankSelectPopupSelectRankButton')">
<el-radio label="default">{{ t('defaultSources') }}</el-radio>
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('customGoods')" v-if="item.source == 'custom'">
<rank-select-popup ref="goodsSelectPopupRef" v-model="diyStore.editComponent.list[index].rankIds" :max="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 v-show="diyStore.editComponent.list.length < 10" class="w-full" @click="addItem">{{ t('activeCubeAddItem') }}</el-button>
</el-form>
</div>
<el-button
v-show="diyStore.editComponent.list.length < 10"
class="w-full"
@click="addItem"
>{{ t('activeCubeAddItem') }}</el-button
>
</el-form>
</div>
</div>
<!-- 样式 -->
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('rankingStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<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 class="style-wrap" v-show="diyStore.editTab == 'style'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('rankingStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<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>
</template>
<script lang="ts" setup>
@ -154,44 +87,44 @@ import useDiyStore from '@/stores/modules/diy'
import { ref, reactive } from 'vue'
import rankSelectPopup from '@/addon/shop/views/marketing/goods_rank/components/rank-select-popup.vue'
const diyStore: any = useDiyStore()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
diyStore.value[index].list.forEach((item: any) => {
if (item.source == 'custom') {
if (item.rankIds.length == 0) {
res.code = false
res.message = t('请选择榜单')
}
}
})
return res
const res = { code: true, message: '' }
diyStore.value[index].list.forEach((item: any) => {
if (item.source == 'custom') {
if (item.rankIds.length == 0) {
res.code = false
res.message = t('请选择榜单')
}
}
});
return res
}
const addItem = () => {
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
bgUrl: '',
text: '榜单名称',
textColor: '#FFFFFF',
imgUrl: '',
subTitle: {
text: '查看更多',
textColor: '#FFFFFF',
link: {
name: '',
},
},
listFrame: {
startColor: '#FEA715',
endColor: '#FE1E00',
},
source: 'default',
rankIds: [],
})
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
bgUrl: '',
text: '榜单名称',
textColor: "#FFFFFF",
imgUrl: "",
subTitle: {
text: '查看更多',
textColor: '#FFFFFF',
link: {
name: ''
}
},
listFrame: {
startColor: '#FEA715',
endColor: '#FE1E00',
},
source: 'default',
rankIds: []
})
}
defineExpose({})

388
admin/src/addon/shop/views/diy/components/edit-shop-goods-recommend.vue

@ -1,281 +1,185 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<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('goodsSelectPopupSelectGoodsButton')">
<el-radio-group
v-model="diyStore.editComponent.source"
:title="t('goodsSelectPopupSelectGoodsButton')"
>
<el-radio label="all">{{ t('defaultGoodsSelect') }}</el-radio>
<el-radio label="custom">{{
t('manualSelectionSources')
}}</el-radio>
</el-radio-group>
</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="diyStore.editComponent.list.length"
:max="diyStore.editComponent.list.length"
/>
</el-form-item>
</el-form>
</div>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<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('goodsSelectPopupSelectGoodsButton')">
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
<el-radio label="all">{{ t('defaultGoodsSelect') }}</el-radio>
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
</el-radio-group>
</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="diyStore.editComponent.list.length" :max="diyStore.editComponent.list.length" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<el-form label-width="120px" class="px-[10px]">
<h3 class="mb-[10px]">{{ t('activeCubeBlockContent') }}</h3>
<p class="text-sm text-gray-400 mb-[10px]">
{{ t('dragMouseAdjustOrder') }}
</p>
<div ref="blockBoxRef">
<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('activeCubeTitle')">
<el-input
v-model.trim="item.title.text"
:placeholder="t('activeCubeTitlePlaceholder')"
clearable
maxlength="4"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('shopGoodsRecommendComponentTag')">
<el-input
v-model.trim="item.moreTitle.text"
:placeholder="t('shopGoodsRecommendComponentTagPlaceholder')"
clearable
maxlength="2"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('activeCubeButton')">
<el-input
v-model.trim="item.button.text"
:placeholder="t('activeCubeButtonPlaceholder')"
clearable
maxlength="2"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('activeCubeSubTitleTextColor')">
<el-color-picker
v-model="item.title.textColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('shopGoodsRecommendComponentTagcolor')">
<el-color-picker
v-model="item.moreTitle.startColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
<icon
name="iconfont iconmap-connect"
size="20px"
class="block !text-gray-400 mx-[5px]"
/>
<el-color-picker
v-model="item.moreTitle.endColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('activeCubeButtonColor')">
<el-color-picker
v-model="item.button.color"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('activeListFrameColor')">
<el-color-picker
v-model="item.listFrame.startColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
<icon
name="iconfont iconmap-connect"
size="20px"
class="block !text-gray-400 mx-[5px]"
/>
<el-color-picker
v-model="item.listFrame.endColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<div
class="del absolute cursor-pointer z-[2] top-[-8px] right-[-8px]"
v-show="diyStore.editComponent.list.length > 1"
@click="deleteTempFn(index)"
>
<icon name="element CircleCloseFilled" color="#bbb" size="20px" />
</div>
</div>
</div>
<el-button
v-show="diyStore.editComponent.list.length < 10"
class="w-full"
@click="addItem"
>{{ t('activeCubeAddItem') }}</el-button
>
</el-form>
</div>
</div>
<div class="edit-attr-item-wrap">
<el-form label-width="120px" class="px-[10px]">
<h3 class="mb-[10px]">{{ t('activeCubeBlockContent') }}</h3>
<p class="text-sm text-gray-400 mb-[10px]">{{ t('dragMouseAdjustOrder') }}</p>
<div ref="blockBoxRef">
<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('activeCubeTitle')">
<el-input v-model.trim="item.title.text" :placeholder="t('activeCubeTitlePlaceholder')" clearable maxlength="4" show-word-limit/>
</el-form-item>
<el-form-item :label="t('shopGoodsRecommendComponentTag')">
<el-input v-model.trim="item.moreTitle.text" :placeholder="t('shopGoodsRecommendComponentTagPlaceholder')" clearable maxlength="2" show-word-limit/>
</el-form-item>
<el-form-item :label="t('activeCubeButton')">
<el-input v-model.trim="item.button.text" :placeholder="t('activeCubeButtonPlaceholder')" clearable maxlength="2" show-word-limit/>
</el-form-item>
<el-form-item :label="t('activeCubeSubTitleTextColor')">
<el-color-picker v-model="item.title.textColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('shopGoodsRecommendComponentTagcolor')">
<el-color-picker v-model="item.moreTitle.startColor" show-alpha :predefine="diyStore.predefineColors" />
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]"/>
<el-color-picker v-model="item.moreTitle.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('activeCubeButtonColor')">
<el-color-picker v-model="item.button.color" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('activeListFrameColor')">
<el-color-picker v-model="item.listFrame.startColor" show-alpha :predefine="diyStore.predefineColors" />
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]"/>
<el-color-picker v-model="item.listFrame.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<div class="del absolute cursor-pointer z-[2] top-[-8px] right-[-8px]" v-show="diyStore.editComponent.list.length > 1" @click="deleteTempFn(index)">
<icon name="element CircleCloseFilled" color="#bbb" size="20px"/>
</div>
</div>
</div>
<el-button v-show="diyStore.editComponent.list.length < 10" class="w-full" @click="addItem">{{ t('activeCubeAddItem') }}</el-button>
</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('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 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('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>
</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 { ref, reactive, onMounted,nextTick } from 'vue'
import goodsSelectPopup from '@/addon/shop/views/goods/components/goods-select-popup.vue'
import Sortable from 'sortablejs'
import { range } from 'lodash-es'
const diyStore: any = useDiyStore()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
diyStore.value[index].list.forEach((item: any) => {
if (!item.title.text) {
res.code = false
res.message = t('activeCubeTitlePlaceholder')
return res
}
if (!item.moreTitle.text) {
res.code = false
res.message = t('shopGoodsRecommendComponentTagPlaceholder')
return res
}
if (!item.button.text) {
res.code = false
res.message = t('activeCubeButtonPlaceholder')
return res
}
})
const res = { code: true, message: '' }
diyStore.value[index].list.forEach((item: any) => {
if (!item.title.text) {
res.code = false
res.message = t('activeCubeTitlePlaceholder')
return res
}
if (!item.moreTitle.text) {
res.code = false
res.message = t('shopGoodsRecommendComponentTagPlaceholder')
return res
}
if (!item.button.text) {
res.code = false
res.message = t('activeCubeButtonPlaceholder')
return res
}
})
if (
diyStore.value[index].source == 'custom' &&
diyStore.value[index].goods_ids.length < diyStore.value[index].list.length
) {
res.code = false
res.message = t('goodsPlaceholder')
if (diyStore.value[index].source == 'custom' && diyStore.value[index].goods_ids.length < diyStore.value[index].list.length) {
res.code = false
res.message = t('goodsPlaceholder')
return res
}
return res
}
return res
}
diyStore.editComponent.list.forEach((item: any) => {
if (!item.id) item.id = diyStore.generateRandom()
if (!item.id) item.id = diyStore.generateRandom()
})
const blockBoxRef = ref()
onMounted(() => {
nextTick(() => {
const sortable = Sortable.create(blockBoxRef.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()
})
)
},
})
nextTick(() => {
const sortable = Sortable.create(blockBoxRef.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()
})
)
}
})
let listNum = diyStore.editComponent.list.length
let goodsIdNum = diyStore.editComponent.goods_ids.length
diyStore.editComponent.goods_ids.splice(listNum, goodsIdNum)
})
let listNum = diyStore.editComponent.list.length;
let goodsIdNum = diyStore.editComponent.goods_ids.length;
diyStore.editComponent.goods_ids.splice(listNum, goodsIdNum);
})
})
const addItem = () => {
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
title: {
text: '标题',
textColor: '#303133',
},
moreTitle: {
text: '精选',
startColor: '#FF7234',
endColor: '#FF213F',
},
listFrame: {
startColor: '#FFE5E5',
endColor: '#FFF5F0',
},
button: {
text: '首单',
textColor: '#FFFFFF',
color: '#FF1128',
},
goodsId: [],
})
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
title: {
text: '标题',
textColor: '#303133'
},
moreTitle: {
text: '精选',
startColor: '#FF7234',
endColor: '#FF213F'
},
listFrame: {
startColor: '#FFE5E5',
endColor: '#FFF5F0'
},
button : {
text: "首单",
textColor: "#FFFFFF",
color: "#FF1128",
},
goodsId: [],
})
}
const deleteTempFn = (index) => {
diyStore.editComponent.list.splice(index, 1)
diyStore.editComponent.goods_ids.splice(index, 1)
const deleteTempFn = (index) =>{
diyStore.editComponent.list.splice(index,1);
diyStore.editComponent.goods_ids.splice(index,1);
}
defineExpose({})
</script>
<style lang="scss" scoped></style>

71
admin/src/addon/shop/views/diy/components/edit-shop-member-info.vue

@ -1,41 +1,41 @@
<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>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('shopMemberInfoComponentAccount')">
<el-switch v-model="diyStore.editComponent.isShowAccount" />
</el-form-item>
</el-form>
</div>
</div>
<!-- 内容 -->
<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>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('shopMemberInfoComponentAccount')">
<el-switch v-model="diyStore.editComponent.isShowAccount" />
</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('memberStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.textColor" />
</el-form-item>
</el-form>
<!-- 样式 -->
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
<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('textColor')">
<el-color-picker v-model="diyStore.editComponent.textColor"/>
</el-form-item>
</el-form>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('shopMemberInfoComponentUidTextColor')">
<el-color-picker v-model="diyStore.editComponent.uidTextColor"/>
</el-form-item>
</el-form>
</div>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('shopMemberInfoComponentUidTextColor')">
<el-color-picker v-model="diyStore.editComponent.uidTextColor" />
</el-form-item>
</el-form>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
@ -46,6 +46,7 @@ const diyStore = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
defineExpose({})
</script>
<style lang="scss" scoped></style>

609
admin/src/addon/shop/views/diy/components/edit-shop-newcomer.vue

@ -1,232 +1,116 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('styleRecommend') }}</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="showTitleStyle"
>{{ diyStore.editComponent.style.title }}</span
>
<el-icon>
<ArrowRight />
</el-icon>
</el-form-item>
</el-form>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('styleRecommend') }}</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="showTitleStyle">{{ diyStore.editComponent.style.title }}</span>
<el-icon>
<ArrowRight />
</el-icon>
</el-form-item>
</el-form>
<el-dialog
v-model="showTitleDialog"
:title="t('selectStyle')"
width="460px"
>
<div class="flex flex-wrap">
<template v-for="(item, index) in styleList" :key="index">
<div
:class="{ 'border-primary': selectStyle.value == item.value }"
@click="changeTitleStyle(item)"
class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] mb-[12px] cursor-pointer border bg-[#eee]"
>
<img :src="img(item.url)" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showTitleDialog = false">{{
t('cancel')
}}</el-button>
<el-button type="primary" @click="confirmTitleStyle">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</div>
<el-dialog v-model="showTitleDialog" :title="t('selectStyle')" width="460px">
<div class="flex flex-wrap">
<template v-for="(item,index) in styleList" :key="index">
<div :class="{ 'border-primary': selectStyle.value == item.value }" @click="changeTitleStyle(item)" class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] mb-[12px] cursor-pointer border bg-[#eee]">
<img :src="img(item.url)" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showTitleDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="confirmTitleStyle">{{ t('confirm') }}</el-button>
</span>
</template>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('image')">
<upload-image v-model="diyStore.editComponent.textImg" :limit="1" />
</el-form-item>
<el-form-item
:label="t('subTitle')"
v-show="
diyStore.editComponent &&
diyStore.editComponent.style &&
diyStore.editComponent.style.value == 'style-3'
"
>
<el-input
v-model.trim="diyStore.editComponent.subTitle.text"
:placeholder="t('subTitlePlaceholder')"
clearable
maxlength="8"
show-word-limit
/>
</el-form-item>
<el-form-item
:label="t('link')"
v-show="
diyStore.editComponent &&
diyStore.editComponent.style &&
diyStore.editComponent.style.value == 'style-3'
"
>
<diy-link v-model="diyStore.editComponent.subTitle.link" />
</el-form-item>
</el-form>
</div>
</el-dialog>
</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('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('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'"
>
<newcomer-goods-select-popup
ref="goodsSelectPopupRef"
v-model="diyStore.editComponent.goods_ids"
:min="1"
:max="99"
mode="sku"
/>
</el-form-item>
</el-form>
</div>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('image')">
<upload-image v-model="diyStore.editComponent.textImg" :limit="1"/>
</el-form-item>
<el-form-item :label="t('subTitle')" v-show="diyStore.editComponent && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<el-input v-model.trim="diyStore.editComponent.subTitle.text" :placeholder="t('subTitlePlaceholder')" clearable maxlength="8" show-word-limit />
</el-form-item>
<el-form-item :label="t('link')" v-show="diyStore.editComponent && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<diy-link v-model="diyStore.editComponent.subTitle.link"/>
</el-form-item>
</el-form>
</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('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 &&
diyStore.editComponent.style &&
diyStore.editComponent.style.value == 'style-3'
"
>
<h3 class="mb-[10px]">{{ t('subTitleStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker
v-model="diyStore.editComponent.subTitle.textColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('subTextBgColor')">
<el-color-picker
v-model="diyStore.editComponent.subTitle.startColor"
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.subTitle.endColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('countDownStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('newcomerNumberColor')">
<el-color-picker
v-model="diyStore.editComponent.countDown.numberColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('newcomerNumberBg')">
<el-color-picker
v-model="diyStore.editComponent.countDown.numberBg.startColor"
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.countDown.numberBg.endColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('newcomerOtherColor')">
<el-color-picker
v-model="diyStore.editComponent.countDown.otherColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t("selectSource") }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('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('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'">
<newcomer-goods-select-popup ref="goodsSelectPopupRef" v-model="diyStore.editComponent.goods_ids" :min="1" :max="99" mode="sku" />
</el-form-item>
</el-form>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</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('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 && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<h3 class="mb-[10px]">{{ t('subTitleStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('subTextBgColor')">
<el-color-picker v-model="diyStore.editComponent.subTitle.startColor" 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.subTitle.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('countDownStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('newcomerNumberColor')">
<el-color-picker v-model="diyStore.editComponent.countDown.numberColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('newcomerNumberBg')">
<el-color-picker v-model="diyStore.editComponent.countDown.numberBg.startColor" 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.countDown.numberBg.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('newcomerOtherColor')">
<el-color-picker v-model="diyStore.editComponent.countDown.otherColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
@ -236,183 +120,174 @@ import useDiyStore from '@/stores/modules/diy'
import { ref, reactive } from 'vue'
import newcomerGoodsSelectPopup from '@/addon/shop/views/goods/components/newcomer-goods-select-popup.vue'
const diyStore: any = useDiyStore()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
const res = { code: true, message: '' }
if (diyStore.value[index].source == 'custom') {
if (diyStore.value[index].goods_ids.length == 0) {
res.code = false
res.message = t('goodsPlaceholder')
if(diyStore.value[index].source == 'custom'){
if(diyStore.value[index].goods_ids.length == 0){
res.code = false
res.message = t('goodsPlaceholder')
}
}
}
return res
return res
}
//
const showTitleDialog = ref(false)
const showTitleStyle = () => {
selectStyle.title = diyStore.editComponent.style.title
selectStyle.value = diyStore.editComponent.style.value
showTitleDialog.value = true
selectStyle.title = diyStore.editComponent.style.title;
selectStyle.value = diyStore.editComponent.style.value;
showTitleDialog.value = true
}
const changeTitleStyle = (item: any) => {
selectStyle.title = item.title
selectStyle.value = item.value
const changeTitleStyle = (item:any) => {
selectStyle.title = item.title;
selectStyle.value = item.value;
}
const confirmTitleStyle = () => {
diyStore.editComponent.style.title = selectStyle.title
diyStore.editComponent.style.value = selectStyle.value
initStyle(diyStore.editComponent.style.value)
showTitleDialog.value = false
diyStore.editComponent.style.title = selectStyle.title;
diyStore.editComponent.style.value = selectStyle.value;
initStyle(diyStore.editComponent.style.value);
showTitleDialog.value = false
}
const styleList = reactive([
{
url: 'addon/shop/diy/newcomer/style_01.png',
title: '风格1',
value: 'style-1',
},
{
url: 'addon/shop/diy/newcomer/style_02.png',
title: '风格2',
value: 'style-2',
},
{
url: 'addon/shop/diy/newcomer/style_03.png',
title: '风格3',
value: 'style-3',
},
{
url: 'addon/shop/diy/newcomer/style_04.png',
title: '风格4',
value: 'style-4',
},
{
url : 'addon/shop/diy/newcomer/style_01.png',
title:'风格1',
value:'style-1'
},{
url : 'addon/shop/diy/newcomer/style_02.png',
title:'风格2',
value:'style-2'
},{
url : 'addon/shop/diy/newcomer/style_03.png',
title:'风格3',
value:'style-3'
},{
url : 'addon/shop/diy/newcomer/style_04.png',
title:'风格4',
value:'style-4'
}
])
const initStyle = (style: any) => {
if (style == 'style-1') {
diyStore.editComponent.textImg =
'addon/shop/diy/newcomer/style_title_01.png'
diyStore.editComponent.countDown.numberColor = 'rgba(255, 0, 0, 1)'
diyStore.editComponent.countDown.numberBg.startColor =
'rgba(255, 255, 255, 1)'
diyStore.editComponent.countDown.numberBg.endColor = ''
diyStore.editComponent.countDown.otherColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.textColor = '#303133'
diyStore.editComponent.pageStartBgColor = ''
diyStore.editComponent.pageEndBgColor = ''
diyStore.editComponent.pageGradientAngle = 'to bottom'
diyStore.editComponent.componentStartBgColor = '#ff6D1A'
diyStore.editComponent.componentEndBgColor = 'rgba(255, 70, 56, 1)'
diyStore.editComponent.componentGradientAngle = 'to right'
diyStore.editComponent.bottomRounded = 12
diyStore.editComponent.topRounded = 12
diyStore.editComponent.elementBgColor = ''
diyStore.editComponent.bottomElementRounded = 10
diyStore.editComponent.topElementRounded = 10
diyStore.editComponent.margin.top = 10
diyStore.editComponent.margin.bottom = 0
diyStore.editComponent.margin.both = 10
} else if (style == 'style-2') {
diyStore.editComponent.textImg =
'addon/shop/diy/newcomer/style_title_02.png'
diyStore.editComponent.countDown.numberColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.countDown.numberBg.startColor =
'rgba(255, 44, 54, 1)'
diyStore.editComponent.countDown.numberBg.endColor = ''
diyStore.editComponent.countDown.otherColor = 'rgba(102, 102, 102, 1)'
diyStore.editComponent.textColor = '#303133'
diyStore.editComponent.pageStartBgColor = ''
diyStore.editComponent.pageEndBgColor = ''
diyStore.editComponent.pageGradientAngle = 'to bottom'
diyStore.editComponent.componentStartBgColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.componentEndBgColor = ''
diyStore.editComponent.componentGradientAngle = 'to bottom'
diyStore.editComponent.bottomRounded = 12
diyStore.editComponent.topRounded = 12
diyStore.editComponent.elementBgColor = ''
diyStore.editComponent.bottomElementRounded = 5
diyStore.editComponent.topElementRounded = 5
diyStore.editComponent.margin.top = 10
diyStore.editComponent.margin.bottom = 0
diyStore.editComponent.margin.both = 10
} else if (style == 'style-3') {
diyStore.editComponent.textImg =
'addon/shop/diy/newcomer/style_title_03.png'
diyStore.editComponent.subTitle.text = '查看更多'
diyStore.editComponent.subTitle.textColor = 'rgba(239, 0, 12, 1)'
diyStore.editComponent.subTitle.startColor = 'rgba(255, 248, 217, 1)'
diyStore.editComponent.subTitle.endColor = 'rgba(255, 254, 251, 1)'
diyStore.editComponent.subTitle.link.name = ''
diyStore.editComponent.countDown.numberColor = 'rgba(239, 0, 12, 1)'
diyStore.editComponent.countDown.numberBg.startColor =
'rgba(255, 248, 217, 1)'
diyStore.editComponent.countDown.numberBg.endColor =
'rgba(255, 253, 246, 1)'
diyStore.editComponent.countDown.otherColor = 'rgba(255, 253, 246, 1)'
diyStore.editComponent.textColor = '#303133'
diyStore.editComponent.pageStartBgColor = ''
diyStore.editComponent.pageEndBgColor = ''
diyStore.editComponent.pageGradientAngle = 'to bottom'
diyStore.editComponent.componentStartBgColor = 'rgba(255, 12, 16, 1)'
diyStore.editComponent.componentEndBgColor = 'rgba(255, 101, 18, 1)'
diyStore.editComponent.componentGradientAngle = 'to right'
diyStore.editComponent.bottomRounded = 12
diyStore.editComponent.topRounded = 12
diyStore.editComponent.elementBgColor = ''
diyStore.editComponent.bottomElementRounded = 0
diyStore.editComponent.topElementRounded = 0
diyStore.editComponent.margin.top = 10
diyStore.editComponent.margin.bottom = 0
diyStore.editComponent.margin.both = 10
} else if (style == 'style-4') {
diyStore.editComponent.textImg =
'addon/shop/diy/newcomer/style_title_02.png'
diyStore.editComponent.countDown.numberColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.countDown.numberBg.startColor = ''
diyStore.editComponent.countDown.numberBg.endColor = ''
diyStore.editComponent.countDown.otherColor = 'rgba(255, 253, 253, 1)'
diyStore.editComponent.textColor = '#303133'
diyStore.editComponent.pageStartBgColor = ''
diyStore.editComponent.pageEndBgColor = ''
diyStore.editComponent.pageGradientAngle = 'to bottom'
diyStore.editComponent.componentStartBgColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.componentEndBgColor = 'rgba(255, 255, 255, 1)'
diyStore.editComponent.componentGradientAngle = 'to bottom'
diyStore.editComponent.bottomRounded = 12
diyStore.editComponent.topRounded = 12
diyStore.editComponent.elementBgColor = ''
diyStore.editComponent.bottomElementRounded = 10
diyStore.editComponent.topElementRounded = 10
diyStore.editComponent.margin.top = 10
diyStore.editComponent.margin.bottom = 0
diyStore.editComponent.margin.both = 10
}
if (style == 'style-1') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_01.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 0, 0, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "#ff6D1A";
diyStore.editComponent.componentEndBgColor = "rgba(255, 70, 56, 1)";
diyStore.editComponent.componentGradientAngle = "to right";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 10;
diyStore.editComponent.topElementRounded = 10;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-2') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_02.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 44, 54, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(102, 102, 102, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentEndBgColor = "";
diyStore.editComponent.componentGradientAngle = "to bottom";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 5;
diyStore.editComponent.topElementRounded = 5;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-3') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_03.png";
diyStore.editComponent.subTitle.text = "查看更多";
diyStore.editComponent.subTitle.textColor = "rgba(239, 0, 12, 1)";
diyStore.editComponent.subTitle.startColor = "rgba(255, 248, 217, 1)";
diyStore.editComponent.subTitle.endColor = "rgba(255, 254, 251, 1)";
diyStore.editComponent.subTitle.link.name = "";
diyStore.editComponent.countDown.numberColor = "rgba(239, 0, 12, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 248, 217, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "rgba(255, 253, 246, 1)";
diyStore.editComponent.countDown.otherColor = "rgba(255, 253, 246, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 12, 16, 1)";
diyStore.editComponent.componentEndBgColor = "rgba(255, 101, 18, 1)";
diyStore.editComponent.componentGradientAngle = "to right";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 0;
diyStore.editComponent.topElementRounded = 0;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-4') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_02.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(255, 253, 253, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentEndBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentGradientAngle = "to bottom";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 10;
diyStore.editComponent.topElementRounded = 10;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
}
}
const selectStyle = reactive({
title: diyStore.editComponent.style.title,
value: diyStore.editComponent.style.value,
title: diyStore.editComponent.style.title,
value: diyStore.editComponent.style.value
})
initStyle(diyStore.editComponent.style.value)
initStyle(diyStore.editComponent.style.value);
defineExpose({})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.goods-list-slider {
.el-slider__input {
width: 100px;
}
}
.goods-list-slider {
.el-slider__input {
width: 100px;
}
}
</style>

205
admin/src/addon/shop/views/diy/components/edit-shop-order-info.vue

@ -1,104 +1,78 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('title')">
<el-input
v-model.trim="diyStore.editComponent.text"
:placeholder="t('titlePlaceholder')"
clearable
maxlength="6"
show-word-limit
/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('subTitle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('more')">
<el-input
v-model.trim="diyStore.editComponent.more.text"
:placeholder="t('morePlaceholder')"
clearable
maxlength="8"
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">
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('textFontSize')">
<el-slider
v-model="diyStore.editComponent.fontSize"
show-input
size="small"
class="ml-[10px] diy-nav-slider"
:min="12"
:max="30"
/>
</el-form-item>
<el-form-item :label="t('textFontWeight')">
<el-radio-group v-model="diyStore.editComponent.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('textColor')">
<el-color-picker v-model="diyStore.editComponent.textColor" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('subTitleStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.more.color" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('textSet') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textFontSize')">
<el-slider
v-model="diyStore.editComponent.item.fontSize"
show-input
size="small"
class="ml-[10px] diy-nav-slider"
:min="12"
:max="16"
/>
</el-form-item>
<el-form-item :label="t('textFontWeight')">
<el-radio-group v-model="diyStore.editComponent.item.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('textColor')">
<el-color-picker
v-model="diyStore.editComponent.item.color"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
</el-form>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('title')">
<el-input v-model.trim="diyStore.editComponent.text" :placeholder="t('titlePlaceholder')" clearable maxlength="6" show-word-limit />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('subTitle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('more')">
<el-input v-model.trim="diyStore.editComponent.more.text" :placeholder="t('morePlaceholder')" clearable maxlength="8" 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">
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('textFontSize')">
<el-slider v-model="diyStore.editComponent.fontSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="12" :max="30" />
</el-form-item>
<el-form-item :label="t('textFontWeight')">
<el-radio-group v-model="diyStore.editComponent.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('textColor')">
<el-color-picker v-model="diyStore.editComponent.textColor" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('subTitleStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.more.color" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('textSet') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textFontSize')">
<el-slider v-model="diyStore.editComponent.item.fontSize" show-input size="small" class="ml-[10px] diy-nav-slider" :min="12" :max="16"/>
</el-form-item>
<el-form-item :label="t('textFontWeight')">
<el-radio-group v-model="diyStore.editComponent.item.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('textColor')">
<el-color-picker v-model="diyStore.editComponent.item.color" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
@ -112,29 +86,30 @@ diyStore.editComponent.ignore = ['componentBgUrl'] // 忽略公共属性
const showDialog = ref(false)
const showStyle = () => {
showDialog.value = true
showDialog.value = true
}
const selectStyle = ref(diyStore.editComponent.style)
const changeStyle = () => {
switch (selectStyle.value) {
case 'style-1':
diyStore.editComponent.subTitle.control = false
diyStore.editComponent.more.control = false
diyStore.editComponent.styleName = '风格1'
break
case 'style-2':
diyStore.editComponent.subTitle.control = true
diyStore.editComponent.more.control = true
diyStore.editComponent.styleName = '风格2'
break
}
diyStore.editComponent.style = selectStyle.value
showDialog.value = false
switch (selectStyle.value) {
case 'style-1':
diyStore.editComponent.subTitle.control = false
diyStore.editComponent.more.control = false
diyStore.editComponent.styleName = '风格1'
break
case 'style-2':
diyStore.editComponent.subTitle.control = true
diyStore.editComponent.more.control = true
diyStore.editComponent.styleName = '风格2'
break
}
diyStore.editComponent.style = selectStyle.value
showDialog.value = false
}
defineExpose({})
</script>
<style lang="scss" scoped></style>

43
admin/src/addon/shop/views/diy/components/edit-shop-search.vue

@ -1,27 +1,24 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('goodsSearchSet') }}</h3>
<el-form label-width="100px" class="px-[10px]">
<el-form-item :label="t('goodsSearchText')">
<el-input
v-model.trim="diyStore.editComponent.text"
:placeholder="t('goodsSearchTextPlaceholder')"
clearable
maxlength="20"
show-word-limit
/>
</el-form-item>
</el-form>
</div>
</div>
<!-- 样式 -->
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('goodsSearchSet') }}</h3>
<el-form label-width="100px" class="px-[10px]">
<el-form-item :label="t('goodsSearchText')">
<el-input v-model.trim="diyStore.editComponent.text" :placeholder="t('goodsSearchTextPlaceholder')" clearable maxlength="20" show-word-limit />
</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>

639
admin/src/addon/shop/views/diy/components/edit-single-recommend.vue

@ -1,313 +1,188 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</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="showTitleStyle"
>{{ diyStore.editComponent.titleStyle.title }}</span
>
<el-icon>
<ArrowRight />
</el-icon>
</el-form-item>
<el-form-item :label="t('image')">
<upload-image v-model="diyStore.editComponent.textImg" :limit="1" />
</el-form-item>
<el-form-item :label="t('link')">
<diy-link v-model="diyStore.editComponent.textLink" />
</el-form-item>
<el-form-item :label="t('subTitle')">
<el-input
v-model.trim="diyStore.editComponent.subTitle.text"
:placeholder="t('subTitlePlaceholder')"
clearable
maxlength="8"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('link')">
<diy-link v-model="diyStore.editComponent.subTitle.link" />
</el-form-item>
</el-form>
<el-dialog
v-model="showTitleDialog"
:title="t('selectStyle')"
width="460px"
>
<div class="flex flex-wrap">
<template v-for="(item, index) in titleStyleList" :key="index">
<div
:class="{
'border-primary': selectTitleStyle.value == item.value,
}"
@click="changeTitleStyle(item)"
class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] mb-[12px] cursor-pointer border bg-[#eee]"
>
<img :src="img(item.url)" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showTitleDialog = false">{{
t('cancel')
}}</el-button>
<el-button type="primary" @click="confirmTitleStyle">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
</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('goodsSelectPopupSelectGoodsButton')">
<el-radio-group
v-model="diyStore.editComponent.source"
:title="t('goodsSelectPopupSelectGoodsButton')"
>
<el-radio label="all">{{ t('defaultGoodsSelect') }}</el-radio>
<el-radio label="custom">{{
t('manualSelectionSources')
}}</el-radio>
</el-radio-group>
</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="1"
/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('imageSet') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<div ref="imageBoxRef">
<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('image')">
<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>
<el-form-item :label="t('link')">
<diy-link v-model="item.link" />
</el-form-item>
</div>
</div>
<el-button
v-show="diyStore.editComponent.list.length < 10"
class="w-full"
@click="addImageAd"
>{{ t('addImageAd') }}</el-button
>
</el-form>
</div>
<el-dialog
v-model="categoryShowDialog"
:title="t('goodsCategoryTitle')"
width="750px"
:close-on-press-escape="false"
: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>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</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="showTitleStyle">{{ diyStore.editComponent.titleStyle.title }}</span>
<el-icon>
<ArrowRight />
</el-icon>
</el-form-item>
<el-form-item :label="t('image')">
<upload-image v-model="diyStore.editComponent.textImg" :limit="1"/>
</el-form-item>
<el-form-item :label="t('link')">
<diy-link v-model="diyStore.editComponent.textLink"/>
</el-form-item>
<el-form-item :label="t('subTitle')">
<el-input v-model.trim="diyStore.editComponent.subTitle.text" :placeholder="t('subTitlePlaceholder')" clearable maxlength="8" show-word-limit />
</el-form-item>
<el-form-item :label="t('link')">
<diy-link v-model="diyStore.editComponent.subTitle.link"/>
</el-form-item>
</el-form>
<el-dialog v-model="showTitleDialog" :title="t('selectStyle')" width="460px">
<div class="flex flex-wrap">
<template v-for="(item,index) in titleStyleList" :key="index">
<div :class="{ 'border-primary': selectTitleStyle.value == item.value }" @click="changeTitleStyle(item)" class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] mb-[12px] cursor-pointer border bg-[#eee]">
<img :src="img(item.url)" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showTitleDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="confirmTitleStyle">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</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('goodsSelectPopupSelectGoodsButton')">
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
<el-radio label="all">{{ t('defaultGoodsSelect') }}</el-radio>
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
</el-radio-group>
</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="1" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('imageSet') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<div ref="imageBoxRef">
<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('image')">
<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>
<el-form-item :label="t('link')">
<diy-link v-model="item.link"/>
</el-form-item>
</div>
</div>
<el-button v-show="diyStore.editComponent.list.length < 10" class="w-full" @click="addImageAd">{{ t('addImageAd') }}</el-button>
</el-form>
</div>
<el-dialog v-model="categoryShowDialog" :title="t('goodsCategoryTitle')" width="750px" :close-on-press-escape="false" :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-image>
<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>
</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="style-wrap" v-show="diyStore.editTab == 'style'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker
v-model="diyStore.editComponent.subTitle.textColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('carouselStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('topRounded')">
<el-slider
v-model="diyStore.editComponent.topCarouselRounded"
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.bottomCarouselRounded"
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('recommendIndicatorStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('recommendIndicatorColor')">
<el-color-picker
v-model="diyStore.editComponent.indicatorColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('recommendIndicatorActiveColor')">
<el-color-picker
v-model="diyStore.editComponent.indicatorActiveColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
</el-form>
</div>
<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('goodsPriceColor')">
<el-color-picker
v-model="diyStore.editComponent.priceStyle.mainColor"
show-alpha
:predefine="diyStore.predefineColors"
/>
</el-form-item>
<el-form-item :label="t('goodsBtnColor')">
<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>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</el-dialog>
</div>
<!-- 样式 -->
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('carouselStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('topRounded')">
<el-slider v-model="diyStore.editComponent.topCarouselRounded" 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.bottomCarouselRounded" 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('recommendIndicatorStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('recommendIndicatorColor')">
<el-color-picker v-model="diyStore.editComponent.indicatorColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('recommendIndicatorActiveColor')">
<el-color-picker v-model="diyStore.editComponent.indicatorActiveColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
</el-form>
</div>
<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('goodsPriceColor')">
<el-color-picker v-model="diyStore.editComponent.priceStyle.mainColor" show-alpha :predefine="diyStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('goodsBtnColor')">
<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>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
@ -315,85 +190,85 @@ 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 { 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()
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
const selectTitleStyle = reactive({
title: diyStore.editComponent.titleStyle.title,
value: diyStore.editComponent.titleStyle.value,
title: diyStore.editComponent.titleStyle.title,
value: diyStore.editComponent.titleStyle.value
})
//
const showTitleDialog = ref(false)
const showTitleStyle = () => {
selectTitleStyle.title = diyStore.editComponent.titleStyle.title
selectTitleStyle.value = diyStore.editComponent.titleStyle.value
showTitleDialog.value = true
selectTitleStyle.title = diyStore.editComponent.titleStyle.title;
selectTitleStyle.value = diyStore.editComponent.titleStyle.value;
showTitleDialog.value = true
}
const changeTitleStyle = (item: any) => {
selectTitleStyle.title = item.title
selectTitleStyle.value = item.value
const changeTitleStyle = (item:any) => {
selectTitleStyle.title = item.title;
selectTitleStyle.value = item.value;
}
const confirmTitleStyle = () => {
diyStore.editComponent.titleStyle.title = selectTitleStyle.title
diyStore.editComponent.titleStyle.value = selectTitleStyle.value
showTitleDialog.value = false
diyStore.editComponent.titleStyle.title = selectTitleStyle.title;
diyStore.editComponent.titleStyle.value = selectTitleStyle.value;
showTitleDialog.value = false
}
const titleStyleList = reactive([
{
url: 'addon/shop/diy/single_recommend/title_style_01.png',
title: '风格1',
value: 'style-1',
},
{
url : 'addon/shop/diy/single_recommend/title_style_01.png',
title:'风格1',
value:'style-1'
}
])
const addImageAd = () => {
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
imageUrl: '',
imgWidth: 0,
imgHeight: 0,
link: { name: '' },
})
diyStore.editComponent.list.push({
id: diyStore.generateRandom(),
imageUrl: '',
imgWidth: 0,
imgHeight: 0,
link: { name: '' }
})
}
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
if (diyStore.value[index].source == 'custom') {
if (diyStore.value[index].goods_ids.length == 0) {
res.code = false
res.message = t('goodsPlaceholder')
const res = { code: true, message: '' }
if(diyStore.value[index].source == 'custom'){
if(diyStore.value[index].goods_ids.length == 0){
res.code = false
res.message = t('goodsPlaceholder')
}
}
}
diyStore.value[index].list.forEach((item, index) => {
if (item.imageUrl === '') {
res.code = false
res.message = t('imageUrlTip')
return res
}
})
diyStore.value[index].list.forEach((item,index) => {
if (item.imageUrl === '') {
res.code = false
res.message = t('imageUrlTip')
return res
}
});
return res
return res
}
const categoryShowDialog = ref(false)
const categoryTable = reactive({
loading: true,
data: [],
loading: true,
data: [],
})
onMounted(() => {
loadCategoryList()
loadCategoryList()
})
const categoryTableRef = ref<InstanceType<typeof ElTable>>()
@ -402,56 +277,54 @@ const categoryTableRef = ref<InstanceType<typeof ElTable>>()
*/
let currCategoryData: any = null
const loadCategoryList = () => {
categoryTable.loading = true
categoryTable.loading = true
getCategoryTree()
.then((res) => {
categoryTable.loading = false
categoryTable.data = res.data
})
.catch(() => {
categoryTable.loading = false
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
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
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()
})
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)
}
})
}
})
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({})

444
admin/src/addon/shop/views/goods/attr.vue

@ -1,189 +1,104 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addShopGoodsAttr') }}
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="goodsAttrTable.searchParam"
ref="searchFormRef"
>
<el-form-item :label="t('attrName')" prop="attr_name">
<el-input
v-model.trim="goodsAttrTable.searchParam.attr_name"
:placeholder="t('attrNamePlaceholder')"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadShopGoodsAttrList()">{{
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="goodsAttrTable.data"
size="large"
v-loading="goodsAttrTable.loading"
@sort-change="sortChange"
>
<template #empty>
<span>{{ !goodsAttrTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="attr_name"
:label="t('attrName')"
min-width="320"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="sort"
:label="t('sort')"
min-width="120"
sortable="custom"
>
<template #default="{ row }">
<el-input
v-model.trim="row.sort"
class="!w-[100px]"
maxlength="8"
@blur="sortInputListener(row.sort, row)"
/>
</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="manageEvent(row)">{{
t('manage')
}}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button
type="primary"
link
@click="deleteEvent(row.attr_id)"
>{{ t('delete') }}</el-button
>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span>
<el-button type="primary" @click="addEvent">
{{ t('addShopGoodsAttr') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="goodsAttrTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('attrName')" prop="attr_name">
<el-input v-model.trim="goodsAttrTable.searchParam.attr_name" :placeholder="t('attrNamePlaceholder')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadShopGoodsAttrList()">{{ 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="goodsAttrTable.data" size="large" v-loading="goodsAttrTable.loading" @sort-change="sortChange">
<template #empty>
<span>{{ !goodsAttrTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="attr_name" :label="t('attrName')" min-width="320" :show-overflow-tooltip="true"/>
<el-table-column prop="sort" :label="t('sort')" min-width="120" sortable="custom">
<template #default="{ row }">
<el-input v-model.trim="row.sort" class="!w-[100px]" maxlength="8" @blur="sortInputListener(row.sort, row)" />
</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="manageEvent(row)">{{ t('manage') }}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.attr_id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="goodsAttrTable.page" v-model:page-size="goodsAttrTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="goodsAttrTable.total"
@size-change="loadShopGoodsAttrList()" @current-change="loadShopGoodsAttrList" />
</div>
</div>
</el-card>
<el-dialog v-model="showDialog" :title="titleDialog" width="500px" :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('attrName')" prop="attr_name">
<el-input v-model.trim="formData.attr_name" clearable :placeholder="t('attrNamePlaceholder')" class="input-width" maxlength="20" />
</el-form-item>
<el-form-item :label="t('sort')" >
<el-input v-model.trim="formData.sort" maxlength="8" show-word-limit clearable :placeholder="t('sortPlaceholder')" class="input-width" @keyup="filterNumber($event)"/>
</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-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="goodsAttrTable.page"
v-model:page-size="goodsAttrTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="goodsAttrTable.total"
@size-change="loadShopGoodsAttrList()"
@current-change="loadShopGoodsAttrList"
/>
</div>
</div>
</el-card>
<el-dialog
v-model="showDialog"
:title="titleDialog"
width="500px"
: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('attrName')" prop="attr_name">
<el-input
v-model.trim="formData.attr_name"
clearable
:placeholder="t('attrNamePlaceholder')"
class="input-width"
maxlength="20"
/>
</el-form-item>
<el-form-item :label="t('sort')">
<el-input
v-model.trim="formData.sort"
maxlength="8"
show-word-limit
clearable
:placeholder="t('sortPlaceholder')"
class="input-width"
@keyup="filterNumber($event)"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
type="primary"
:loading="loading"
@click="confirm(formRef)"
>{{ t('confirm') }}</el-button
>
</span>
</template>
</el-dialog>
</div>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { reactive, ref,computed } from 'vue'
import { t } from '@/lang'
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
import { ElMessage,ElMessageBox,FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { debounce, filterNumber } from '@/utils/common'
import {
getAttrPageList,
addAttr,
deleteAttr,
modifyAttrSort,
editAttr,
} from '@/addon/shop/api/goods'
import { debounce,filterNumber } from '@/utils/common'
import { getAttrPageList, addAttr, deleteAttr,modifyAttrSort,editAttr} from '@/addon/shop/api/goods'
const route = useRoute()
const router = useRouter()
const pageName = route.meta.title
const pageName = route.meta.title;
const goodsAttrTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
attr_name: '',
order: '',
sort: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
attr_name: '',
order: '',
sort: ''
}
})
const searchFormRef = ref<FormInstance>()
@ -193,56 +108,54 @@ const loading = ref(false)
const titleDialog = ref('')
const formData = reactive({
attr_id: 0,
attr_name: '',
sort: 0,
attr_id: 0,
attr_name: '',
sort: 0
})
const formRef = ref<FormInstance>()
//
const formRules = computed(() => {
return {
attr_name: [
{ required: true, message: t('attrNamePlaceholder'), trigger: 'blur' },
],
}
return {
attr_name: [
{ required: true, message: t('attrNamePlaceholder'), trigger: 'blur' }
]
}
})
//
const sortChange = (event: any) => {
let sort = ''
if (event.order == 'ascending') {
sort = 'asc'
} else if (event.order == 'descending') {
sort = 'desc'
}
if (sort) {
goodsAttrTable.searchParam.order = event.prop
goodsAttrTable.searchParam.sort = sort
}
loadShopGoodsAttrList()
let sort = ''
if (event.order == 'ascending') {
sort = 'asc'
} else if (event.order == 'descending') {
sort = 'desc'
}
if (sort) {
goodsAttrTable.searchParam.order = event.prop
goodsAttrTable.searchParam.sort = sort
}
loadShopGoodsAttrList()
}
/**
* 获取商品参数列表
*/
const loadShopGoodsAttrList = (page: number = 1) => {
goodsAttrTable.loading = true
goodsAttrTable.page = page
getAttrPageList({
page: goodsAttrTable.page,
limit: goodsAttrTable.limit,
...goodsAttrTable.searchParam,
})
.then((res) => {
goodsAttrTable.loading = false
goodsAttrTable.data = res.data.data
goodsAttrTable.total = res.data.total
})
.catch(() => {
goodsAttrTable.loading = false
goodsAttrTable.loading = true
goodsAttrTable.page = page
getAttrPageList({
page: goodsAttrTable.page,
limit: goodsAttrTable.limit,
...goodsAttrTable.searchParam
}).then(res => {
goodsAttrTable.loading = false
goodsAttrTable.data = res.data.data
goodsAttrTable.total = res.data.total
}).catch(() => {
goodsAttrTable.loading = false
})
}
@ -252,20 +165,20 @@ loadShopGoodsAttrList()
* 添加商品参数
*/
const addEvent = () => {
formData.attr_id = 0
formData.attr_name = ''
formData.sort = 0
titleDialog.value = t('addShopGoodsAttr')
showDialog.value = true
formData.attr_id = 0;
formData.attr_name = '';
formData.sort = 0;
titleDialog.value = t('addShopGoodsAttr');
showDialog.value = true
}
//
const editEvent = (data: any) => {
formData.attr_id = data.attr_id
formData.attr_name = data.attr_name
formData.sort = data.sort
titleDialog.value = t('updateShopGoodsAttr')
showDialog.value = true
const editEvent = (data:any)=>{
formData.attr_id = data.attr_id;
formData.attr_name = data.attr_name;
formData.sort = data.sort;
titleDialog.value = t('updateShopGoodsAttr');
showDialog.value = true
}
/**
@ -273,23 +186,21 @@ const editEvent = (data: any) => {
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
const save = formData.attr_id ? editAttr : addAttr
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
save(formData)
.then((res) => {
loading.value = false
showDialog.value = false
loadShopGoodsAttrList()
})
.catch((err) => {
loading.value = false
})
}
})
if (loading.value || !formEl) return
const save = formData.attr_id ? editAttr : addAttr
await formEl.validate(async (valid) => {
if (valid) {
loading.value = true
save(formData).then(res => {
loading.value = false
showDialog.value = false
loadShopGoodsAttrList()
}).catch(err => {
loading.value = false
})
}
})
}
/**
@ -297,49 +208,52 @@ const confirm = async (formEl: FormInstance | undefined) => {
* @param data
*/
const manageEvent = (data: any) => {
router.push('/shop/goods/attr_edit?attr_id=' + data.attr_id)
router.push('/shop/goods/attr_edit?attr_id=' + data.attr_id)
}
/**
* 删除商品参数
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('goodsAttrDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteAttr(id)
.then(() => {
loadShopGoodsAttrList()
})
.catch(() => {})
})
ElMessageBox.confirm(t('goodsAttrDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteAttr(id).then(() => {
loadShopGoodsAttrList()
}).catch(() => {
})
})
}
//
const sortInputListener = debounce((sort, row) => {
if (isNaN(sort) || !/^\d{0,8}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${t('sortTips')}`,
if (isNaN(sort) || !/^\d{0,8}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${ t('sortTips') }`
})
return
}
if (sort > 99999999) {
row.sort = 99999999
}
modifyAttrSort({
attr_id: row.attr_id,
sort
}).then((res) => {
})
return
}
if (sort > 99999999) {
row.sort = 99999999
}
modifyAttrSort({
attr_id: row.attr_id,
sort,
}).then((res) => {})
})
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadShopGoodsAttrList()
if (!formEl) return
formEl.resetFields()
loadShopGoodsAttrList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

862
admin/src/addon/shop/views/goods/attr_edit.vue

@ -1,363 +1,202 @@
<template>
<div class="main-container">
<el-card class="card !border-none mb-[15px]" shadow="never">
<el-page-header
:content="pageName"
:icon="ArrowLeft"
@back="router.push(`/shop/goods/attr`)"
/>
</el-card>
<el-card class="box-card !border-none" shadow="never">
<!-- 商品参数基础信息 -->
<el-row
:gutter="20"
class="text-[14px]"
v-if="Object.keys(attrInfo).length"
>
<el-col :span="8">
<label>{{ t('attrName') }}</label>
<span class="ml-[10px]">{{ attrInfo.attr_name }}</span>
</el-col>
<el-col :span="6">
<label>{{ t('sort') }}</label>
<span class="ml-[10px]">{{ attrInfo.sort }}</span>
</el-col>
<el-col :span="6">
<el-button type="primary" link @click="editEvent">{{
t('edit')
}}</el-button>
</el-col>
</el-row>
<el-button type="primary" @click="openAttrValueEvent" class="my-[15px]">{{
t('addShopGoodsAttr')
}}</el-button>
<el-table
:data="goodsAttrTable.data"
size="large"
v-loading="goodsAttrTable.loading"
>
<template #empty>
<span>{{ !goodsAttrTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="attr_value_name"
:label="t('attrValueName')"
min-width="200"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="type"
:label="t('attrValueType')"
min-width="100"
:show-overflow-tooltip="true"
>
<template #default="{ row }">
<template v-if="row.type == 'radio'">
<span>{{ t('attrValueTypeRadio') }}</span>
<div class="main-container">
<el-card class="card !border-none mb-[15px]" shadow="never">
<el-page-header :content="pageName" :icon="ArrowLeft" @back="router.push(`/shop/goods/attr`)" />
</el-card>
<el-card class="box-card !border-none" shadow="never">
<!-- 商品参数基础信息 -->
<el-row :gutter="20" class="text-[14px]" v-if="Object.keys(attrInfo).length">
<el-col :span="8">
<label>{{ t('attrName') }}</label>
<span class="ml-[10px]">{{ attrInfo.attr_name }}</span>
</el-col>
<el-col :span="6">
<label>{{ t('sort') }}</label>
<span class="ml-[10px]">{{ attrInfo.sort }}</span>
</el-col>
<el-col :span="6">
<el-button type="primary" link @click="editEvent">{{ t('edit') }}</el-button>
</el-col>
</el-row>
<el-button type="primary" @click="openAttrValueEvent" class="my-[15px]">{{ t('addShopGoodsAttr') }}</el-button>
<el-table :data="goodsAttrTable.data" size="large" v-loading="goodsAttrTable.loading">
<template #empty>
<span>{{ !goodsAttrTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="attr_value_name" :label="t('attrValueName')" min-width="200" :show-overflow-tooltip="true"/>
<el-table-column prop="type" :label="t('attrValueType')" min-width="100" :show-overflow-tooltip="true">
<template #default="{ row }">
<template v-if="row.type == 'radio'">
<span>{{ t('attrValueTypeRadio') }}</span>
</template>
<template v-else-if="row.type == 'checkbox'">
<span>{{ t('attrValueTypeCheckbox') }}</span>
</template>
<template v-if="row.type == 'text'">
<span>{{ t('attrValueTypeText') }}</span>
</template>
</template>
</el-table-column>
<el-table-column prop="child" :label="t('attrValueChild')" min-width="320" :show-overflow-tooltip="true">
<template #default="{ row }">
<template v-if="row.type != 'text'">
<template v-for="(item,index) in row.child">
<span :class="{ 'mr-[5px]' : (index+1) != row.child.length }">{{ item.name }}</span>
</template>
</template>
<template v-else>
<span>-</span>
</template>
</template>
</el-table-column>
<el-table-column prop="sort" :label="t('sort')" min-width="120" sortable="custom">
<template #default="{ row,$index }">
<el-input v-model.trim="row.sort" class="w-[70px]" maxlength="8" @input="sortInputListener($event, row)" />
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="120">
<template #default="{ row,$index }">
<el-button type="primary" link @click="editAttrValueEvent(row,$index)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent($index)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 编辑商品参数信息 -->
<el-dialog v-model="showDialogByAttr" :title="t('updateAttr')" width="500px" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRulesByAttr" class="page-form" v-loading="loadingByAttr">
<el-form-item :label="t('attrName')" prop="attr_name">
<el-input v-model.trim="formData.attr_name" clearable :placeholder="t('attrNamePlaceholder')" class="input-width" maxlength="20" />
</el-form-item>
<el-form-item :label="t('sort')" >
<el-input v-model.trim="formData.sort" maxlength="8" show-word-limit clearable :placeholder="t('sortPlaceholder')" class="input-width" @keyup="filterNumber($event)"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialogByAttr = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loadingByAttr" @click="confirmAttr(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
<template v-else-if="row.type == 'checkbox'">
<span>{{ t('attrValueTypeCheckbox') }}</span>
</template>
<template v-if="row.type == 'text'">
<span>{{ t('attrValueTypeText') }}</span>
</template>
</template>
</el-table-column>
<el-table-column
prop="child"
:label="t('attrValueChild')"
min-width="320"
:show-overflow-tooltip="true"
>
<template #default="{ row }">
<template v-if="row.type != 'text'">
<template v-for="(item, index) in row.child">
<span :class="{ 'mr-[5px]': index + 1 != row.child.length }">{{
item.name
}}</span>
</template>
</template>
<template v-else>
<span>-</span>
</template>
</template>
</el-table-column>
<el-table-column
prop="sort"
:label="t('sort')"
min-width="120"
sortable="custom"
>
<template #default="{ row, $index }">
<el-input
v-model.trim="row.sort"
class="w-[70px]"
maxlength="8"
@input="sortInputListener($event, row)"
/>
</template>
</el-table-column>
<el-table-column
:label="t('operation')"
fixed="right"
align="right"
min-width="120"
>
<template #default="{ row, $index }">
<el-button
type="primary"
link
@click="editAttrValueEvent(row, $index)"
>{{ t('edit') }}</el-button
>
<el-button type="primary" link @click="deleteEvent($index)">{{
t('delete')
}}</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 编辑商品参数信息 -->
<el-dialog
v-model="showDialogByAttr"
:title="t('updateAttr')"
width="500px"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRulesByAttr"
class="page-form"
v-loading="loadingByAttr"
>
<el-form-item :label="t('attrName')" prop="attr_name">
<el-input
v-model.trim="formData.attr_name"
clearable
:placeholder="t('attrNamePlaceholder')"
class="input-width"
maxlength="20"
/>
</el-form-item>
<el-form-item :label="t('sort')">
<el-input
v-model.trim="formData.sort"
maxlength="8"
show-word-limit
clearable
:placeholder="t('sortPlaceholder')"
class="input-width"
@keyup="filterNumber($event)"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialogByAttr = false">{{
t('cancel')
}}</el-button>
<el-button
type="primary"
:loading="loadingByAttr"
@click="confirmAttr(formRef)"
>{{ t('confirm') }}</el-button
>
</span>
</template>
</el-dialog>
<!-- 编辑商品参数值信息 -->
<el-dialog
v-model="showDialogByAttrValue"
:title="attrValueTitleDialog"
width="700px"
:destroy-on-close="true"
>
<el-form
:model="formAttrValueData"
label-width="120px"
ref="formAttrValueRef"
:rules="formRulesByAttrValue"
class="page-form"
v-loading="loadingByAttrValue"
>
<el-form-item :label="t('attrValueName')" prop="attr_value_name">
<el-input
v-model.trim="formAttrValueData.attr_value_name"
clearable
:placeholder="t('attrValueNamePlaceholder')"
class="input-width"
maxlength="20"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('attrValueType')">
<el-select
v-model="formAttrValueData.type"
class="!w-[150px]"
:disabled="actionAttrValueIndex > -1"
>
<el-option
v-for="item in attrValueTypeOptions"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('sort')">
<el-input
v-model.trim="formAttrValueData.sort"
maxlength="8"
show-word-limit
clearable
:placeholder="t('sortPlaceholder')"
class="!w-[150px]"
@keyup="filterNumber($event)"
/>
</el-form-item>
<template v-if="formAttrValueData.type != 'text'">
<el-table :data="formAttrValueData.child" size="large">
<template #empty>
<span>{{
formAttrValueData.child.length == 0 ? t('emptyData') : ''
}}</span>
</el-dialog>
<!-- 编辑商品参数值信息 -->
<el-dialog v-model="showDialogByAttrValue" :title="attrValueTitleDialog" width="700px" :destroy-on-close="true">
<el-form :model="formAttrValueData" label-width="120px" ref="formAttrValueRef" :rules="formRulesByAttrValue" class="page-form" v-loading="loadingByAttrValue">
<el-form-item :label="t('attrValueName')" prop="attr_value_name">
<el-input v-model.trim="formAttrValueData.attr_value_name" clearable :placeholder="t('attrValueNamePlaceholder')" class="input-width" maxlength="20" show-word-limit />
</el-form-item>
<el-form-item :label="t('attrValueType')">
<el-select v-model="formAttrValueData.type" class="!w-[150px]" :disabled="actionAttrValueIndex > -1">
<el-option v-for="item in attrValueTypeOptions" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item :label="t('sort')" >
<el-input v-model.trim="formAttrValueData.sort" maxlength="8" show-word-limit clearable :placeholder="t('sortPlaceholder')" class="!w-[150px]" @keyup="filterNumber($event)"/>
</el-form-item>
<template v-if="formAttrValueData.type != 'text'">
<el-table :data="formAttrValueData.child" size="large">
<template #empty>
<span>{{ formAttrValueData.child.length == 0 ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="name" :label="t('attrValueName')" min-width="200">
<template #default="{ row }">
<el-input v-model.trim="row.name" class="input-width" maxlength="20" :placeholder="t('attrValueNamePlaceholder')" clearable show-word-limit />
</template>
</el-table-column>
<el-table-column prop="name" :label="t('sort')" min-width="120">
<template #default="{ row }">
<el-input v-model.trim="row.sort" class="!w-[150px]" maxlength="8" :placeholder="t('sortPlaceholder')" 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="deleteAttrValueEvent(row,$index)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<el-button type="primary" plain @click="addAttrValueEvent" class="my-[10px]" v-show="formAttrValueData.child.length < maxLength">{{ t('addAttrValue') }}</el-button>
</template>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialogByAttrValue = false">{{ t('cancel') }}</el-button>
<el-button type="primary" :loading="loadingByAttrValue" @click="confirmAttrValue(formAttrValueRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
<el-table-column
prop="name"
:label="t('attrValueName')"
min-width="200"
>
<template #default="{ row }">
<el-input
v-model.trim="row.name"
class="input-width"
maxlength="20"
:placeholder="t('attrValueNamePlaceholder')"
clearable
show-word-limit
/>
</template>
</el-table-column>
<el-table-column prop="name" :label="t('sort')" min-width="120">
<template #default="{ row }">
<el-input
v-model.trim="row.sort"
class="!w-[150px]"
maxlength="8"
:placeholder="t('sortPlaceholder')"
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="deleteAttrValueEvent(row, $index)"
>{{ t('delete') }}</el-button
>
</template>
</el-table-column>
</el-table>
<el-button
type="primary"
plain
@click="addAttrValueEvent"
class="my-[10px]"
v-show="formAttrValueData.child.length < maxLength"
>{{ t('addAttrValue') }}</el-button
>
</template>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialogByAttrValue = false">{{
t('cancel')
}}</el-button>
<el-button
type="primary"
:loading="loadingByAttrValue"
@click="confirmAttrValue(formAttrValueRef)"
>{{ t('confirm') }}</el-button
>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue'
import { reactive, ref,computed } from 'vue'
import { t } from '@/lang'
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus'
import { ElMessage,ElMessageBox,FormInstance } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { debounce, filterNumber } from '@/utils/common'
import { getAttrInfo, editAttr, modifyAttrValue } from '@/addon/shop/api/goods'
import { debounce,filterNumber } from '@/utils/common'
import { getAttrInfo,editAttr, modifyAttrValue } from '@/addon/shop/api/goods'
import { cloneDeep } from 'lodash-es'
const route = useRoute()
const router = useRouter()
const pageName = route.meta.title
const pageName = route.meta.title;
route.query.attr_id = route.query.attr_id || 0
const attrId: any = ref(route.query.attr_id)
const attrInfo: any = reactive({})
const attrId:any = ref(route.query.attr_id)
const attrInfo:any = reactive({})
const maxLength = ref(30) //
const goodsAttrTable = reactive({
loading: true,
data: [],
loading: true,
data: []
})
const loadAttrInfo = () => {
//
getAttrInfo(attrId.value).then((res: any) => {
Object.assign(attrInfo, res.data)
if (attrInfo.attr_value_format) {
attrInfo.attr_value_format = JSON.parse(attrInfo.attr_value_format)
} else {
attrInfo.attr_value_format = []
}
const loadAttrInfo = ()=> {
//
getAttrInfo(attrId.value).then((res: any) => {
Object.assign(attrInfo, res.data)
if (attrInfo.attr_value_format) {
attrInfo.attr_value_format = JSON.parse(attrInfo.attr_value_format);
} else {
attrInfo.attr_value_format = []
}
goodsAttrTable.data = cloneDeep(attrInfo.attr_value_format)
goodsAttrTable.data.sort((a: any, b: any) => {
return b.sort - a.sort
})
goodsAttrTable.data = cloneDeep(attrInfo.attr_value_format)
goodsAttrTable.data.sort((a: any, b: any) => {
return b.sort - a.sort
});
goodsAttrTable.loading = false
})
goodsAttrTable.loading = false
})
}
loadAttrInfo()
@ -366,26 +205,26 @@ const showDialogByAttr = ref(false)
const loadingByAttr = ref(false)
const formRef = ref<FormInstance>()
const formData = reactive({
attr_id: 0,
attr_name: '',
sort: 0,
attr_id: 0,
attr_name: '',
sort: 0
})
//
const formRulesByAttr = computed(() => {
return {
attr_name: [
{ required: true, message: t('attrNamePlaceholder'), trigger: 'blur' },
],
}
return {
attr_name: [
{ required: true, message: t('attrNamePlaceholder'), trigger: 'blur' }
]
}
})
//
const editEvent = (data: any) => {
formData.attr_id = attrInfo.attr_id
formData.attr_name = attrInfo.attr_name
formData.sort = attrInfo.sort
showDialogByAttr.value = true
const editEvent = (data:any)=>{
formData.attr_id = attrInfo.attr_id;
formData.attr_name = attrInfo.attr_name;
formData.sort = attrInfo.sort;
showDialogByAttr.value = true
}
/**
@ -393,228 +232,205 @@ const editEvent = (data: any) => {
* @param formEl
*/
const confirmAttr = async (formEl: FormInstance | undefined) => {
if (loadingByAttr.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loadingByAttr.value = true
editAttr(formData)
.then((res) => {
loadingByAttr.value = false
showDialogByAttr.value = false
loadAttrInfo()
})
.catch((err) => {
loadingByAttr.value = false
})
}
})
if (loadingByAttr.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
loadingByAttr.value = true
editAttr(formData).then(res => {
loadingByAttr.value = false
showDialogByAttr.value = false
loadAttrInfo()
}).catch(err => {
loadingByAttr.value = false
})
}
})
}
//
const deleteEvent = (index: any) => {
ElMessageBox.confirm(t('goodsAttrDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
if (repeatAttrValue.value) return
repeatAttrValue.value = true
attrInfo.attr_value_format.splice(index, 1)
let data = {
attr_id: attrId.value,
attr_value_format: JSON.stringify(attrInfo.attr_value_format),
}
modifyAttrValue(data)
.then((res) => {
repeatAttrValue.value = false
loadAttrInfo()
})
.catch((err) => {
repeatAttrValue.value = false
})
})
ElMessageBox.confirm(t('goodsAttrDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
if (repeatAttrValue.value) return
repeatAttrValue.value = true
attrInfo.attr_value_format.splice(index, 1);
let data = {
attr_id: attrId.value,
attr_value_format: JSON.stringify(attrInfo.attr_value_format)
};
modifyAttrValue(data).then(res => {
repeatAttrValue.value = false
loadAttrInfo()
}).catch(err => {
repeatAttrValue.value = false
})
})
}
const showDialogByAttrValue = ref(false)
const loadingByAttrValue = ref(false)
const formAttrValueRef = ref<FormInstance>()
const attrValueTitleDialog = ref('')
const formAttrValueData: any = reactive({
attr_value_id: 0,
attr_value_name: '',
type: 'radio',
sort: 0,
child: <any>[],
const formAttrValueData:any = reactive({
attr_value_id: 0,
attr_value_name: '',
type: 'radio',
sort: 0,
child: <any>[]
})
//
const attrValueTypeOptions = reactive([
{
label: '单选',
value: 'radio',
},
{
label: '多选',
value: 'checkbox',
},
{
label: '输入',
value: 'text',
},
{
label:'单选',
value:'radio'
},
{
label:'多选',
value:'checkbox'
},
{
label:'输入',
value:'text'
}
])
// 便
const generateRandom = () => {
return (
Math.floor(new Date().getSeconds()) +
Math.floor(new Date().getMilliseconds())
)
return (Math.floor(new Date().getSeconds()) + Math.floor(new Date().getMilliseconds()));
}
//
const openAttrValueEvent = () => {
formAttrValueData.attr_value_id =
attrInfo.attr_value_format.length + generateRandom()
formAttrValueData.attr_value_name = ''
formAttrValueData.type = 'radio'
formAttrValueData.sort = 0
formAttrValueData.child = []
showDialogByAttrValue.value = true
attrValueTitleDialog.value = t('addShopGoodsAttr')
actionAttrValueId.value = -1
const openAttrValueEvent = ()=> {
formAttrValueData.attr_value_id = attrInfo.attr_value_format.length + generateRandom();
formAttrValueData.attr_value_name = '';
formAttrValueData.type = 'radio';
formAttrValueData.sort = 0;
formAttrValueData.child = [];
showDialogByAttrValue.value = true;
attrValueTitleDialog.value = t('addShopGoodsAttr');
actionAttrValueId.value = -1
}
//
const sortInputListener = debounce((sort: any, row: any) => {
if (isNaN(sort) || !/^\d{0,10}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${t('sortTips')}`,
})
return
}
const sortInputListener = debounce((sort:any, row:any) => {
if (isNaN(sort) || !/^\d{0,10}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${t('sortTips')}`
})
return
}
for (let i = 0; i < attrInfo.attr_value_format.length; i++) {
if (attrInfo.attr_value_format[i].attr_value_id == row.attr_value_id) {
attrInfo.attr_value_format[i].sort = sort
break
for (let i = 0; i < attrInfo.attr_value_format.length; i++) {
if (attrInfo.attr_value_format[i].attr_value_id == row.attr_value_id) {
attrInfo.attr_value_format[i].sort = sort;
break;
}
}
}
let data = {
attr_id: attrId.value,
attr_value_format: JSON.stringify(attrInfo.attr_value_format),
}
modifyAttrValue(data)
.then((res) => {
loadAttrInfo()
let data = {
attr_id: attrId.value,
attr_value_format: JSON.stringify(attrInfo.attr_value_format)
};
modifyAttrValue(data).then(res => {
loadAttrInfo()
}).catch(err => {
})
.catch((err) => {})
})
//
const addAttrValueEvent = () => {
formAttrValueData.child.push({
id: formAttrValueData.child.length + generateRandom(),
name: '',
sort: 0,
})
const addAttrValueEvent = ()=>{
formAttrValueData.child.push({
id: formAttrValueData.child.length + generateRandom(),
name: '',
sort: 0
});
}
//
const editAttrValueEvent = (data: any, index: any) => {
attrValueTitleDialog.value = t('updateShopGoodsAttr')
actionAttrValueId.value = data.attr_value_id
Object.assign(formAttrValueData, cloneDeep(data))
showDialogByAttrValue.value = true
const editAttrValueEvent = (data:any,index:any)=> {
attrValueTitleDialog.value = t('updateShopGoodsAttr');
actionAttrValueId.value = data.attr_value_id
Object.assign(formAttrValueData,cloneDeep(data))
showDialogByAttrValue.value = true;
}
//
const formRulesByAttrValue = computed(() => {
return {
attr_value_name: [
{
required: true,
message: t('attrValueNamePlaceholder'),
trigger: 'blur',
},
],
}
return {
attr_value_name: [
{ required: true, message: t('attrValueNamePlaceholder'), trigger: 'blur' }
]
}
})
const actionAttrValueId = ref(-1)
const repeatAttrValue = ref(false)
const confirmAttrValue = async (formEl: FormInstance | undefined) => {
if (loadingByAttrValue.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
if (formAttrValueData.type != 'text') {
if (formAttrValueData.child.length == 0) {
ElMessage({
type: 'warning',
message: `${t('attrValueNamePlaceholder')}`,
})
return
}
for (let i = 0; i < formAttrValueData.child.length; i++) {
if (formAttrValueData.child[i].name == '') {
ElMessage({
type: 'warning',
message: `${t('attrValueNamePlaceholder')}`,
if (loadingByAttrValue.value || !formEl) return
await formEl.validate(async (valid) => {
if (valid) {
if(formAttrValueData.type != 'text'){
if(formAttrValueData.child.length == 0){
ElMessage({type: 'warning', message: `${t('attrValueNamePlaceholder')}`})
return;
}
for(let i=0;i<formAttrValueData.child.length;i++){
if(formAttrValueData.child[i].name == ''){
ElMessage({type: 'warning', message: `${t('attrValueNamePlaceholder')}`})
break;
}
}
}
if (repeatAttrValue.value) return
repeatAttrValue.value = true
formAttrValueData.child.sort((a: any, b: any) => {
return b.sort - a.sort
});
loadingByAttrValue.value = true
if(actionAttrValueId.value == -1) {
attrInfo.attr_value_format.push(formAttrValueData)
}else{
for (let i = 0; i < attrInfo.attr_value_format.length; i++) {
if (attrInfo.attr_value_format[i].attr_value_id == actionAttrValueId.value) {
attrInfo.attr_value_format[i] = cloneDeep(formAttrValueData)
break;
}
}
}
let data = {
attr_id : attrId.value,
attr_value_format : JSON.stringify(attrInfo.attr_value_format)
};
modifyAttrValue(data).then(res => {
loadingByAttrValue.value = false
showDialogByAttrValue.value = false
repeatAttrValue.value = false
loadAttrInfo()
}).catch(err => {
loadingByAttrValue.value = false
repeatAttrValue.value = false
})
break
}
}
}
if (repeatAttrValue.value) return
repeatAttrValue.value = true
formAttrValueData.child.sort((a: any, b: any) => {
return b.sort - a.sort
})
loadingByAttrValue.value = true
if (actionAttrValueId.value == -1) {
attrInfo.attr_value_format.push(formAttrValueData)
} else {
for (let i = 0; i < attrInfo.attr_value_format.length; i++) {
if (
attrInfo.attr_value_format[i].attr_value_id ==
actionAttrValueId.value
) {
attrInfo.attr_value_format[i] = cloneDeep(formAttrValueData)
break
}
}
}
let data = {
attr_id: attrId.value,
attr_value_format: JSON.stringify(attrInfo.attr_value_format),
}
modifyAttrValue(data)
.then((res) => {
loadingByAttrValue.value = false
showDialogByAttrValue.value = false
repeatAttrValue.value = false
loadAttrInfo()
})
.catch((err) => {
loadingByAttrValue.value = false
repeatAttrValue.value = false
})
}
})
})
}
//
const deleteAttrValueEvent = (item: any, index: any) => {
formAttrValueData.child.splice(index, 1)
const deleteAttrValueEvent = (item:any,index:any)=> {
formAttrValueData.child.splice(index,1);
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

328
admin/src/addon/shop/views/goods/brand_list.vue

@ -1,132 +1,77 @@
<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('addBrand') }}
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="brandTable.searchParam"
ref="searchFormRef"
>
<el-form-item :label="t('brandName')" prop="brand_name">
<el-input
v-model.trim="brandTable.searchParam.brand_name"
:placeholder="t('brandNamePlaceholder')"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadBrandList()">{{
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="brandTable.data"
size="large"
v-loading="brandTable.loading"
@sort-change="sortChange"
>
<template #empty>
<span>{{ !brandTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="brand_name"
:label="t('brandName')"
min-width="120"
/>
<el-table-column :label="t('logo')" min-width="120">
<template #default="{ row }">
<div class="h-[30px]">
<el-image
class="w-[30px] h-[30px]"
:src="img(row.logo)"
fit="contain"
>
<template #error>
<div class="image-slot">
<img
class="w-[30px] h-[30px]"
src="@/addon/shop/assets/brand_default.png"
/>
</div>
</template>
</el-image>
</div>
</template>
</el-table-column>
<el-table-column
prop="sort"
:label="t('sort')"
min-width="120"
sortable="custom"
>
<template #default="{ row }">
<el-input
v-model.trim="row.sort"
class="!w-[100px]"
maxlength="8"
@blur="sortInputListener(row.sort, row)"
/>
</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.brand_id)"
>{{ t('delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="brandTable.page"
v-model:page-size="brandTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="brandTable.total"
@size-change="loadBrandList()"
@current-change="loadBrandList"
/>
</div>
</div>
<brand-edit ref="editBrandDialog" @complete="loadBrandList" />
</el-card>
</div>
<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('addBrand') }}
</el-button>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="brandTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('brandName')" prop="brand_name">
<el-input v-model.trim="brandTable.searchParam.brand_name" :placeholder="t('brandNamePlaceholder')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadBrandList()">{{ 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="brandTable.data" size="large" v-loading="brandTable.loading" @sort-change="sortChange">
<template #empty>
<span>{{ !brandTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column prop="brand_name" :label="t('brandName')" min-width="120" />
<el-table-column :label="t('logo')" min-width="120">
<template #default="{ row }">
<div class="h-[30px]">
<el-image class="w-[30px] h-[30px] " :src="img(row.logo)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[30px] h-[30px]" src="@/addon/shop/assets/brand_default.png" />
</div>
</template>
</el-image>
</div>
</template>
</el-table-column>
<el-table-column prop="sort" :label="t('sort')" min-width="120" sortable="custom">
<template #default="{ row }">
<el-input v-model.trim="row.sort" class="!w-[100px]" maxlength="8" @blur="sortInputListener(row.sort, row)" />
</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.brand_id)">{{ t('delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="brandTable.page" v-model:page-size="brandTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="brandTable.total"
@size-change="loadBrandList()" @current-change="loadBrandList" />
</div>
</div>
<brand-edit ref="editBrandDialog" @complete="loadBrandList" />
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { t } from '@/lang'
import {
getBrandPageList,
deleteBrand,
modifyBrandSort,
} from '@/addon/shop/api/goods'
import { getBrandPageList, deleteBrand, modifyBrandSort } from '@/addon/shop/api/goods'
import { img, debounce } from '@/utils/common'
import { ElMessageBox, FormInstance, ElMessage } from 'element-plus'
import BrandEdit from '@/addon/shop/views/goods/components/brand-edit.vue'
@ -136,54 +81,52 @@ const route = useRoute()
const pageName = route.meta.title
const brandTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
brand_name: '',
order: '',
sort: '',
},
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
brand_name: '',
order: '',
sort: ''
}
})
const searchFormRef = ref<FormInstance>()
//
const sortChange = (event: any) => {
let sort = ''
if (event.order == 'ascending') {
sort = 'asc'
} else if (event.order == 'descending') {
sort = 'desc'
}
if (sort) {
brandTable.searchParam.order = event.prop
brandTable.searchParam.sort = sort
}
loadBrandList()
let sort = ''
if (event.order == 'ascending') {
sort = 'asc'
} else if (event.order == 'descending') {
sort = 'desc'
}
if (sort) {
brandTable.searchParam.order = event.prop
brandTable.searchParam.sort = sort
}
loadBrandList()
}
/**
* 获取商品品牌列表
*/
const loadBrandList = (page: number = 1) => {
brandTable.loading = true
brandTable.page = page
getBrandPageList({
page: brandTable.page,
limit: brandTable.limit,
...brandTable.searchParam,
})
.then((res) => {
brandTable.loading = false
brandTable.data = res.data.data
brandTable.total = res.data.total
})
.catch(() => {
brandTable.loading = false
brandTable.loading = true
brandTable.page = page
getBrandPageList({
page: brandTable.page,
limit: brandTable.limit,
...brandTable.searchParam
}).then(res => {
brandTable.loading = false
brandTable.data = res.data.data
brandTable.total = res.data.total
}).catch(() => {
brandTable.loading = false
})
}
loadBrandList()
@ -194,8 +137,8 @@ const editBrandDialog: Record<string, any> | null = ref(null)
* 添加商品品牌
*/
const addEvent = () => {
editBrandDialog.value.setFormData()
editBrandDialog.value.showDialog = true
editBrandDialog.value.setFormData()
editBrandDialog.value.showDialog = true
}
/**
@ -203,49 +146,52 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
editBrandDialog.value.setFormData(data)
editBrandDialog.value.showDialog = true
editBrandDialog.value.setFormData(data)
editBrandDialog.value.showDialog = true
}
/**
* 删除商品品牌
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('brandDeleteTips'), t('warning'), {
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteBrand(id)
.then(() => {
loadBrandList()
})
.catch(() => {})
})
ElMessageBox.confirm(t('brandDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteBrand(id).then(() => {
loadBrandList()
}).catch(() => {
})
})
}
//
const sortInputListener = debounce((sort, row) => {
if (isNaN(sort) || !/^\d{0,8}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${t('sortTips')}`,
if (isNaN(sort) || !/^\d{0,8}$/.test(sort)) {
ElMessage({
type: 'warning',
message: `${ t('sortTips') }`
})
return
}
if (sort > 99999999) {
row.sort = 99999999
}
modifyBrandSort({
brand_id: row.brand_id,
sort
}).then((res) => {
})
return
}
if (sort > 99999999) {
row.sort = 99999999
}
modifyBrandSort({
brand_id: row.brand_id,
sort,
}).then((res) => {})
})
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadBrandList()
if (!formEl) return
formEl.resetFields()
loadBrandList()
}
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
</style>

399
admin/src/addon/shop/views/goods/category.vue

@ -1,118 +1,75 @@
<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-page-title">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addCategory') }}
</el-button>
</div>
<el-tabs
class="demo-tabs"
model-value="/shop/goods/category"
@tab-change="handleClick"
>
<el-tab-pane
:label="t('tabGoodsCategory')"
name="/shop/goods/category"
/>
<el-tab-pane
:label="t('tabGoodsCategoryConfig')"
name="/shop/goods/category/config"
/>
</el-tabs>
<div class="mt-[10px]">
<el-table
:data="categoryTable.data"
ref="tableRef"
size="large"
v-loading="categoryTable.loading"
row-key="category_id"
:tree-props="{ hasChildren: 'hasChildren', children: 'child_list' }"
>
<template #empty>
<span>{{ !categoryTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column :label="t('categoryName')" min-width="120">
<template #default="{ row }">
<i class="order-0 iconfont icontuodong vues-rank mr-[8px]"></i>
<span class="order-2">{{ row.category_name }}</span>
</template>
</el-table-column>
<el-table-column :label="t('image')" 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-column prop="is_show" :label="t('isShow')" width="400">
<template #default="{ row }">
<el-tag
class="cursor-pointer"
:type="row.is_show != 2 ? 'success' : 'danger'"
@click="showClick(row)"
>{{ row.is_show != 2 ? '是' : '否' }}</el-tag
>
</template>
</el-table-column>
<el-table-column prop="sort" :label="t('sort')" width="120" />
<el-table-column
:label="t('operation')"
fixed="right"
align="right"
width="200"
>
<template #default="{ row }">
<el-button type="primary" link @click="spreadEvent(row)">{{
t('spreadGoodsCategory')
}}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="deleteEvent(row)">{{
t('delete')
}}</el-button>
</template>
</el-table-column>
</el-table>
</div>
<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-page-title">{{ pageName }}</span>
<el-button type="primary" @click="addEvent">
{{ t('addCategory') }}
</el-button>
</div>
<el-tabs class="demo-tabs" model-value="/shop/goods/category" @tab-change="handleClick">
<el-tab-pane :label="t('tabGoodsCategory')" name="/shop/goods/category" />
<el-tab-pane :label="t('tabGoodsCategoryConfig')" name="/shop/goods/category/config" />
</el-tabs>
<div class="mt-[10px]">
<el-table :data="categoryTable.data" ref="tableRef" size="large" v-loading="categoryTable.loading" row-key="category_id" :tree-props="{ hasChildren: 'hasChildren', children: 'child_list' }">
<template #empty>
<span>{{ !categoryTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column :label="t('categoryName')" min-width="120">
<template #default="{ row }">
<i class="order-0 iconfont icontuodong vues-rank mr-[8px]"></i>
<span class="order-2">{{ row.category_name }}</span>
</template>
</el-table-column>
<el-table-column :label="t('image')" 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-column prop="is_show" :label="t('isShow')" width="400">
<template #default="{ row }">
<el-tag class="cursor-pointer" :type="row.is_show != 2 ? 'success' : 'danger'" @click="showClick(row)">{{ row.is_show != 2 ? '' : '' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="sort" :label="t('sort')" width="120" />
<el-table-column :label="t('operation')" fixed="right" align="right" width="200">
<template #default="{ row }">
<el-button type="primary" link @click="spreadEvent(row)">{{ t('spreadGoodsCategory') }}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
<category-edit ref="editCategoryDialog" @complete="loadCategoryList" />
</el-card>
</el-table>
</div>
<!-- 商品分类推广弹出框 -->
<goods-category-spread-popup ref="goodsCategorySpreadPopupRef" />
</div>
<category-edit ref="editCategoryDialog" @complete="loadCategoryList" />
</el-card>
<!-- 商品分类推广弹出框 -->
<goods-category-spread-popup ref="goodsCategorySpreadPopupRef" />
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, nextTick } from 'vue'
import { t } from '@/lang'
import {
getCategoryTree,
deleteCategory,
updateCategory,
editCategory,
} from '@/addon/shop/api/goods'
import { getCategoryTree, deleteCategory, updateCategory, editCategory } from '@/addon/shop/api/goods'
import { img } from '@/utils/common'
import { ElMessageBox } from 'element-plus'
import categoryEdit from '@/addon/shop/views/goods/components/category-edit.vue'
import goodsCategorySpreadPopup from '@/addon/shop/views/goods/components/goods-category-spread-popup.vue'
import { useRoute, useRouter } from 'vue-router'
import { useRoute,useRouter } from 'vue-router'
import Sortable from 'sortablejs'
import { useTemplateRefsList } from '@vueuse/core'
import { cloneDeep } from 'lodash-es'
@ -121,132 +78,114 @@ const route = useRoute()
const pageName = route.meta.title
const tableRef = useTemplateRefsList<HTMLElement>()
const categoryTable = reactive({
loading: true,
data: [],
loading: true,
data: []
})
onMounted(() => {
nextTick(() => {
rowDrop()
})
loadCategoryList()
nextTick(() => {
rowDrop()
})
loadCategoryList()
})
//
const activeRows = ref<any[]>([])
//
const rowDrop = () => {
const tbody = tableRef.value.$el.querySelector(
'.el-table__body-wrapper tbody'
)
Sortable.create(tbody, {
handle: '.vues-rank',
animation: 300,
onMove: ({ dragged, related }) => {
const oldRow = activeRows.value[dragged.rowIndex] //
const newRow = activeRows.value[related.rowIndex] //
if (oldRow.pid !== newRow.pid) {
// id
return false //
}
},
onStart: () => {
//
activeRows.value = treeToTile(cloneDeep(categoryTable.data)) //
},
onEnd: (e) => {
const oldRow = activeRows.value[e.oldIndex] //
const newRow = activeRows.value[e.newIndex] //
const tbody = tableRef.value.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(tbody, {
handle: '.vues-rank',
animation: 300,
onMove: ({ dragged, related }) => {
const oldRow = activeRows.value[dragged.rowIndex] //
const newRow = activeRows.value[related.rowIndex] //
if (oldRow.pid !== newRow.pid) { // id
return false //
}
},
onStart: () => { //
activeRows.value = treeToTile(cloneDeep(categoryTable.data)) //
},
onEnd: e => {
const oldRow = activeRows.value[e.oldIndex] //
const newRow = activeRows.value[e.newIndex] //
if (e.oldIndex === e.newIndex || oldRow.pid !== newRow.pid) return false
if (e.oldIndex === e.newIndex || oldRow.pid !== newRow.pid) return false
const index = activeRows.value.indexOf(oldRow)
const index = activeRows.value.indexOf(oldRow)
if (index < 0) return false
if (index < 0) return false
const currRow = activeRows.value.splice(e.oldIndex, 1)[0]
activeRows.value.splice(e.newIndex, 0, currRow)
const pid = newRow.pid
const currentRows = activeRows.value
.filter((c) => c.pid === pid)
?.map((item, index) => {
if (item.level === 1 && item.category_id === currRow.category_id) {
categoryTable.data = categoryTable.data.filter(
(c) => c.category_id !== currRow.category_id
)
categoryTable.data.splice(index, 0, currRow)
}
if (item.level === 2 && item.category_id === currRow.category_id) {
const treeIndex = categoryTable.data.findIndex(
(el) => el.category_id === item.pid
)
const obj = cloneDeep(
categoryTable.data[treeIndex].child_list.filter(
(c) => c.category_id !== currRow.category_id
)
)
categoryTable.data[treeIndex].child_list = []
categoryTable.data[treeIndex].child_list.push(...obj)
categoryTable.data[treeIndex].child_list.splice(index, 0, currRow)
}
return {
category_id: item.category_id, //
sort: 9999 - index,
}
})
updateCategoryFn({ category_sort_array: currentRows })
},
})
const currRow = activeRows.value.splice(e.oldIndex, 1)[0]
activeRows.value.splice(e.newIndex, 0, currRow)
const pid = newRow.pid
const currentRows = activeRows.value.filter(c => c.pid === pid)?.map((item, index) => {
if (item.level === 1 && item.category_id === currRow.category_id) {
categoryTable.data = categoryTable.data.filter(c => c.category_id !== currRow.category_id)
categoryTable.data.splice(index, 0, currRow)
}
if (item.level === 2 && item.category_id === currRow.category_id) {
const treeIndex = categoryTable.data.findIndex(el => el.category_id === item.pid)
const obj = cloneDeep(categoryTable.data[treeIndex].child_list.filter(c => c.category_id !== currRow.category_id))
categoryTable.data[treeIndex].child_list = []
categoryTable.data[treeIndex].child_list.push(...obj)
categoryTable.data[treeIndex].child_list.splice(index, 0, currRow)
}
return {
category_id: item.category_id, //
sort: 9999 - index
}
})
updateCategoryFn({ category_sort_array: currentRows })
}
})
}
/**
* 将树数据转化为平铺数据
* @param <Array> treeData当前要转的id
* @param <String> childKey 子级字段
* @return <Array> 返回数据
*/
const treeToTile = (treeData: any, childKey = 'child_list') => {
const arr: Array<any> = []
const expanded = (data: any) => {
if (data && data.length > 0) {
data
.filter((d: any) => d)
.forEach((e: any) => {
arr.push(e)
expanded(e[childKey] || [])
})
* 将树数据转化为平铺数据
* @param <Array> treeData当前要转的id
* @param <String> childKey 子级字段
* @return <Array> 返回数据
*/
const treeToTile = (treeData:any, childKey = 'child_list') => {
const arr:Array<any> = []
const expanded = (data:any) => {
if (data && data.length > 0) {
data.filter((d:any) => d).forEach((e:any) => {
arr.push(e)
expanded(e[childKey] || [])
})
}
}
}
expanded(treeData)
return arr
expanded(treeData)
return arr
}
/**
* 获取商品分类列表
*/
const loadCategoryList = () => {
categoryTable.loading = true
categoryTable.loading = true
getCategoryTree()
.then((res) => {
categoryTable.loading = false
categoryTable.data = res.data
})
.catch(() => {
categoryTable.loading = false
getCategoryTree().then(res => {
categoryTable.loading = false
categoryTable.data = res.data
}).catch(() => {
categoryTable.loading = false
})
}
const updateCategoryFn = (params: any) => {
updateCategory(params).then((res) => {
loadCategoryList()
})
updateCategory(params).then(res => {
loadCategoryList()
})
}
const showClick = (row: any) => {
row.is_show = row.is_show === 1 ? 2 : 1
const obj = cloneDeep(row)
delete obj.child_list
editCategory(obj)
row.is_show = row.is_show === 1 ? 2 : 1
const obj = cloneDeep(row)
delete obj.child_list
editCategory(obj)
}
const editCategoryDialog: Record<string, any> | null = ref(null)
@ -254,8 +193,8 @@ const editCategoryDialog: Record<string, any> | null = ref(null)
* 添加商品分类
*/
const addEvent = () => {
editCategoryDialog.value.setFormData()
editCategoryDialog.value.showDialog = true
editCategoryDialog.value.setFormData()
editCategoryDialog.value.showDialog = true
}
/**
@ -263,59 +202,57 @@ const addEvent = () => {
* @param data
*/
const editEvent = (data: any) => {
editCategoryDialog.value.setFormData(data)
editCategoryDialog.value.showDialog = true
editCategoryDialog.value.setFormData(data)
editCategoryDialog.value.showDialog = true
}
/**
* 删除商品分类
*/
const deleteEvent = (row: any) => {
ElMessageBox.confirm(
!row.child_list || !row.child_list.length
? t('categoryDeleteTips')
: t('categoryDeleteTips1'),
t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}
).then(() => {
deleteCategory(row.category_id)
.then(() => {
loadCategoryList()
})
.catch(() => {})
})
ElMessageBox.confirm(!row.child_list || !row.child_list.length ? t('categoryDeleteTips') : t('categoryDeleteTips1'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning'
}
).then(() => {
deleteCategory(row.category_id).then(() => {
loadCategoryList()
}).catch(() => {
})
})
}
// 广
const goodsCategorySpreadPopupRef: any = ref(null)
const spreadEvent = (data: any) => {
goodsCategorySpreadPopupRef.value.show(data)
goodsCategorySpreadPopupRef.value.show(data)
}
const router = useRouter()
const handleClick = (path: string) => {
router.push({ path })
router.push({ path })
}
</script>
<style lang="scss" scoped>
:deep(.el-table__row) {
> .el-table__cell:nth-child(1) {
.cell {
display: flex;
align-items: center;
> .el-table__cell:nth-child(1) {
.cell {
display: flex;
align-items: center;
.el-table__expand-icon,
.el-table__placeholder {
order: 1;
}
}
.el-table__expand-icon,
.el-table__placeholder {
order: 1;
}
}
}
}
</style>

439
admin/src/addon/shop/views/goods/category_config.vue

@ -1,109 +1,46 @@
<template>
<div class="main-container pt-[20px] bg-[#fff]">
<div class="flex ml-[18px] justify-between items-center mb-[5px]">
<span class="text-page-title">{{ pageName }}</span>
</div>
<el-tabs
class="demo-tabs mx-[18px]"
model-value="/shop/goods/category/config"
@tab-change="handleClick"
>
<el-tab-pane :label="t('tabGoodsCategory')" name="/shop/goods/category" />
<el-tab-pane
:label="t('tabGoodsCategoryConfig')"
name="/shop/goods/category/config"
/>
</el-tabs>
<el-form
v-if="Object.keys(formData).length"
:model="formData"
label-width="170"
ref="formRef"
:rules="rules"
class="page-form"
v-loading="loading"
>
<el-card class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-[16px] pl-[15px]">
{{ t('categoryTemplate') }}
</h3>
<el-form-item :label="t('categoryType')">
<el-radio-group
class="mx-[10px]"
v-model="formData.level"
@change="formData.template = 'style-1'"
>
<el-radio :label="1">{{ t('categorystyleOne') }}</el-radio>
<el-radio :label="2">{{ t('categorystyleTwo') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('categoryTemplate')">
<template
v-for="(item, index) in config['level_' + formData.level]"
:key="index"
>
<div
:class="[
'w-[150px] border-[1px] border-[#ededed] border-solid overflow-hidden text-[#ededed] rounded-[4px] mr-[20px] relative',
formData.template === item.template
? 'border-color text-color'
: '',
]"
@click="levelChange(item.template)"
>
<img
class="w-[100%]"
:src="img(item.preview)"
fit-object="contain"
/>
<span
class="iconfont iconicon-selected absolute right-0 bottom-[-8px]"
></span>
</div>
</template>
</el-form-item>
</el-card>
<el-card class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-[16px] pl-[15px]">
{{ t('pageSettings') }}
</h3>
<el-form-item :label="t('pageTitle')" prop="page_title">
<el-input
v-model.trim="formData.page_title"
clearable
:placeholder="t('pageTitlePlaceholder')"
class="input-width"
maxlength="10"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('searchControl')">
<el-radio-group class="mx-[10px]" v-model="formData.search.control">
<el-radio :label="1">{{ t('open') }}</el-radio>
<el-radio :label="0">{{ t('close') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="formData.search.control"
:label="t('searchTitle')"
prop="search.title"
>
<el-input
v-model.trim="formData.search.title"
clearable
:placeholder="t('searchTitlePlaceholder')"
class="input-width"
maxlength="12"
show-word-limit
/>
</el-form-item>
<template
v-if="
formData.level != 2 ||
(formData.level === 2 && formData.template != 'style-1')
"
>
<!-- <el-form-item :label="t('sort')" prop="sort">
<div class="main-container pt-[20px] bg-[#fff]" >
<div class="flex ml-[18px] justify-between items-center mb-[5px]">
<span class="text-page-title">{{ pageName }}</span>
</div>
<el-tabs class="demo-tabs mx-[18px]" model-value="/shop/goods/category/config" @tab-change="handleClick">
<el-tab-pane :label="t('tabGoodsCategory')" name="/shop/goods/category" />
<el-tab-pane :label="t('tabGoodsCategoryConfig')" name="/shop/goods/category/config" />
</el-tabs>
<el-form v-if="Object.keys(formData).length" :model="formData" label-width="170" ref="formRef" :rules="rules" class="page-form" v-loading="loading">
<el-card class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-[16px] pl-[15px]">{{ t('categoryTemplate') }}</h3>
<el-form-item :label="t('categoryType')">
<el-radio-group class="mx-[10px]" v-model="formData.level" @change="formData.template='style-1'">
<el-radio :label="1">{{ t('categorystyleOne') }}</el-radio>
<el-radio :label="2">{{ t('categorystyleTwo') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('categoryTemplate')">
<template v-for="(item,index) in config['level_'+formData.level]" :key="index">
<div :class="['w-[150px] border-[1px] border-[#ededed] border-solid overflow-hidden text-[#ededed] rounded-[4px] mr-[20px] relative', formData.template ===item.template ? 'border-color text-color' : '']" @click="levelChange(item.template)">
<img class="w-[100%]" :src="img(item.preview)" fit-object="contain" />
<span class="iconfont iconicon-selected absolute right-0 bottom-[-8px]"></span>
</div>
</template>
</el-form-item>
</el-card>
<el-card class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-[16px] pl-[15px]">{{ t('pageSettings') }}</h3>
<el-form-item :label="t('pageTitle')" prop="page_title">
<el-input v-model.trim="formData.page_title" clearable :placeholder="t('pageTitlePlaceholder')" class="input-width" maxlength="10" show-word-limit />
</el-form-item>
<el-form-item :label="t('searchControl')">
<el-radio-group class="mx-[10px]" v-model="formData.search.control">
<el-radio :label="1">{{ t('open') }}</el-radio>
<el-radio :label="0">{{ t('close') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.search.control" :label="t('searchTitle')" prop="search.title">
<el-input v-model.trim="formData.search.title" clearable :placeholder="t('searchTitlePlaceholder')" class="input-width" maxlength="12" show-word-limit />
</el-form-item>
<template v-if="formData.level!=2||(formData.level===2&&formData.template != 'style-1')">
<!-- <el-form-item :label="t('sort')" prop="sort">
<el-select v-model="formData.sort" clearable :placeholder="t('sortPlaceholder')"
class="input-width">
<el-option label="综合" value="default" />
@ -111,99 +48,61 @@
<el-option label="价格" value="price" />
</el-select>
</el-form-item> -->
<!-- <el-form-item :label="t('goodsStyle')">
<!-- <el-form-item :label="t('goodsStyle')">
<el-radio-group class="mx-[10px]" v-model="formData.goods.style">
<el-radio label="single-cols">{{ t('singleCols') }}</el-radio>
<el-radio label="double-cols">{{ t('doubleCols') }}</el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item :label="t('cartControl')">
<el-radio-group class="mx-[10px]" v-model="formData.cart.control">
<el-radio :label="1">{{ t('show') }}</el-radio>
<el-radio :label="0">{{ t('hidden') }}</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="formData.cart.control">
<el-form-item :label="t('cartStyle')" class="carStyle">
<div class="flex items-center">
<div
:class="[
'flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]',
formData.cart.style === 'style-1' ? '!border-[1px]' : '',
]"
@click="carStyleClick(1)"
>
<div
class="text-[#fff] bg-color h-[20px] text-[12px] px-[10px] leading-[20px] rounded-[10px]"
>
{{ formData.cart.text }}
</div>
</div>
<!-- <div :class="['flex items-center justify-center w-[50px] h-[50px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]', formData.cart.style === 'style-2' ? '!border-[1px]' : '']"
<el-form-item :label="t('cartControl')">
<el-radio-group class="mx-[10px]" v-model="formData.cart.control">
<el-radio :label="1">{{ t('show') }}</el-radio>
<el-radio :label="0">{{ t('hidden') }}</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="formData.cart.control">
<el-form-item :label="t('cartStyle')" class="carStyle">
<div class="flex items-center">
<div :class="['flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]', formData.cart.style === 'style-1' ? '!border-[1px]' : '']" @click="carStyleClick(1)">
<div class="text-[#fff] bg-color h-[20px] text-[12px] px-[10px] leading-[20px] rounded-[10px]">
{{ formData.cart.text }}
</div>
</div>
<!-- <div :class="['flex items-center justify-center w-[50px] h-[50px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]', formData.cart.style === 'style-2' ? '!border-[1px]' : '']"
@click="carStyleClick(2)">
<el-icon size="30px" class="text-color">
<CirclePlusFilled />
</el-icon>
</div> -->
<div
:class="[
'flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]',
formData.cart.style === 'style-3' ? '!border-[1px]' : '',
]"
@click="carStyleClick(3)"
>
<span
class="text-color nc-iconfont nc-icon-gouwucheV6xx6 !text-[24px]"
></span>
</div>
<div
:class="[
'flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]',
formData.cart.style === 'style-4' ? '!border-[1px]' : '',
]"
@click="carStyleClick(4)"
>
<div
class="text-[#fff] bg-color h-[30px] w-[30px] leading-[30px] rounded-[30px] text-center"
>
<span
class="nc-iconfont nc-icon-gouwucheV6xx6 !text-[20px]"
></span>
</div>
</div>
</div>
</el-form-item>
<el-form-item
v-if="formData.cart.style === 'style-1'"
prop="cart.text"
>
<el-input
v-model.trim="formData.cart.text"
clearable
:placeholder="t('cartTextPlaceholder')"
class="input-width"
maxlength="3"
show-word-limit
/>
</el-form-item>
<el-form-item :label="t('cartEvent')">
<el-radio-group class="mx-[10px]" v-model="formData.cart.event">
<el-radio label="detail">{{ t('detail') }}</el-radio>
<el-radio label="cart">{{ t('cart') }}</el-radio>
</el-radio-group>
</el-form-item>
</template>
</template>
</el-card>
</el-form>
<div class="fixed-footer-wrap">
<div class="fixed-footer">
<el-button type="primary" @click="onSave(formRef)">{{
t('save')
}}</el-button>
</div>
<div :class="['flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]', formData.cart.style === 'style-3' ? '!border-[1px]' : '']" @click="carStyleClick(3)">
<span class="text-color nc-iconfont nc-icon-gouwucheV6xx6 !text-[24px]"></span>
</div>
<div :class="['flex items-center justify-center w-[65px] h-[65px] border-0 border-color rounded-[4px] border-solid box-border cursor-pointer mr-[15px]', formData.cart.style === 'style-4' ? '!border-[1px]' : '']" @click="carStyleClick(4)">
<div class="text-[#fff] bg-color h-[30px] w-[30px] leading-[30px] rounded-[30px] text-center">
<span class="nc-iconfont nc-icon-gouwucheV6xx6 !text-[20px]"></span>
</div>
</div>
</div>
</el-form-item>
<el-form-item v-if="formData.cart.style === 'style-1'" prop="cart.text">
<el-input v-model.trim="formData.cart.text" clearable :placeholder="t('cartTextPlaceholder')" class="input-width" maxlength="3" show-word-limit />
</el-form-item>
<el-form-item :label="t('cartEvent')">
<el-radio-group class="mx-[10px]" v-model="formData.cart.event">
<el-radio label="detail">{{ t('detail') }}</el-radio>
<el-radio label="cart">{{ t('cart') }}</el-radio>
</el-radio-group>
</el-form-item>
</template>
</template>
</el-card>
</el-form>
<div class="fixed-footer-wrap">
<div class="fixed-footer">
<el-button type="primary" @click="onSave(formRef)">{{ t('save') }}</el-button>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
@ -211,131 +110,127 @@ import { reactive, ref, computed } from 'vue'
import { t } from '@/lang'
import { getCategoryConfig, setCategoryConfig } from '@/addon/shop/api/goods'
import { img } from '@/utils/common'
import { useRoute, useRouter } from 'vue-router'
import { useRoute,useRouter } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
interface formDataType {
level: string | number
template: string
page_title: string
search: {
title: string
control: number | string
}
sort: string
cart: {
control: number
style: string
text: string
event: string
}
level: string|number
template: string
page_title: string
search: {
title: string
control: number|string
}
sort: string
cart: {
control: number
style: string
text: string
event: string
}
}
const formData = ref<formDataType | any>({})
const formData = ref<formDataType|any>({})
const loading = ref(false)
const rules = computed(() => {
return {
page_title: [
{ required: true, message: t('pageTitlePlaceholder'), trigger: 'blur' },
],
'search.title': [
{ required: true, message: t('searchTitlePlaceholder'), trigger: 'blur' },
],
sort: [
{ required: true, message: t('sortPlaceholder'), trigger: 'change' },
],
'cart.text': [
{ required: true, message: t('cartTextPlaceholder'), trigger: 'blur' },
],
}
return {
page_title: [
{ required: true, message: t('pageTitlePlaceholder'), trigger: 'blur' }
],
'search.title': [
{ required: true, message: t('searchTitlePlaceholder'), trigger: 'blur' }
],
sort: [
{ required: true, message: t('sortPlaceholder'), trigger: 'change' }
],
'cart.text': [
{ required: true, message: t('cartTextPlaceholder'), trigger: 'blur' }
]
}
})
interface configType {
level_1: {
template: string
preview: string
}[]
level_2: {
template: string
preview: string
}[]
level_1: {
template: string
preview: string
}[]
level_2: {
template: string
preview: string
}[]
}
const config = reactive<configType | any>({
level_1: [
{
template: 'style-1',
preview: 'addon/shop/category_style1_1.png',
},
],
level_2: [
{
template: 'style-1',
preview: 'addon/shop/category_style2_1.png',
},
{
template: 'style-2',
preview: 'addon/shop/category_style2_2.png',
},
],
const config = reactive<configType|any>({
level_1: [
{
template: 'style-1',
preview: 'addon/shop/category_style1_1.png'
}
],
level_2: [
{
template: 'style-1',
preview: 'addon/shop/category_style2_1.png'
},
{
template: 'style-2',
preview: 'addon/shop/category_style2_2.png'
}
]
})
const getCategoryConfigFn = () => {
loading.value = true
getCategoryConfig()
.then((res) => {
formData.value = res.data
loading.value = false
})
.catch(() => {
loading.value = false
loading.value = true
getCategoryConfig().then(res => {
formData.value = res.data
loading.value = false
}).catch(() => {
loading.value = false
})
}
getCategoryConfigFn()
const levelChange = (value: any) => {
formData.value.template = value
formData.value.template = value
}
const carStyleClick = (value: any) => {
formData.value.cart.style = 'style-' + value
formData.value.cart.style = 'style-' + value
}
const formRef = ref()
const onSave = async (formEl: any) => {
await formEl.validate(async (valid: any) => {
if (valid) {
loading.value = true
setCategoryConfig(formData.value)
.then((res) => {
getCategoryConfigFn()
})
.catch(() => {
loading.value = false
})
}
})
await formEl.validate(async (valid:any) => {
if (valid) {
loading.value = true
setCategoryConfig(formData.value).then(res => {
getCategoryConfigFn()
}).catch(() => {
loading.value = false
})
}
})
}
const router = useRouter()
const handleClick = (path: string) => {
router.push({ path })
router.push({ path })
}
</script>
<style lang="scss" scoped>
.border-color {
border-color: var(--el-color-primary);
border-color: var(--el-color-primary);
}
.text-color {
color: var(--el-color-primary);
color: var(--el-color-primary);
}
.bg-color {
background-color: var(--el-color-primary);
background-color: var(--el-color-primary);
}
.carStyle {
:deep(.el-form-item__label) {
height: 50px;
line-height: 50px;
}
:deep(.el-form-item__label) {
height: 50px;
line-height: 50px;
}
}
</style>

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

Loading…
Cancel
Save