|
@@ -2,39 +2,21 @@
|
|
<el-container class="goods-select">
|
|
<el-container class="goods-select">
|
|
<el-container>
|
|
<el-container>
|
|
<el-header class="goods-search">
|
|
<el-header class="goods-search">
|
|
- <sa-search-simple
|
|
|
|
- :searchFields="searchFields"
|
|
|
|
- :defaultValues="defaultSearchValues"
|
|
|
|
- @search="(val) => getData(1, val)"
|
|
|
|
- @reset="getData(1)"
|
|
|
|
- />
|
|
|
|
|
|
+ <sa-search-simple :searchFields="searchFields" :defaultValues="defaultSearchValues"
|
|
|
|
+ @search="(val) => getData(1, val)" @reset="getData(1)" />
|
|
</el-header>
|
|
</el-header>
|
|
<el-main v-loading="loading">
|
|
<el-main v-loading="loading">
|
|
- <el-table
|
|
|
|
- class="sa-table"
|
|
|
|
- ref="multipleTableRef"
|
|
|
|
- :data="table.list"
|
|
|
|
- @select="selectRow"
|
|
|
|
- @select-all="selectAll"
|
|
|
|
- stripe
|
|
|
|
- >
|
|
|
|
|
|
+ <el-table class="sa-table" ref="multipleTableRef" :data="table.list" @select="selectRow" @select-all="selectAll"
|
|
|
|
+ stripe>
|
|
<template #empty>
|
|
<template #empty>
|
|
<sa-empty />
|
|
<sa-empty />
|
|
</template>
|
|
</template>
|
|
- <el-table-column
|
|
|
|
- v-if="modal.params.multiple"
|
|
|
|
- type="selection"
|
|
|
|
- width="48"
|
|
|
|
- ></el-table-column>
|
|
|
|
|
|
+ <el-table-column v-if="modal.params.multiple" type="selection" width="48"></el-table-column>
|
|
<el-table-column prop="id" :label="t('modules.goods.goodsNumber')" align="center" />
|
|
<el-table-column prop="id" :label="t('modules.goods.goodsNumber')" align="center" />
|
|
<el-table-column :label="t('modules.goods.goodsInfo')">
|
|
<el-table-column :label="t('modules.goods.goodsInfo')">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<div class="sa-flex">
|
|
<div class="sa-flex">
|
|
- <el-image
|
|
|
|
- :src="scope.row.image"
|
|
|
|
- style="width: 60px; height: 60px; margin-right: 12px"
|
|
|
|
- fit="cover"
|
|
|
|
- />
|
|
|
|
|
|
+ <el-image :src="scope.row.image" class="goods-image" fit="cover" />
|
|
<div>
|
|
<div>
|
|
<div class="goods-title">{{ scope.row.storeName }}</div>
|
|
<div class="goods-title">{{ scope.row.storeName }}</div>
|
|
</div>
|
|
</div>
|
|
@@ -47,12 +29,7 @@
|
|
<div>{{ t('modules.goods.onlinePrice') }}: ৳{{ scope.row.price }}</div>
|
|
<div>{{ t('modules.goods.onlinePrice') }}: ৳{{ scope.row.price }}</div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column
|
|
|
|
- prop="stock"
|
|
|
|
- :label="t('modules.goods.goodsStock')"
|
|
|
|
- min-width="100"
|
|
|
|
- align="center"
|
|
|
|
- >
|
|
|
|
|
|
+ <el-table-column prop="stock" :label="t('modules.goods.goodsStock')" min-width="100" align="center">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
{{ scope.row.stock || 0 }}
|
|
{{ scope.row.stock || 0 }}
|
|
</template>
|
|
</template>
|
|
@@ -61,13 +38,8 @@
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<template v-if="modal.params.ftype == 'score_shop'">
|
|
<template v-if="modal.params.ftype == 'score_shop'">
|
|
<span v-if="scope.row.is_score_shop">{{ t('modules.goods.alreadyJoined') }}</span>
|
|
<span v-if="scope.row.is_score_shop">{{ t('modules.goods.alreadyJoined') }}</span>
|
|
- <el-button
|
|
|
|
- v-if="!scope.row.is_score_shop"
|
|
|
|
- link
|
|
|
|
- type="primary"
|
|
|
|
- @click="singleSelect(scope.row.id)"
|
|
|
|
- >{{ t('modules.goods.join') }}</el-button
|
|
|
|
- >
|
|
|
|
|
|
+ <el-button v-if="!scope.row.is_score_shop" link type="primary" @click="singleSelect(scope.row.id)">{{
|
|
|
|
+ t('modules.goods.join') }}</el-button>
|
|
</template>
|
|
</template>
|
|
<template v-else>
|
|
<template v-else>
|
|
<el-button link type="primary" @click="singleSelect(scope.row.id)">{{
|
|
<el-button link type="primary" @click="singleSelect(scope.row.id)">{{
|
|
@@ -78,10 +50,7 @@
|
|
</el-table-column>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-table>
|
|
</el-main>
|
|
</el-main>
|
|
- <el-footer
|
|
|
|
- class="sa-footer--submit"
|
|
|
|
- :class="modal.params.multiple ? 'sa-row-between' : 'sa-row-right'"
|
|
|
|
- >
|
|
|
|
|
|
+ <el-footer class="sa-footer--submit" :class="modal.params.multiple ? 'sa-row-between' : 'sa-row-right'">
|
|
<sa-pagination :pageData="pageData" layout="total, prev, pager, next" @updateFn="getData" />
|
|
<sa-pagination :pageData="pageData" layout="total, prev, pager, next" @updateFn="getData" />
|
|
<el-button v-if="modal.params.multiple" type="primary" @click="confirm">{{
|
|
<el-button v-if="modal.params.multiple" type="primary" @click="confirm">{{
|
|
t('common.confirm')
|
|
t('common.confirm')
|
|
@@ -92,301 +61,316 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
- /**@property {Array} ids - 已经选中
|
|
|
|
- * @param {Boolean} multiple - 是否多选
|
|
|
|
- * @param {Number} max - 多选时最大数量(0 代表限制数量)
|
|
|
|
- * @param {String} ftype - 打开来源(score_shop)
|
|
|
|
- */
|
|
|
|
- import { nextTick, onMounted, reactive, ref } from 'vue';
|
|
|
|
- import { api } from '../goods.service';
|
|
|
|
- import { ElMessage } from 'element-plus';
|
|
|
|
- import { usePagination } from '@/sheep/hooks';
|
|
|
|
- import { useI18n } from 'vue-i18n';
|
|
|
|
|
|
+/**@property {Array} ids - 已经选中
|
|
|
|
+ * @param {Boolean} multiple - 是否多选
|
|
|
|
+ * @param {Number} max - 多选时最大数量(0 代表限制数量)
|
|
|
|
+ * @param {String} ftype - 打开来源(score_shop)
|
|
|
|
+ */
|
|
|
|
+import { nextTick, onMounted, reactive, ref } from 'vue';
|
|
|
|
+import { api } from '../goods.service';
|
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
|
+import { usePagination } from '@/sheep/hooks';
|
|
|
|
+import { useI18n } from 'vue-i18n';
|
|
|
|
|
|
- const { t } = useI18n();
|
|
|
|
- const { pageData } = usePagination();
|
|
|
|
|
|
+const { t } = useI18n();
|
|
|
|
+const { pageData } = usePagination();
|
|
|
|
|
|
- const emit = defineEmits(['modalCallBack']);
|
|
|
|
- const props = defineProps(['modal']);
|
|
|
|
|
|
+const emit = defineEmits(['modalCallBack']);
|
|
|
|
+const props = defineProps(['modal']);
|
|
|
|
|
|
- // 搜索字段配置
|
|
|
|
- const searchFields = reactive({
|
|
|
|
- title: {
|
|
|
|
- type: 'input',
|
|
|
|
- get label() {
|
|
|
|
- return t('modules.goods.goodsName');
|
|
|
|
- },
|
|
|
|
- get placeholder() {
|
|
|
|
- return t('form.inputNameOrNumber');
|
|
|
|
- },
|
|
|
|
- width: 200,
|
|
|
|
|
|
+// 搜索字段配置
|
|
|
|
+const searchFields = reactive({
|
|
|
|
+ title: {
|
|
|
|
+ type: 'input',
|
|
|
|
+ get label() {
|
|
|
|
+ return t('modules.goods.goodsName');
|
|
},
|
|
},
|
|
- });
|
|
|
|
|
|
+ get placeholder() {
|
|
|
|
+ return t('form.inputNameOrNumber');
|
|
|
|
+ },
|
|
|
|
+ width: 200,
|
|
|
|
+ },
|
|
|
|
+});
|
|
|
|
|
|
- // 默认搜索值
|
|
|
|
- const defaultSearchValues = reactive({
|
|
|
|
- title: '',
|
|
|
|
- });
|
|
|
|
|
|
+// 默认搜索值
|
|
|
|
+const defaultSearchValues = reactive({
|
|
|
|
+ title: '',
|
|
|
|
+});
|
|
|
|
|
|
- const loading = ref(true);
|
|
|
|
- const table = reactive({
|
|
|
|
- list: [],
|
|
|
|
- ids: props.modal.params.ids || [],
|
|
|
|
- selectedGoods: new Map(), // 使用Map存储选中的商品完整数据,key为商品id
|
|
|
|
- preloadedGoods: new Map(), // 存储预加载的商品数据
|
|
|
|
- });
|
|
|
|
- async function getData(page, searchParams = {}) {
|
|
|
|
- if (page) pageData.page = page;
|
|
|
|
- loading.value = true;
|
|
|
|
|
|
+const loading = ref(true);
|
|
|
|
+const table = reactive({
|
|
|
|
+ list: [],
|
|
|
|
+ ids: props.modal.params.ids || [],
|
|
|
|
+ selectedGoods: new Map(), // 使用Map存储选中的商品完整数据,key为商品id
|
|
|
|
+ preloadedGoods: new Map(), // 存储预加载的商品数据
|
|
|
|
+});
|
|
|
|
+async function getData(page, searchParams = {}) {
|
|
|
|
+ if (page) pageData.page = page;
|
|
|
|
+ loading.value = true;
|
|
|
|
|
|
- try {
|
|
|
|
- const params = {
|
|
|
|
- page: pageData.page,
|
|
|
|
- size: pageData.size,
|
|
|
|
- isShow: 1,
|
|
|
|
- ...searchParams,
|
|
|
|
- };
|
|
|
|
- const { code, data } = await api.goods.list(params);
|
|
|
|
- if (code == '200') {
|
|
|
|
- table.list = data.list || [];
|
|
|
|
- pageData.page = data.pageNum;
|
|
|
|
- pageData.size = data.pageSize;
|
|
|
|
- pageData.total = data.total;
|
|
|
|
|
|
+ try {
|
|
|
|
+ const params = {
|
|
|
|
+ page: pageData.page,
|
|
|
|
+ size: pageData.size,
|
|
|
|
+ isShow: 1,
|
|
|
|
+ ...searchParams,
|
|
|
|
+ };
|
|
|
|
+ const { code, data } = await api.goods.list(params);
|
|
|
|
+ if (code == '200') {
|
|
|
|
+ table.list = data.list || [];
|
|
|
|
+ pageData.page = data.pageNum;
|
|
|
|
+ pageData.size = data.pageSize;
|
|
|
|
+ pageData.total = data.total;
|
|
|
|
|
|
- nextTick(() => {
|
|
|
|
- setDefaultSelected();
|
|
|
|
- // 初始化当前页面的选中商品数据
|
|
|
|
- initSelectedGoods();
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error('获取商品列表失败:', error);
|
|
|
|
- table.list = []; // 确保出错时也有默认值
|
|
|
|
- } finally {
|
|
|
|
- loading.value = false;
|
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ setDefaultSelected();
|
|
|
|
+ // 初始化当前页面的选中商品数据
|
|
|
|
+ initSelectedGoods();
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('获取商品列表失败:', error);
|
|
|
|
+ table.list = []; // 确保出错时也有默认值
|
|
|
|
+ } finally {
|
|
|
|
+ loading.value = false;
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- // 设置默认选中
|
|
|
|
- function setDefaultSelected() {
|
|
|
|
- // 确保 table.list 存在且为数组
|
|
|
|
- if (!table.list || !Array.isArray(table.list)) {
|
|
|
|
- console.warn('table.list is not available or not an array:', table.list);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- table.list.forEach((item) => {
|
|
|
|
- if (table.ids?.includes(item.id)) {
|
|
|
|
- multipleTableRef.value?.toggleRowSelection(item, true);
|
|
|
|
- toggleRowSelection('row', [item], item);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
|
|
+// 设置默认选中
|
|
|
|
+function setDefaultSelected() {
|
|
|
|
+ // 确保 table.list 存在且为数组
|
|
|
|
+ if (!table.list || !Array.isArray(table.list)) {
|
|
|
|
+ console.warn('table.list is not available or not an array:', table.list);
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
- const multipleTableRef = ref();
|
|
|
|
- function selectRow(selection, row) {
|
|
|
|
- if (
|
|
|
|
- !props.modal.params.max ||
|
|
|
|
- (props.modal.params.max && props.modal.params.max > table.ids.length)
|
|
|
|
- ) {
|
|
|
|
- if (table.ids.includes(row.id)) {
|
|
|
|
- let index = table.ids.findIndex((id) => id == row.id);
|
|
|
|
- table.ids.splice(index, 1);
|
|
|
|
- // 从选中商品数据中移除
|
|
|
|
- table.selectedGoods.delete(row.id);
|
|
|
|
- } else {
|
|
|
|
- table.ids.push(row.id);
|
|
|
|
- // 添加到选中商品数据中
|
|
|
|
- addToSelectedGoods(row);
|
|
|
|
- }
|
|
|
|
|
|
+ table.list.forEach((item) => {
|
|
|
|
+ if (table.ids?.includes(item.id)) {
|
|
|
|
+ multipleTableRef.value?.toggleRowSelection(item, true);
|
|
|
|
+ toggleRowSelection('row', [item], item);
|
|
}
|
|
}
|
|
- toggleRowSelection('row', selection, row);
|
|
|
|
- }
|
|
|
|
- function selectAll(selection) {
|
|
|
|
- if (
|
|
|
|
- !props.modal.params.max ||
|
|
|
|
- (props.modal.params.max && props.modal.params.max > table.ids.length + selection.length)
|
|
|
|
- ) {
|
|
|
|
- if (selection.length == 0) {
|
|
|
|
- // 取消全选:移除当前页面的所有选中项
|
|
|
|
- table.list.forEach((l) => {
|
|
|
|
- if (table.ids.includes(l.id)) {
|
|
|
|
- let index = table.ids.findIndex((id) => id == l.id);
|
|
|
|
- table.ids.splice(index, 1);
|
|
|
|
- // 从选中商品数据中移除
|
|
|
|
- table.selectedGoods.delete(l.id);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- // 全选:添加当前页面的所有项
|
|
|
|
- table.list.forEach((l) => {
|
|
|
|
- if (!table.ids.includes(l.id)) {
|
|
|
|
- table.ids.push(l.id);
|
|
|
|
- // 添加到选中商品数据中
|
|
|
|
- addToSelectedGoods(l);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const multipleTableRef = ref();
|
|
|
|
+function selectRow(selection, row) {
|
|
|
|
+ if (
|
|
|
|
+ !props.modal.params.max ||
|
|
|
|
+ (props.modal.params.max && props.modal.params.max > table.ids.length)
|
|
|
|
+ ) {
|
|
|
|
+ if (table.ids.includes(row.id)) {
|
|
|
|
+ let index = table.ids.findIndex((id) => id == row.id);
|
|
|
|
+ table.ids.splice(index, 1);
|
|
|
|
+ // 从选中商品数据中移除
|
|
|
|
+ table.selectedGoods.delete(row.id);
|
|
|
|
+ } else {
|
|
|
|
+ table.ids.push(row.id);
|
|
|
|
+ // 添加到选中商品数据中
|
|
|
|
+ addToSelectedGoods(row);
|
|
}
|
|
}
|
|
- toggleRowSelection('all', selection);
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- function toggleRowSelection(type, selection, row) {
|
|
|
|
- // 限制数量
|
|
|
|
- if (props.modal.params.max && props.modal.params.max < selection.length) {
|
|
|
|
- if (type == 'row') {
|
|
|
|
- multipleTableRef.value.toggleRowSelection(row, false);
|
|
|
|
- } else if (type == 'all') {
|
|
|
|
- multipleTableRef.value?.clearSelection();
|
|
|
|
- table.list.forEach((l) => {
|
|
|
|
- if (table.ids?.includes(l.id)) {
|
|
|
|
- multipleTableRef.value?.toggleRowSelection(l, true);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- ElMessage({
|
|
|
|
- type: 'warning',
|
|
|
|
- message: t('message.selectionLimitReached'),
|
|
|
|
|
|
+ toggleRowSelection('row', selection, row);
|
|
|
|
+}
|
|
|
|
+function selectAll(selection) {
|
|
|
|
+ if (
|
|
|
|
+ !props.modal.params.max ||
|
|
|
|
+ (props.modal.params.max && props.modal.params.max > table.ids.length + selection.length)
|
|
|
|
+ ) {
|
|
|
|
+ if (selection.length == 0) {
|
|
|
|
+ // 取消全选:移除当前页面的所有选中项
|
|
|
|
+ table.list.forEach((l) => {
|
|
|
|
+ if (table.ids.includes(l.id)) {
|
|
|
|
+ let index = table.ids.findIndex((id) => id == l.id);
|
|
|
|
+ table.ids.splice(index, 1);
|
|
|
|
+ // 从选中商品数据中移除
|
|
|
|
+ table.selectedGoods.delete(l.id);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ // 全选:添加当前页面的所有项
|
|
|
|
+ table.list.forEach((l) => {
|
|
|
|
+ if (!table.ids.includes(l.id)) {
|
|
|
|
+ table.ids.push(l.id);
|
|
|
|
+ // 添加到选中商品数据中
|
|
|
|
+ addToSelectedGoods(l);
|
|
|
|
+ }
|
|
});
|
|
});
|
|
- return false;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ toggleRowSelection('all', selection);
|
|
|
|
+}
|
|
|
|
|
|
- // 添加商品到选中数据集合
|
|
|
|
- function addToSelectedGoods(item) {
|
|
|
|
- const goodsData = {
|
|
|
|
- id: item.id,
|
|
|
|
- title: item.title || item.storeName,
|
|
|
|
- image: item.image,
|
|
|
|
- price: item.price || item.current_price || item.original_price || item.otPrice,
|
|
|
|
- stock: item.stock,
|
|
|
|
- };
|
|
|
|
- table.selectedGoods.set(item.id, goodsData);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 初始化时添加已选中的商品数据
|
|
|
|
- function initSelectedGoods() {
|
|
|
|
- table.list.forEach((item) => {
|
|
|
|
- if (table.ids.includes(item.id)) {
|
|
|
|
- addToSelectedGoods(item);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 预加载所有已选中商品的完整数据
|
|
|
|
- async function preloadSelectedGoods() {
|
|
|
|
- if (!table.ids.length) return;
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- // 批量获取已选中商品的详细信息
|
|
|
|
- const promises = table.ids.map(async (id) => {
|
|
|
|
- try {
|
|
|
|
- const { code, data } = await api.goods.info(id);
|
|
|
|
- if (code === '200' && data) {
|
|
|
|
- addToSelectedGoods(data);
|
|
|
|
- table.preloadedGoods.set(id, data);
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.warn(`获取商品${id}详情失败:`, error);
|
|
|
|
|
|
+function toggleRowSelection(type, selection, row) {
|
|
|
|
+ // 限制数量
|
|
|
|
+ if (props.modal.params.max && props.modal.params.max < selection.length) {
|
|
|
|
+ if (type == 'row') {
|
|
|
|
+ multipleTableRef.value.toggleRowSelection(row, false);
|
|
|
|
+ } else if (type == 'all') {
|
|
|
|
+ multipleTableRef.value?.clearSelection();
|
|
|
|
+ table.list.forEach((l) => {
|
|
|
|
+ if (table.ids?.includes(l.id)) {
|
|
|
|
+ multipleTableRef.value?.toggleRowSelection(l, true);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
-
|
|
|
|
- await Promise.allSettled(promises);
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error('预加载选中商品数据失败:', error);
|
|
|
|
}
|
|
}
|
|
|
|
+ ElMessage({
|
|
|
|
+ type: 'warning',
|
|
|
|
+ message: t('message.selectionLimitReached'),
|
|
|
|
+ });
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- function singleSelect(id) {
|
|
|
|
- // 找到对应的商品数据
|
|
|
|
- const selectedItem = table.list.find((item) => item.id === id);
|
|
|
|
- if (selectedItem) {
|
|
|
|
- const goodsData = {
|
|
|
|
- id: selectedItem.id,
|
|
|
|
- title: selectedItem.title || selectedItem.storeName,
|
|
|
|
- image: selectedItem.image,
|
|
|
|
- price:
|
|
|
|
- selectedItem.price ||
|
|
|
|
- selectedItem.current_price ||
|
|
|
|
- selectedItem.original_price ||
|
|
|
|
- selectedItem.otPrice,
|
|
|
|
- stock: selectedItem.stock,
|
|
|
|
- };
|
|
|
|
|
|
+// 添加商品到选中数据集合
|
|
|
|
+function addToSelectedGoods(item) {
|
|
|
|
+ const goodsData = {
|
|
|
|
+ id: item.id,
|
|
|
|
+ title: item.title || item.storeName,
|
|
|
|
+ image: item.image,
|
|
|
|
+ price: item.price || item.current_price || item.original_price || item.otPrice,
|
|
|
|
+ stock: item.stock,
|
|
|
|
+ };
|
|
|
|
+ table.selectedGoods.set(item.id, goodsData);
|
|
|
|
+}
|
|
|
|
|
|
- emit('modalCallBack', {
|
|
|
|
- event: 'confirm',
|
|
|
|
- data: goodsData,
|
|
|
|
- });
|
|
|
|
|
|
+// 初始化时添加已选中的商品数据
|
|
|
|
+function initSelectedGoods() {
|
|
|
|
+ table.list.forEach((item) => {
|
|
|
|
+ if (table.ids.includes(item.id)) {
|
|
|
|
+ addToSelectedGoods(item);
|
|
}
|
|
}
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 预加载所有已选中商品的完整数据
|
|
|
|
+async function preloadSelectedGoods() {
|
|
|
|
+ if (!table.ids.length) return;
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 批量获取已选中商品的详细信息
|
|
|
|
+ const promises = table.ids.map(async (id) => {
|
|
|
|
+ try {
|
|
|
|
+ const { code, data } = await api.goods.info(id);
|
|
|
|
+ if (code === '200' && data) {
|
|
|
|
+ addToSelectedGoods(data);
|
|
|
|
+ table.preloadedGoods.set(id, data);
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.warn(`获取商品${id}详情失败:`, error);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ await Promise.allSettled(promises);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('预加载选中商品数据失败:', error);
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- function confirm() {
|
|
|
|
- // 将Map转换为数组,获取所有选中的商品数据
|
|
|
|
- const selectedGoodsData = Array.from(table.selectedGoods.values());
|
|
|
|
|
|
+function singleSelect(id) {
|
|
|
|
+ // 找到对应的商品数据
|
|
|
|
+ const selectedItem = table.list.find((item) => item.id === id);
|
|
|
|
+ if (selectedItem) {
|
|
|
|
+ const goodsData = {
|
|
|
|
+ id: selectedItem.id,
|
|
|
|
+ title: selectedItem.title || selectedItem.storeName,
|
|
|
|
+ image: selectedItem.image,
|
|
|
|
+ price:
|
|
|
|
+ selectedItem.price ||
|
|
|
|
+ selectedItem.current_price ||
|
|
|
|
+ selectedItem.original_price ||
|
|
|
|
+ selectedItem.otPrice,
|
|
|
|
+ stock: selectedItem.stock,
|
|
|
|
+ };
|
|
|
|
|
|
emit('modalCallBack', {
|
|
emit('modalCallBack', {
|
|
event: 'confirm',
|
|
event: 'confirm',
|
|
- data: selectedGoodsData,
|
|
|
|
|
|
+ data: goodsData,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function confirm() {
|
|
|
|
+ // 将Map转换为数组,获取所有选中的商品数据
|
|
|
|
+ const selectedGoodsData = Array.from(table.selectedGoods.values());
|
|
|
|
|
|
- onMounted(async () => {
|
|
|
|
- // 先预加载已选中的商品数据
|
|
|
|
- await preloadSelectedGoods();
|
|
|
|
- // 再获取第一页数据
|
|
|
|
- getData();
|
|
|
|
|
|
+ emit('modalCallBack', {
|
|
|
|
+ event: 'confirm',
|
|
|
|
+ data: selectedGoodsData,
|
|
});
|
|
});
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+onMounted(async () => {
|
|
|
|
+ // 先预加载已选中的商品数据
|
|
|
|
+ await preloadSelectedGoods();
|
|
|
|
+ // 再获取第一页数据
|
|
|
|
+ getData();
|
|
|
|
+});
|
|
</script>
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
- .goods-select {
|
|
|
|
- .goods-search {
|
|
|
|
- --el-header-height: auto;
|
|
|
|
- padding-top: var(--sa-padding);
|
|
|
|
- }
|
|
|
|
|
|
+.goods-select {
|
|
|
|
+ .goods-search {
|
|
|
|
+ --el-header-height: auto;
|
|
|
|
+ padding-top: var(--sa-padding);
|
|
|
|
+ }
|
|
|
|
|
|
- .sa-footer--submit {
|
|
|
|
- height: auto;
|
|
|
|
- padding: 16px;
|
|
|
|
- border-top: 1px solid var(--sa-border);
|
|
|
|
- background: #fff;
|
|
|
|
- }
|
|
|
|
- .title {
|
|
|
|
- height: 16px;
|
|
|
|
- line-height: 16px;
|
|
|
|
- font-size: 12px;
|
|
|
|
- font-weight: 400;
|
|
|
|
- color: var(--sa-subtitle);
|
|
|
|
- }
|
|
|
|
- .price {
|
|
|
|
- line-height: 16px;
|
|
|
|
- font-size: 12px;
|
|
|
|
- font-weight: 400;
|
|
|
|
- color: #ff4d4f;
|
|
|
|
- }
|
|
|
|
|
|
+ .sa-footer--submit {
|
|
|
|
+ height: auto;
|
|
|
|
+ padding: 16px;
|
|
|
|
+ border-top: 1px solid var(--sa-border);
|
|
|
|
+ background: #fff;
|
|
|
|
+ }
|
|
|
|
|
|
- .goods-title {
|
|
|
|
- font-size: 14px;
|
|
|
|
- color: #333;
|
|
|
|
- line-height: 1.4;
|
|
|
|
- word-break: break-word;
|
|
|
|
- display: -webkit-box;
|
|
|
|
- -webkit-box-orient: vertical;
|
|
|
|
- -webkit-line-clamp: 2;
|
|
|
|
- line-clamp: 2;
|
|
|
|
- overflow: hidden;
|
|
|
|
- text-overflow: ellipsis;
|
|
|
|
- }
|
|
|
|
- .sa-footer--submit {
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- flex-wrap: wrap;
|
|
|
|
- --el-footer-height: auto;
|
|
|
|
- min-height: 60px;
|
|
|
|
- }
|
|
|
|
|
|
+ .title {
|
|
|
|
+ height: 16px;
|
|
|
|
+ line-height: 16px;
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ font-weight: 400;
|
|
|
|
+ color: var(--sa-subtitle);
|
|
}
|
|
}
|
|
- @media only screen and (max-width: 768px) {
|
|
|
|
- .goods-price {
|
|
|
|
- display: none;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ .price {
|
|
|
|
+ line-height: 16px;
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ font-weight: 400;
|
|
|
|
+ color: #ff4d4f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .goods-title {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #333;
|
|
|
|
+ line-height: 1.4;
|
|
|
|
+ word-break: break-word;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
+ line-clamp: 2;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .goods-image {
|
|
|
|
+ width: 60px;
|
|
|
|
+ height: 60px;
|
|
|
|
+ margin-right: 12px;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+ object-fit: cover;
|
|
|
|
+ aspect-ratio: 1 / 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .sa-footer--submit {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ --el-footer-height: auto;
|
|
|
|
+ min-height: 60px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+@media only screen and (max-width: 768px) {
|
|
|
|
+ .goods-price {
|
|
|
|
+ display: none;
|
|
}
|
|
}
|
|
|
|
+}
|
|
</style>
|
|
</style>
|