提交 82fe7a10 authored 作者: 袁伟伟's avatar 袁伟伟

feat: 批量订单审核

上级 d43b68e0
......@@ -152,6 +152,9 @@ export interface Goods {
// 套件数量
quantity: number;
uuid: string;
cartProductDetailList: Array<Product>;
goodsId?: number;
lineThirdId: number;
}
export type GoodsPageResult = PageResult<Goods>;
......
......@@ -5,11 +5,7 @@
*/
import { defHttp } from '/@/utils/http/axios';
import {
BatchOrder,
BatchOrderParams,
BatchOrderPageResult,
} from '../model/batchOrder';
import { BatchOrder, BatchOrderParams, BatchOrderPageResult } from '../model/batchOrder';
const baseApi = '/v1/order/batch-order';
/**
......@@ -30,7 +26,8 @@ export const remove = (id: any) => defHttp.delete<Number>({ url: `${baseApi}/${i
/**
* 分页查询
*/
export const search = (params?: BatchOrderParams) => defHttp.get<BatchOrderPageResult>({ url: `${baseApi}/search`, params });
export const search = (params?: BatchOrderParams) =>
defHttp.get<BatchOrderPageResult>({ url: `${baseApi}/search`, params });
/**
* 列表查询
......@@ -50,21 +47,37 @@ export const getOne = (params?: BatchOrderParams) => defHttp.get<BatchOrder>({ u
/**
* 批量删除
*/
export const batchRemove = (idList: Array<any>) => defHttp.post<boolean>({ url: `${baseApi}/batch-delete`, data: idList });
export const batchRemove = (idList: Array<any>) =>
defHttp.post<boolean>({ url: `${baseApi}/batch-delete`, data: idList });
/**
* 批量新增
*/
export const batchAdd = (entityList: Array<BatchOrder>) => defHttp.post<boolean>({ url: `${baseApi}/batch-save`, data: entityList });
export const batchAdd = (entityList: Array<BatchOrder>) =>
defHttp.post<boolean>({ url: `${baseApi}/batch-save`, data: entityList });
/**
* 批量更新
*/
export const batchUpdate = (entityList: Array<BatchOrder>) => defHttp.post<boolean>({ url: `${baseApi}/batch-update`, data: entityList });
export const batchUpdate = (entityList: Array<BatchOrder>) =>
defHttp.post<boolean>({ url: `${baseApi}/batch-update`, data: entityList });
/**
* 查询数量
*/
export const count = (params?: BatchOrderParams) => defHttp.get<Number>({ url: `${baseApi}/count`, params });
/**
* 提交
*/
export const submit = (params?: BatchOrder) => defHttp.post<BatchOrder>({ url: `${baseApi}/submit/order`, params });
/**
* 取消
*/
export const cancel = (params?: BatchOrder) => defHttp.post<BatchOrder>({ url: `${baseApi}/cancel/order`, params });
/**
* 取消
*/
export const save = (params?: BatchOrder) => defHttp.post<BatchOrder>({ url: `${baseApi}/save/order`, params });
import { defHttp } from '/@/utils/http/axios';
const baseApi = '/v1/order/cart';
/**
* 新增
*/
export const add = (entity) => defHttp.post<any>({ url: `${baseApi}/`, data: entity });
/**
* 数量
*/
export const count = () => defHttp.get<any>({ url: `${baseApi}/count` });
/**
* 列表
*/
export const all = () => defHttp.get<any>({ url: `${baseApi}/all` });
/**
* 修改数量
*/
export const update = (data) => defHttp.post<any>({ url: `${baseApi}/update`, data });
/**
* 删除商品
*/
export const remove = (data) => defHttp.post<any>({ url: `${baseApi}/delete`, data });
/**
* 删除全部商品
*/
export const removeAll = () => defHttp.post<any>({ url: `${baseApi}/clear` });
......@@ -2,6 +2,7 @@ import lodash from 'lodash';
import { reactive } from 'vue';
import * as goodsCategoryApi from '/@/api/product/goodsCategoryApi';
import { useUserStore } from '/@/store/modules/user';
import * as CartApi from '/@/api/order/cartApi';
const userStore = useUserStore();
......@@ -66,3 +67,26 @@ const navTree = (navList, init?: Function, str?: string) => {
export const useNavTree = () => {
return navTree;
};
const getCartList = (productList) => {
CartApi.all().then((res) => {
res.forEach((item) => {
// uuid是唯一标识符
item.uuid = item.goodsId + '';
item.goodsType = item.goods.goodsType;
item.cartProductDetailList.forEach((product) => {
product.uuid = item.goodsId + '-' + product.id;
product.type = item.goods.goodsType;
if (item.goodsType === 'KIT') {
product.basicQuantity = product.quantity / item.quantity;
}
});
});
productList.value = res;
});
};
export const useCartList = () => {
return getCartList;
};
......@@ -2,203 +2,17 @@ import { defineStore } from 'pinia';
import { store } from '/@/store';
interface ShoppingStore {
shoppingCart: any[];
shoppingCartRefresh: number;
}
export const useShoppingStore = defineStore({
id: 'app-shoppingStore',
state: (): ShoppingStore => ({
shoppingCart: [
{
id: 5,
goodsCategoryList: [
{
id: 33,
distributorId: 0,
name: '正天生物型翻修柄成套手术器械',
parentId: 32,
sort: 0,
status: 'YES',
lineName: '正天关节',
lineThirdId: '3',
remark: '',
editorId: 1,
editorName: '管理员',
createTime: '2022-11-07 14:03:12',
updateTime: '2022-11-07 14:03:12',
},
],
distributorId: 0,
name: '医用持针钳',
pic: 'http://192.168.101.69:8087/upload/20221031/d4844172-f412-4bc9-93ec-86db1fc7fbf6.png',
price: 0,
pageRemark: '提示:A类为临床常规规格,B类为临床少用规格,C类为临床极少用规格;定制专区产品,订货不退不换',
pageKeyword: '钳子',
remark: '医用不锈钢止血钳 结实耐用',
status: 'YES',
isImport: 'NO',
isNews: 'YES',
isUnconventional: 'NO',
isPromotion: 'NO',
sort: 1,
goodsType: 'PRODUCT',
deleteStatus: 'NO',
editorId: 1,
editorName: 'root',
createTime: '2022-10-31 16:54:06',
updateTime: '2022-11-08 15:42:08',
lineName: '正天关节',
categoryName: '正天生物型翻修柄成套手术器械',
productList: [
{
id: 4,
distributorId: 0,
thirdProductId: 'ZT.QC12046',
editorId: 1,
editorName: '管理员',
createTime: '2022-10-31 16:54:06',
updateTime: '2022-10-31 16:54:06',
quantity: 1,
uuid: '5-4',
type: 'PRODUCT',
},
{
id: 5,
distributorId: 0,
thirdProductId: 'ZT.QC12045',
editorId: 1,
editorName: '管理员',
createTime: '2022-10-31 16:54:06',
updateTime: '2022-10-31 16:54:06',
quantity: 1,
uuid: '5-5',
type: 'PRODUCT',
},
{
id: 6,
distributorId: 0,
thirdProductId: 'ZT.QC12047',
editorId: 1,
editorName: '管理员',
createTime: '2022-10-31 16:54:06',
updateTime: '2022-10-31 16:54:06',
quantity: 1,
uuid: '5-6',
type: 'PRODUCT',
},
],
uuid: '5',
},
{
id: 7,
goodsCategoryList: [
{
id: 33,
distributorId: 0,
name: '正天生物型翻修柄成套手术器械',
parentId: 32,
sort: 0,
status: 'YES',
lineName: '正天关节',
lineThirdId: '3',
remark: '',
editorId: 1,
editorName: '管理员',
createTime: '2022-11-07 14:03:12',
updateTime: '2022-11-09 15:49:50',
},
],
distributorId: 0,
name: 'NS2 白金钉棒成套器械',
pic: 'http://192.168.101.69:8087/upload/20221108/8232144a-3232-44d4-b6fc-0764d94642a9.jpg',
price: 0,
pageRemark: '提示:A类为临床常用规格,B类为临床少用规格,C类为临床极少用规格;定制专区产品,订货不退不换。',
pageKeyword: 'NS2 白金钉棒成套器械',
remark: '最新版NS2 白金钉棒成套器械',
status: 'YES',
isImport: 'NO',
isNews: 'NO',
isUnconventional: 'NO',
isPromotion: 'YES',
sort: 0,
goodsType: 'KIT',
deleteStatus: 'NO',
editorId: 1,
editorName: 'root',
createTime: '2022-11-08 14:26:57',
updateTime: '2022-11-08 14:27:08',
lineName: '正天关节',
categoryName: '正天生物型翻修柄成套手术器械',
productList: [
{
id: 1,
distributorId: 0,
thirdProductId: '1',
editorId: 1,
editorName: '管理员',
createTime: '2022-10-31 13:46:07',
updateTime: '2022-10-31 13:46:07',
quantity: 2,
basicQuantity: 1,
uuid: '7-1',
type: 'KIT',
},
{
id: 2,
distributorId: 0,
thirdProductId: '2',
editorId: 1,
editorName: '管理员',
createTime: '2022-10-31 13:46:07',
updateTime: '2022-10-31 13:46:07',
quantity: 4,
basicQuantity: 2,
uuid: '7-2',
type: 'KIT',
},
],
uuid: '7',
quantity: 2,
},
],
shoppingCartRefresh: 0,
}),
getters: {
getShoppingCartList(): any[] {
return this.shoppingCart;
},
},
actions: {
setShoppingCart(goods: any) {
const flag = this.shoppingCart.some((item, index) => {
if (item.id === goods.id) {
this.shoppingCart[index] = goods;
return true;
}
});
if (!flag) {
this.shoppingCart.push(goods);
}
},
removeSoppingCartByGoodsId(id) {
const idx = this.shoppingCart.findIndex((item) => {
return item.id === id * 1;
});
this.shoppingCart.splice(idx, 1);
},
removeSoppingCartByProductId(ids) {
this.shoppingCart.some((item) => {
if (item.id === ids[0] * 1) {
const idx = item.productList.findIndex((pro) => {
return pro.id === ids[1] * 1;
});
item.productList.splice(idx, 1);
return true;
}
});
},
removeAll() {
this.shoppingCart.length = 0;
refresh() {
this.shoppingCartRefresh++;
},
},
});
......
......@@ -15,21 +15,57 @@
</template>
</Descriptions.Item>
</Descriptions>
<a-table
:dataSource="productList"
:columns="detailColumns"
:pagination="false"
childrenColumnName="batchOrderDetailProductDetailList"
rowKey="uuid"
:scroll="{ y: 450 }"
>
</a-table>
<div class="btnWrap">
<a-button
type="primary"
danger
v-if="isRetain && hasPermission('AUTH_BATCH_ORDER:CANCEL')"
@click="handleChangeStatus('REJECT')"
>驳回</a-button
>
<a-button type="primary" @click="handleGoBack">返回</a-button>
<a-button
type="primary"
v-if="isRetain && hasPermission('AUTH_BATCH_ORDER:SUBMIT')"
@click="handleChangeStatus('PENDING_REVIEW')"
>提交</a-button
>
</div>
</Card>
</template>
<script lang="ts" setup name="DeviceDetail">
import { onMounted, computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
import { useAsyncState } from '@vueuse/core';
import { ImagePreview } from '/@/components/Preview/index';
import { ComputedRef } from '@vue/reactivity';
import { Descriptions, Card } from 'ant-design-vue';
import { descriptionColumns } from './schema';
import { descriptionColumns, detailColumns } from './schema';
import * as BatchOrderApi from '/@/api/order/batchOrderApi';
import { BatchOrder } from '/@/api/model/batchOrder';
import { toNumber } from 'lodash';
import { usePermission } from '/@/hooks/web/usePermission';
import { useUserStore } from '/@/store/modules/user';
const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const id = ref(route.params?.id);
const { hasPermission } = usePermission();
const productList = ref<any>([]);
if (userStore.getIsDistributor) {
}
// id 查询
const {
......@@ -38,13 +74,23 @@
isLoading,
execute,
} = useAsyncState(
() => {
return BatchOrderApi.getById(id.value).then((res: BatchOrder) => res);
},
null,
{
immediate: false,
},
() => {
return BatchOrderApi.getById(id.value).then((res: BatchOrder) => {
res.batchOrderDetailList?.forEach((item) => {
item.uuid = item.goodsId + '';
item.batchOrderDetailProductDetailList.forEach((el) => {
el.uuid = item.goodsId + '-' + el.id;
});
});
productList.value = res.batchOrderDetailList;
return res;
});
},
null,
{
immediate: false,
},
);
onMounted(() => {
......@@ -56,10 +102,41 @@
const display: any = descriptionColumns.map(({ title, dataIndex = '', customRender }) => ({
key: dataIndex,
title,
value: customRender ? customRender({ text: detail.value[dataIndex], record: detail.value }) : detail.value[dataIndex],
value: customRender
? customRender({ text: detail.value[dataIndex], record: detail.value })
: detail.value[dataIndex],
}));
return display;
});
const isRetain = computed(() => detail.value?.status === 'TO_BE_USE');
const handleGoBack = () => {
router.back();
};
const handleChangeStatus = (status) => {
if (id) {
const api = status === 'REJECT' ? BatchOrderApi.cancel : BatchOrderApi.submit;
api({
id: toNumber(id.value),
}).then(() => {
execute();
});
}
};
</script>
<style scoped></style>
<style lang="less" scoped>
.ant-table-wrapper {
margin-top: 20px;
}
.btnWrap {
margin-top: 20px;
text-align: center;
button {
margin: 0 5px;
}
}
</style>
......@@ -8,7 +8,7 @@
<span>已选中{{ checkedKeys.length }}条记录</span>
<a-button type="link" @click="checkedKeys = []" size="small">清空</a-button>
<a-popconfirm
v-auth="'AUTH_ORDER_BATCH_ORDER'"
v-auth="'AUTH_BATCH_ORDER'"
class="ml-4"
title="确定要全部删除吗?"
ok-text="是"
......@@ -25,7 +25,7 @@
</a-alert>
</template>
<template #toolbar>
<a-button v-auth="'AUTH_ORDER_BATCH_ORDER:ADD'" type="primary" @click="handleCreate"> 新增</a-button>
<a-button v-auth="'AUTH_BATCH_ORDER:ADD'" type="primary" @click="handleCreate"> 新增</a-button>
</template>
<template #bodyCell="{ column, record, text }">
<template v-if="[].includes(column.dataIndex)">
......@@ -34,27 +34,36 @@
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
// {
// tooltip: '编辑',
// icon: 'clarity:note-edit-line',
// onClick: handleEdit.bind(null, record),
// ifShow: hasPermission('AUTH_BATCH_ORDER:EDIT'),
// },
{
tooltip: '编辑',
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
ifShow: hasPermission('AUTH_ORDER_BATCH_ORDER:EDIT'),
},
{
tooltip: '详情',
icon: 'ant-design:eye-outlined',
onClick: handleView.bind(null, record),
ifShow: hasPermission('AUTH_ORDER_BATCH_ORDER:QUERY'),
label: '通过',
color: 'success',
popConfirm: {
title: '是否确认通过',
confirm: handleVerify.bind(null, record),
},
ifShow: hasPermission('AUTH_BATCH_ORDER:CHECK') && record.status === 'PENDING_REVIEW',
},
{
tooltip: '删除',
icon: 'ant-design:delete-outlined',
label: '拒绝',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
title: '是否确认拒绝',
confirm: handleVerify.bind(null, record),
},
ifShow: hasPermission('AUTH_ORDER_BATCH_ORDER:DELETE'),
ifShow: hasPermission('AUTH_BATCH_ORDER:CHECK') && record.status === 'PENDING_REVIEW',
},
{
tooltip: '详情',
icon: 'ant-design:eye-outlined',
onClick: handleView.bind(null, record),
ifShow: hasPermission('AUTH_BATCH_ORDER:QUERY'),
},
]"
/>
......@@ -64,7 +73,7 @@
<BatchOrderDrawer @register="registerDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup name="AUTH_ORDER_BATCH_ORDER">
<script lang="ts" setup name="AUTH_BATCH_ORDER">
import { ref } from 'vue';
import { useGo } from '/@/hooks/web/usePage';
import { usePermission } from '/@/hooks/web/usePermission';
......@@ -79,20 +88,15 @@
const { hasPermission } = usePermission();
const go = useGo();
const {
formConfig,
showTableSetting,
bordered,
showIndexColumn,
} = componentSetting.table;
const { formConfig, showTableSetting, bordered, showIndexColumn } = componentSetting.table;
const checkedKeys = ref<Array<string | number>>([]);
const onSelectChange = (selectedRowKeys: (string | number)[]) => {
checkedKeys.value = selectedRowKeys;
}
};
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerTable, { reload ,setLoading}] = useTable({
const [registerTable, { reload, setLoading }] = useTable({
title: '批量订单管理',
api: (params) => BatchOrderApi.search(handleParams(params)),
columns,
......@@ -114,7 +118,7 @@
canResize: false,
rowKey: (record: any) => record.id,
actionColumn: {
width: 120,
width: 180,
title: '操作',
dataIndex: 'action',
fixed: 'right',
......@@ -160,27 +164,33 @@
const handleDelete = (record: Recordable) => {
setLoading(true);
BatchOrderApi.remove(record.id).then((_) => {
reload();
}).catch(() => {
setLoading(false);
});
BatchOrderApi.remove(record.id)
.then((_) => {
reload();
})
.catch(() => {
setLoading(false);
});
};
const handleBatchDelete = () => {
setLoading(true);
BatchOrderApi.batchRemove(checkedKeys.value).then((_) => {
reload();
}).catch(() => {
setLoading(false);
});
BatchOrderApi.batchRemove(checkedKeys.value)
.then((_) => {
reload();
})
.catch(() => {
setLoading(false);
});
};
const handleSuccess = () => {
reload();
};
const handleVerify = () => {};
const handleView = (record) => {
go('/main/order/batch-order/' + record.id);
go('/main/batch-order/detail/' + record.id);
};
</script>
......@@ -82,14 +82,14 @@
</a-form-item>
</template>
<a-form-item label="备注" name="remark">
<a-input v-model="formData.remark"></a-input>
<a-input v-model:value="formData.remark"></a-input>
</a-form-item>
</a-form>
<a-table
:dataSource="productList"
:columns="columns"
:pagination="false"
childrenColumnName="productList"
childrenColumnName="cartProductDetailList"
rowKey="uuid"
:scroll="{ y: 450 }"
>
......@@ -117,9 +117,24 @@
>合计:<span class="num">{{ productNum }}</span
></span
>
<a-button type="primary" size="large" @click="handleVerify"> 校验 </a-button>
<a-button type="default" size="large" @click="handleSubmitOrder('TO_BE_USE')"> 保存订单 </a-button>
<a-button type="primary" danger size="large" @click="handleSubmitOrder(undefined)"> 提交订单 </a-button>
<a-button type="primary" size="large" @click="handleVerify" :disabled="productNum === 0"> 校验 </a-button>
<a-button
type="default"
size="large"
@click="handleSubmitOrder('TO_BE_USE')"
:disabled="productNum === 0"
>
保存订单
</a-button>
<a-button
type="primary"
danger
size="large"
@click="handleSubmitOrder(undefined)"
:disabled="productNum === 0"
>
提交订单
</a-button>
</div>
</div>
</div>
......@@ -131,11 +146,10 @@
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, watch, computed } from 'vue';
import { ref, onMounted, reactive, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useGo } from '/@/hooks/web/usePage';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
import { useNavTree } from '/@/hooks/myhooks/index';
import { useNavTree, useCartList } from '/@/hooks/myhooks/index';
import { DataItem } from '/@/views/product/goods-category/type';
import { cloneDeep, toNumber } from 'lodash';
import { rulesRef } from './schema';
......@@ -149,6 +163,7 @@
import * as BatchOrderApi from '/@/api/order/batchOrderApi';
import { BatchOrder } from '/@/api/model/batchOrder';
import { message } from 'ant-design-vue';
import * as CartApi from '/@/api/order/cartApi';
const go = useGo();
const route = useRoute();
......@@ -163,9 +178,8 @@
const navId = toNumber(query.nav); // 一级选择id
const navList = ref<DataItem[]>([]); // 菜单树
const navActiveKey = ref(navId); // 一级标签选择
const shoppingStore = useShoppingStoreWithOut();
const title = ref(''); // 标题名称
const productList = shoppingStore.shoppingCart;
const productList = ref<any>([]);
const formData = reactive<BatchOrder>({
saleUserName: undefined,
......@@ -188,6 +202,8 @@
});
};
const getCartList = useCartList();
// 选择发货方式
const handleChangeDespatch = (val) => {
console.log(val);
......@@ -223,25 +239,30 @@
// 提交订单
const handleSubmitOrder = (status: string | undefined) => {
const batchOrder = cloneDeep(productList);
const batchOrder = cloneDeep(productList.value);
batchOrder.forEach((item) => {
item.goodsId = item.id;
item.batchOrderDetailProductDetailList = item.cartProductDetailList;
});
formRef.value.validate().then(() => {
BatchOrderApi.add(Object.assign({ status, batchOrderDetailList: batchOrder }, formData)).then((res) => {
const api = status ? BatchOrderApi.save : BatchOrderApi.submit;
api(Object.assign({ batchOrderDetailList: batchOrder }, formData)).then(() => {
if (status) {
message.success('保存成功');
} else {
message.success('提交成功');
}
CartApi.removeAll();
go('/main/batch-order/order-list');
});
});
};
const productNum = computed(() => {
let num = 0;
shoppingStore.shoppingCart.forEach((item) => {
item.productList.forEach((product) => {
productList.value.forEach((item) => {
item.cartProductDetailList.forEach((product) => {
num += product.quantity;
});
});
......@@ -250,15 +271,8 @@
onMounted(() => {
navTree(navList, getGrandsonList, 'getGrandsonList');
getCartList(productList);
});
watch(
() => navActiveKey.value,
(n) => {
shoppingStore.removeAll();
go('/main/store/home' + `?id=${n}`);
},
);
</script>
<style lang="less" scoped>
......
......@@ -4,30 +4,47 @@
<li>产品线</li>
<template v-for="(item, index) in navList">
<li v-if="index !== 4">|</li>
<li class="title" :class="{ active: navActiveKey === item.id }" @click="handleChangeNav(item.id)">{{
item.name
}}</li>
<li
class="title"
:class="{ active: navActiveKey === item.id || navId === item.id }"
@click="handleChangeNav(item.id)"
>{{ item.name }}</li
>
</template>
</ul>
</div>
</template>
<script lang="ts" setup>
import { defineProps, defineEmits, createVNode } from 'vue';
import { defineProps, createVNode } from 'vue';
import { Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import * as CartApi from '/@/api/order/cartApi';
import { useGo } from '/@/hooks/web/usePage';
import { useRoute } from 'vue-router';
import { toNumber } from 'lodash';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
const go = useGo();
const props = defineProps(['navList', 'navActiveKey']);
const emits = defineEmits(['handleChangeNavId', 'update:navActiveKey']);
const shoppingStore = useShoppingStoreWithOut();
const route = useRoute();
const query = route.query;
const navId = toNumber(query.nav); // 一级选择id
const handleChangeNav = (id) => {
if (props.navActiveKey === id) return;
if (props.navActiveKey === id || navId === id) return;
Modal.confirm({
title: '提示',
icon: createVNode(ExclamationCircleOutlined),
content: '你确定切换产品线吗?切换产品线会清空购物车!',
onOk() {
emits('update:navActiveKey', id);
CartApi.removeAll().then(() => {
go('/main/store/home' + `?id=${id}`);
});
shoppingStore.refresh();
},
onCancel() {},
});
......
......@@ -8,7 +8,7 @@
@search="onSearch"
/>
<div class="shoppingCart" @click="handleGoShoppingCart">
<a-badge :count="shoppingCartNum.length">
<a-badge :count="shoppingCartNum">
<ShoppingCartOutlined />
</a-badge>
</div>
......@@ -16,23 +16,40 @@
</template>
<script lang="ts" setup>
import { ref, defineProps } from 'vue';
import { ref, defineProps, onMounted, watch } from 'vue';
import { ShoppingCartOutlined } from '@ant-design/icons-vue';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
import { useGo } from '/@/hooks/web/usePage';
import * as CartApi from '/@/api/order/cartApi';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
const go = useGo();
const shoppingStore = useShoppingStoreWithOut();
const props = defineProps(['navId']);
const shoppingCartNum = shoppingStore.shoppingCart;
const shoppingCartNum = ref(0);
const handleGoShoppingCart = () => {
go('/main/store/shopping-cart' + `?nav=${props.navId}`);
};
const getCount = () => {
CartApi.count().then((res) => {
shoppingCartNum.value = res;
});
};
watch(
() => shoppingStore.shoppingCartRefresh,
() => {
getCount();
},
);
const searchInfo = ref('');
const onSearch = () => {};
onMounted(() => {
getCount();
});
</script>
<style lang="less" scoped>
......
......@@ -56,7 +56,6 @@
import { useRoute } from 'vue-router';
import { useNavTree } from '/@/hooks/myhooks/index';
import * as GoodsApi from '/@/api/product/goodsApi';
import { useGo } from '/@/hooks/web/usePage';
import { toNumber, cloneDeep } from 'lodash';
import Search from '../components/search.vue';
import Nav from '../components/nav.vue';
......@@ -67,8 +66,8 @@
import { ShoppingCartOutlined } from '@ant-design/icons-vue';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
import { message } from 'ant-design-vue';
import * as CartApi from '/@/api/order/cartApi';
const go = useGo();
const route = useRoute();
const navTree = useNavTree();
const shoppingStore = useShoppingStoreWithOut();
......@@ -146,41 +145,41 @@
if (goods) {
goods.pic = picList.value[0];
goods.uuid = goods.id + '';
} else {
return;
}
if (isKIT.value && goods) {
if (isKIT.value) {
if (goodsNum.value === 0) {
return message.warning('请填写套件数量!');
}
goods.productList.forEach((item) => {
item.uuid = goods.id + '-' + item.id;
item.type = 'KIT';
});
goods.cartProductDetailList = goods.productList;
goods.quantity = goodsNum.value;
shoppingStore.setShoppingCart(goods);
} else if (isPRODUCT.value && goods) {
} else if (isPRODUCT.value) {
let flag = true;
const list = <any[]>[];
productList.value.forEach((item) => {
if (item.quantity > 0) {
item.uuid = goods.id + '-' + item.id;
list.push(item);
item.type = 'PRODUCT';
flag = false;
}
});
if (flag) return message.warning('请填写产品数量!');
goods.productList = list;
shoppingStore.setShoppingCart(goods);
goods.cartProductDetailList = list;
goods.quantity = 1;
}
message.success('添加成功');
goods.goodsId = goods.id;
goods.lineThirdId = navActiveKey.value;
CartApi.add(goods).then(() => {
message.success('添加成功');
shoppingStore.refresh();
});
};
// 回显
......@@ -212,14 +211,6 @@
navTree(navList, getGrandsonList, 'getGrandsonList');
getGoodsInfo();
});
watch(
() => navActiveKey.value,
(n) => {
shoppingStore.removeAll();
go('/main/store/home' + `?id=${n}`);
},
);
</script>
<style scoped lang="less">
......
......@@ -5,7 +5,7 @@
<div class="top">
<div class="title">{{ title }}</div>
<div class="wrap">
<Nav v-model:navList="navList" v-model:navActiveKey="navActiveKey" />
<Nav v-model:navList="navList" />
</div>
</div>
<div class="classify">
......@@ -77,20 +77,17 @@
import * as GoodsApi from '/@/api/product/goodsApi';
import newPng from '/@/assets/images/new.png';
import nopl from '/@/assets/images/nopl.jpg';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
const go = useGo();
const route = useRoute();
const navTree = useNavTree();
const userStore = useUserStore();
const shoppingStore = useShoppingStoreWithOut();
const query = route.query;
const navId = toNumber(query.nav); // 一级选择id
const tabId = toNumber(query.tab); // 二级选择id
const tabItemId = toNumber(query.tabItem); // 三级选择id
const navList = ref<DataItem[]>([]); // 菜单树
const navActiveKey = ref(navId); // 一级标签选择
const levelFourTree = ref<DataItem[]>([]); // 四级菜单树
const levelFourActiveKey = ref<string | number>('all');
const levelFiveTree = ref<DataItem[]>([]); // 五级菜单树
......@@ -169,14 +166,6 @@
go('/main/store/goodDetail' + `?goods=${goods.id}&nav=${navId}`);
};
watch(
() => navActiveKey.value,
(n) => {
shoppingStore.removeAll();
go('/main/store/home' + `?id=${n}`);
},
);
onMounted(() => {
navTree(navList, getGrandsonList, 'getGrandsonList');
getGoodsList();
......@@ -290,6 +279,7 @@
top: 10px;
width: 50px;
height: 50px;
z-index: 99;
}
.pic {
......
......@@ -5,7 +5,7 @@
<div class="top">
<div class="title">{{ title }}</div>
<div class="wrap">
<Nav v-model:navList="navList" v-model:navActiveKey="navActiveKey" />
<Nav v-model:navList="navList" />
</div>
</div>
<div class="info">
......@@ -19,7 +19,7 @@
:dataSource="productList"
:columns="columns"
:pagination="false"
childrenColumnName="productList"
childrenColumnName="cartProductDetailList"
rowKey="uuid"
:scroll="{ y: 450 }"
>
......@@ -41,7 +41,7 @@
title="是否确认删除?"
ok-text="是"
cancel-text="否"
@confirm="confirm(record.uuid)"
@confirm="confirm(record.uuid, record.id)"
@cancel="() => {}"
>
<a-button type="link">删除</a-button>
......@@ -62,7 +62,9 @@
>已选数量:<span class="num">{{ productNum }}</span
></span
>
<a-button type="primary" size="large" @click="handleGoCheckOrder"> 去结算 </a-button>
<a-button type="primary" size="large" @click="handleGoCheckOrder" :disabled="productNum === 0">
去结算
</a-button>
</div>
</div>
</div>
......@@ -74,8 +76,7 @@
<script lang="ts" setup>
import { ref, onMounted, computed, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useNavTree } from '/@/hooks/myhooks/index';
import { useShoppingStoreWithOut } from '/@/store/modules/store';
import { useNavTree, useCartList } from '/@/hooks/myhooks/index';
import Search from '../components/search.vue';
import Nav from '../components/nav.vue';
import { DataItem } from '/@/views/product/goods-category/type';
......@@ -83,18 +84,26 @@
import { columns } from './schema';
import { ShoppingCartOutlined } from '@ant-design/icons-vue';
import { useGo } from '/@/hooks/web/usePage';
import * as CartApi from '/@/api/order/cartApi';
import { message } from 'ant-design-vue';
const go = useGo();
const navTree = useNavTree();
const route = useRoute();
const shoppingStore = useShoppingStoreWithOut();
const getCartList = useCartList();
columns.push({
title: '操作',
key: 'active',
width: '100px',
});
const query = route.query;
const navId = toNumber(query.nav); // 一级选择id
const navList = ref<DataItem[]>([]); // 菜单树
const navActiveKey = ref(navId); // 一级标签选择
const title = ref(''); // 标题名称
const productList = shoppingStore.shoppingCart;
// const productList = shoppingStore.shoppingCart;
const productList = ref<any>([]);
const getGrandsonList = (arr: DataItem[]) => {
arr.some((item) => {
......@@ -106,37 +115,66 @@
};
// 删除
const confirm = (uuid) => {
const confirm = (uuid, id) => {
const uuidArr = uuid.split('-');
if (uuidArr.length === 1) {
shoppingStore.removeSoppingCartByGoodsId(uuidArr[0]);
CartApi.remove([{ id }]).then((res) => {
message.success('删除成功');
getCartList(productList);
});
} else if (uuidArr.length === 2) {
shoppingStore.removeSoppingCartByProductId(uuidArr);
const goodsId = toNumber(uuidArr[0]);
const index = productList.value.findIndex((item) => {
const idx = item.cartProductDetailList.findIndex((pro) => {
return pro.uuid === uuid;
});
if (idx != -1) {
item.cartProductDetailList.splice(idx, 1);
}
return item.goodsId === goodsId;
});
if (index != -1) {
CartApi.update(productList.value[index]);
}
}
};
// 数量改变
const handleQuantityChange = (val, record) => {
if (record.productList) {
record.productList.forEach((product) => {
if (record.cartProductDetailList) {
record.cartProductDetailList.forEach((product) => {
if (record.goodsType === 'KIT') {
product.quantity = product.basicQuantity * val;
} else if (record.goodsType === 'PRODUCT') {
product.quantity = val;
}
});
CartApi.update(record);
} else {
const uuid = record.uuid;
const goodsId = toNumber(uuid[0]);
const index = productList.value.findIndex((item) => {
return item.goodsId === goodsId;
});
if (index != -1) {
CartApi.update(productList.value[index]);
}
}
};
// 清空购物车
const handleEmptyShoppingCart = () => {
shoppingStore.removeAll();
CartApi.removeAll().then((_) => {
message.success('清除成功');
});
getCartList(productList);
};
const productNum = computed(() => {
let num = 0;
shoppingStore.shoppingCart.forEach((item) => {
item.productList.forEach((product) => {
productList.value.forEach((item) => {
item.cartProductDetailList.forEach((product) => {
num += product.quantity;
});
});
......@@ -147,16 +185,9 @@
go('/main/store/check-order' + `?nav=${navId}`);
};
watch(
() => navActiveKey.value,
(n) => {
shoppingStore.removeAll();
go('/main/store/home' + `?id=${n}`);
},
);
onMounted(() => {
navTree(navList, getGrandsonList, 'getGrandsonList');
getCartList(productList);
});
</script>
......
export const columns = [
export const columns = <any>[
{
title: '产品编号',
dataIndex: 'thirdProductId',
......@@ -41,9 +41,4 @@ export const columns = [
dataIndex: 'price',
width: '120px',
},
{
title: '操作',
key: 'active',
width: '100px',
},
];
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论