!179 fix: 删除china2相关的地图json

Merge pull request !179 from 痴货/master
This commit is contained in:
芋道源码
2025-07-23 05:08:38 +00:00
committed by Gitee
97 changed files with 4922 additions and 1138 deletions

View File

@@ -4,7 +4,7 @@ import type { MallBrandApi } from '#/api/mall/product/brand';
import { Page, useVbenModal } from '@vben/common-ui';
import { ElLoading, ElMessage } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteBrand, getBrandPage } from '#/api/mall/product/brand';
@@ -35,17 +35,15 @@ function handleEdit(row: MallBrandApi.Brand) {
/** 删除品牌 */
async function handleDelete(row: MallBrandApi.Brand) {
const loadingInstance = ElLoading.service({
text: $t('ui.actionMessage.deleting', [row.name]),
fullscreen: true,
// 二次确认
await ElMessageBox.confirm('确定删除该品牌吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
try {
await deleteBrand(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
} finally {
loadingInstance.close();
}
await deleteBrand(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
}
const [Grid, gridApi] = useVbenVxeGrid({

View File

@@ -7,7 +7,7 @@ import { useRouter } from 'vue-router';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { ElLoading, ElMessage } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteCategory, getCategoryList } from '#/api/mall/product/category';
@@ -52,17 +52,14 @@ const handleViewSpu = (id: number) => {
/** 删除分类 */
async function handleDelete(row: MallCategoryApi.Category) {
const loadingInstance = ElLoading.service({
text: $t('ui.actionMessage.deleting', [row.name]),
fullscreen: true,
await ElMessageBox.confirm('确定删除该分类吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
try {
await deleteCategory(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
} finally {
loadingInstance.close();
}
await deleteCategory(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
}
/** 切换树形展开/收缩状态 */

View File

@@ -7,7 +7,7 @@ import type { MallPropertyApi } from '#/api/mall/product/property';
import { useVbenModal } from '@vben/common-ui';
import { ElLoading, ElMessage } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteProperty, getPropertyPage } from '#/api/mall/product/property';
@@ -40,17 +40,14 @@ function handleEdit(row: any) {
/** 删除属性 */
async function handleDelete(row: MallPropertyApi.Property) {
const loadingInstance = ElLoading.service({
text: $t('ui.actionMessage.deleting', [row.name]),
fullscreen: true,
await ElMessageBox.confirm('确定删除该属性吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
try {
await deleteProperty(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
} finally {
loadingInstance.close();
}
await deleteProperty(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
}
/** 表格事件 */

View File

@@ -6,7 +6,7 @@ import { watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { ElLoading, ElMessage } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
@@ -47,17 +47,14 @@ function handleEdit(row: MallPropertyApi.PropertyValue) {
/** 删除字典数据 */
async function handleDelete(row: MallPropertyApi.PropertyValue) {
const loadingInstance = ElLoading.service({
text: $t('ui.actionMessage.deleting', [row.name]),
fullscreen: true,
await ElMessageBox.confirm('确定删除该属性值吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
try {
await deletePropertyValue(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
} finally {
loadingInstance.close();
}
await deletePropertyValue(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
}
const [Grid, gridApi] = useVbenVxeGrid({

View File

@@ -1,14 +1,18 @@
<script lang="ts" setup>
import { watch } from 'vue';
import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import * as ExpressTemplateApi from '#/api/mall/trade/delivery/expressTemplate';
import { watch } from 'vue';
import { ElMessage } from 'element-plus';
import { DICT_TYPE, getIntDictOptions, DeliveryTypeEnum } from '#/utils';
import { DeliveryTypeEnum, DICT_TYPE, getIntDictOptions } from '#/utils';
const props = defineProps<{
propFormData: Object;
}>();
const emit = defineEmits(['update:activeName']);
/** 将传进来的值赋值给 formData */
watch(
() => props.propFormData,
@@ -20,7 +24,6 @@ watch(
},
);
const emit = defineEmits(['update:activeName']);
const validate = async () => {
const { valid } = await formApi.validate();
if (!valid) {
@@ -29,10 +32,10 @@ const validate = async () => {
try {
// 校验通过更新数据
Object.assign(props.propFormData, formApi.getValues());
} catch (e) {
} catch (error) {
ElMessage.error('【物流设置】不完善,请填写相关信息');
emit('update:activeName', 'delivery');
throw e; // 目的截断之后的校验
throw error; // 目的截断之后的校验
}
};
defineExpose({ validate });
@@ -62,11 +65,8 @@ const [Form, formApi] = useVbenForm({
component: 'ApiSelect',
componentProps: {
api: ExpressTemplateApi.getSimpleTemplateList,
props: {
label: 'name',
value: 'id',
children: 'children',
},
labelField: 'name',
valueField: 'id',
},
rules: 'required',
dependencies: {

View File

@@ -1,20 +1,25 @@
<script lang="ts" setup>
import { useVbenForm } from '#/adapter/form';
import { handleTree } from '@vben/utils';
import * as ProductCategoryApi from '#/api/mall/product/category';
import * as ProductBrandApi from '#/api/mall/product/brand';
import { watch } from 'vue';
import { handleTree } from '@vben/utils';
import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import * as ProductBrandApi from '#/api/mall/product/brand';
import * as ProductCategoryApi from '#/api/mall/product/category';
const props = defineProps<{
propFormData: Object;
}>();
const emit = defineEmits(['update:activeName']);
const getCategoryList = async () => {
const data = await ProductCategoryApi.getCategorySimpleList();
return handleTree(data, 'id');
};
const props = defineProps<{
propFormData: Object;
}>();
/** 将传进来的值赋值给 formData */
watch(
() => props.propFormData,
@@ -26,7 +31,6 @@ watch(
},
);
const emit = defineEmits(['update:activeName']);
const validate = async () => {
const { valid } = await formApi.validate();
if (!valid) {
@@ -35,10 +39,10 @@ const validate = async () => {
try {
// 校验通过更新数据
Object.assign(props.propFormData, formApi.getValues());
} catch (e) {
} catch (error) {
ElMessage.error('【基础设置】不完善,请填写相关信息');
emit('update:activeName', 'info');
throw e; // 目的截断之后的校验
throw error; // 目的截断之后的校验
}
};
defineExpose({ validate });
@@ -68,11 +72,9 @@ const [Form, formApi] = useVbenForm({
component: 'ApiCascader',
componentProps: {
api: getCategoryList,
props: {
label: 'name',
value: 'id',
children: 'children',
},
labelField: 'name',
valueField: 'id',
childrenField: 'children',
},
rules: 'required',
},

View File

@@ -24,7 +24,9 @@ export function useGridFormSchema(): VbenFormSchema[] {
const res = await getCategoryList({});
return handleTree(res, 'id', 'parentId', 'children');
},
fieldNames: { label: 'name', value: 'id', children: 'children' },
labelField: 'name',
valueField: 'id',
childrenField: 'children',
},
},
{

View File

@@ -13,7 +13,7 @@ import {
treeToString,
} from '@vben/utils';
import { ElDescriptions, ElLoading, ElMessage, ElTabs } from 'element-plus';
import { ElDescriptions, ElMessage, ElMessageBox, ElTabs } from 'element-plus';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getCategoryList } from '#/api/mall/product/category';
@@ -97,35 +97,31 @@ function handleEdit(row: MallSpuApi.Spu) {
/** 删除商品 */
async function handleDelete(row: MallSpuApi.Spu) {
const hideLoading = ElLoading.service({
text: $t('ui.actionMessage.deleting', [row.name]),
fullscreen: true,
await ElMessageBox.confirm('确定删除该商品吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
try {
await deleteSpu(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
} finally {
hideLoading.close();
}
await deleteSpu(row.id as number);
ElMessage.success($t('ui.actionMessage.deleteSuccess', [row.name]));
onRefresh();
}
/** 添加到仓库 / 回收站的状态 */
async function handleStatus02Change(row: MallSpuApi.Spu, newStatus: number) {
// 二次确认
const text =
newStatus === ProductSpuStatusEnum.RECYCLE.status
? '加入到回收站'
: '恢复到仓库';
confirm(`确认要"${row.name}"${text}吗?`)
.then(async () => {
await updateStatus({ id: row.id as number, status: newStatus });
ElMessage.success(`${text}成功`);
onRefresh();
})
.catch(() => {
ElMessage.error(`${text}失败`);
});
// 二次确认
await ElMessageBox.confirm(`确认要jian"${row.name}"${text}吗?`, {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
await updateStatus({ id: row.id as number, status: newStatus });
ElMessage.success(`${text}成功`);
onRefresh();
}
/** 更新状态 */

View File

@@ -1,29 +1,31 @@
<script lang="ts" setup>
import { useRouter, useRoute } from 'vue-router';
import { ref, onMounted } from 'vue';
import { floatToFixed2 } from '@vben/utils';
import * as ProductSpuApi from '#/api/mall/product/spu';
import type { MallSpuApi } from '#/api/mall/product/spu';
import * as ProductCategoryApi from '#/api/mall/product/category';
import * as ProductBrandApi from '#/api/mall/product/brand';
import { onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
import { getIntDictOptions, DICT_TYPE } from '#/utils/dict';
import { IconifyIcon } from '@vben/icons';
import { floatToFixed2 } from '@vben/utils';
import {
ElButton,
ElCard,
ElDescriptions,
ElDescriptionsItem,
ElCarousel,
ElCarouselItem,
ElImage,
ElDivider,
ElButton,
ElTabs,
ElTabPane,
ElTag,
ElBadge,
ElDescriptions,
ElDescriptionsItem,
ElEmpty,
ElImage,
ElTabPane,
ElTabs,
ElTag,
} from 'element-plus';
import { IconifyIcon } from '@vben/icons';
import * as ProductBrandApi from '#/api/mall/product/brand';
import * as ProductCategoryApi from '#/api/mall/product/category';
import * as ProductSpuApi from '#/api/mall/product/spu';
import { DICT_TYPE, getIntDictOptions } from '#/utils/dict';
interface Category {
id: number;
@@ -214,18 +216,18 @@ onMounted(async () => {
<ElTag v-if="formData.specType" type="success">多规格</ElTag>
<ElTag v-else type="info">单规格</ElTag>
<ElTag v-if="formData.subCommissionType" type="warning">分销</ElTag>
<ElTag type="danger"
>库存:
<ElTag type="danger">
库存:
{{
formData.skus?.reduce(
(sum, sku) => sum + (sku.stock || 0),
0,
) || 0
}}</ElTag
>
<ElTag type="info"
>分类: {{ getCategoryNameById(formData.categoryId) }}</ElTag
>
}}
</ElTag>
<ElTag type="info">
分类: {{ getCategoryNameById(formData.categoryId) }}
</ElTag>
</div>
</div>
</div>
@@ -236,32 +238,31 @@ onMounted(async () => {
<!-- 基本信息 -->
<ElCard shadow="never" header="商品信息" class="h-full">
<ElDescriptions :column="1" border>
<ElDescriptionsItem label="商品名称">{{
formData.name
}}</ElDescriptionsItem>
<ElDescriptionsItem label="商品名称">
{{ formData.name }}
</ElDescriptionsItem>
<ElDescriptionsItem label="商品分类">
<ElTag type="success">{{
getCategoryNameById(formData.categoryId)
}}</ElTag>
<ElTag type="success">
{{ getCategoryNameById(formData.categoryId) }}
</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="商品品牌">
<ElTag type="primary">{{
getBrandNameById(formData.brandId)
}}</ElTag>
<ElTag type="primary">
{{ getBrandNameById(formData.brandId) }}
</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="关键字">
<ElTag type="danger"></ElTag
>{{ formData.keyword || '无' }}</ElDescriptionsItem
>
<ElDescriptionsItem label="赠送积分">{{
formData.giveIntegral
}}</ElDescriptionsItem>
<ElDescriptionsItem label="虚拟销量">{{
formData.virtualSalesCount
}}</ElDescriptionsItem>
<ElDescriptionsItem label="排序">{{
formData.sort
}}</ElDescriptionsItem>
<ElTag type="danger" />{{ formData.keyword || '无' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="赠送积分">
{{ formData.giveIntegral }}
</ElDescriptionsItem>
<ElDescriptionsItem label="虚拟销量">
{{ formData.virtualSalesCount }}
</ElDescriptionsItem>
<ElDescriptionsItem label="排序">
{{ formData.sort }}
</ElDescriptionsItem>
<ElDescriptionsItem label="规格类型">
<ElTag :type="formData.specType ? 'success' : 'info'">
{{ formData.specType ? '多规格' : '单规格' }}
@@ -309,9 +310,9 @@ onMounted(async () => {
</span>
</div>
</ElDescriptionsItem>
<ElDescriptionsItem label="运费模板">{{
formData.deliveryTemplateId || '未设置'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="运费模板">
{{ formData.deliveryTemplateId || '未设置' }}
</ElDescriptionsItem>
</ElDescriptions>
</ElCard>
</div>
@@ -370,7 +371,7 @@ onMounted(async () => {
>
<ElCard
shadow="hover"
:header="`规格 ${index + 1}${sku.properties && sku.properties.length > 0 ? ' - ' + sku.properties.map((p) => p.valueName).join('/') : ''}`"
:header="`规格 ${index + 1}${sku.properties && sku.properties.length > 0 ? ` - ${sku.properties.map((p) => p.valueName).join('/')}` : ''}`"
>
<div class="flex flex-col gap-4 md:flex-row">
<ElImage
@@ -484,14 +485,17 @@ onMounted(async () => {
background-color: #fff;
border-radius: 4px;
}
.product-description :deep(img) {
max-width: 100%;
height: auto;
}
.product-description :deep(table) {
width: 100%;
border-collapse: collapse;
}
.product-description :deep(table td) {
padding: 8px;
border: 1px solid #eee;