Commit f97656c0 authored by cxr's avatar cxr

Merge branch 'lmy' of http://119.78.67.12/git/root/ops_2024_vue into feature/JiraTML-148/cxr

parents b1eca428 c1da8356
import { tmallabHttp } from '/@/utils/http/axios'; import { tmallabHttp } from '/@/utils/http/axios';
enum Api { enum Api {
List = '/system/productNegotiated/getList', GetStatus = '/system/opsProduct/IsOpsSupplier',
BrandList = '/regionalSpotManage/commit', List = '/system/opsProduct/getList',
GroupList = '/system/opsProduct/getTypeList',
BrandList = '/system/supplierBrandQualification/getApproveList',
ProductList = '/system/productNegotiated/getProductList',
GetAreaList = '/system/opsProduct/getAreaList', GetAreaList = '/system/opsProduct/getAreaList',
OpsAddProduct = '/system/opsProduct/opsAddProduct', OpsAddProduct = '/system/opsProduct/opsAddProduct',
GetGhsAreaList = '/system/opsProduct/getGhsAreaList', GetGhsAreaList = '/system/opsProduct/getGhsAreaList',
OpsDeleteProduct = '/system/opsProduct/opsDeleteProduct', OpsDeleteProduct = '/system/opsProduct/opsDeleteProduct',
OpsEditProduct = '/system/opsProduct/opsEditProduct', OpsEditProduct = '/system/opsProduct/opsEditProduct',
UploadOpsProduct = '/excel/excelNew/uploadOpsProduct', UploadOpsProduct = '/excel/excelNew/uploadOpsProduct',
QueryList = '/system/logProductManager/queryList',
RevokeExcelUpload = '/system/logProductManager/revokeExcelUpload', RevokeExcelUpload = '/system/logProductManager/revokeExcelUpload',
PlatformProBatchList = '/system/logNegotiationProductOperate/getList', PlatformProBatchList = '/system/logNegotiationProductOperate/getList',
PlatformProBatchGetDetail = '/system/logNegotiationProductOperate/getList', PlatformProBatchGetDetail = '/system/logNegotiationProductOperate/getDetail',
} }
/** /**
* @description: 区域现货管理列表 * @description: 区域现货管理列表
*/ */
export const regionalSpotManageListApi = (data) => export const regionalSpotManageGetStatusApi = () => tmallabHttp.post({ url: Api.GetStatus });
tmallabHttp.post({ url: Api.List, data }, { errorMessageMode: 'message'});
/**
* @description: 区域现货管理列表
*/
export const regionalSpotManageListApi = (data) =>
tmallabHttp.post({ url: Api.List, data }, { errorMessageMode: 'message' });
/** /**
* @description: 获取品牌列表 * @description: 获取品牌列表
*/ */
export const regionalSpotManageBrandListApi = (data) => export const regionalSpotManageBrandListApi = (data) =>
tmallabHttp.post({ url: Api.BrandList,data }, { errorMessageMode: 'message'}); tmallabHttp.post({ url: Api.BrandList, data });
/**
* @description: 获取分组列表
*/
export const regionalSpotManageGroupListApi = (data) =>
tmallabHttp.post({ url: Api.GroupList, data });
/**
* @description: 获取左边穿梭框商品列表
*/
export const regionalSpotManageProductListApi = (data) =>
tmallabHttp.post({ url: Api.ProductList, data });
/** /**
* @description: 获取现货区域列表 * @description: 获取现货区域列表
*/ */
export const regionalSpotManageGetAreaListApi = (data) => export const regionalSpotManageGetAreaListApi = (data) =>
tmallabHttp.post({ url: Api.GetAreaList,data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.GetAreaList, data });
/** /**
* @description: 新增商品接口 * @description: 新增商品接口
*/ */
export const regionalSpotManageOpsAddProductApi = (data) => export const regionalSpotManageOpsAddProductApi = (data) =>
tmallabHttp.post({ url: Api.OpsAddProduct, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.OpsAddProduct, data }, { errorMessageMode: 'message' });
/** /**
* @description: 获取已开通区域 * @description: 获取已开通区域
*/ */
export const regionalSpotManageGetGhsAreaListApi = (data) => export const regionalSpotManageGetGhsAreaListApi = (data) =>
tmallabHttp.post({ url: Api.GetGhsAreaList, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.GetGhsAreaList, data });
/** /**
* @description: 单条/批量删除 * @description: 单条/批量删除
*/ */
export const regionalSpotManageOpsDeleteProductApi = (data) => export const regionalSpotManageOpsDeleteProductApi = (data) =>
tmallabHttp.post({ url: Api.OpsDeleteProduct, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.OpsDeleteProduct, data }, { errorMessageMode: 'message' });
/** /**
* @description: 增加区域 * @description: 增加区域
*/ */
export const regionalSpotManageOpsEditProductApi = (data) => export const regionalSpotManageOpsEditProductApi = (data) =>
tmallabHttp.post({ url: Api.OpsEditProduct, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.OpsEditProduct, data }, { errorMessageMode: 'message' });
/** /**
* @description: 批量上传 * @description: 批量上传
*/ */
export const regionalSpotManageUploadOpsProductApi = (data) => export const regionalSpotManageUploadOpsProductApi = (data, file) =>
tmallabHttp.post({ url: Api.UploadOpsProduct, data },{ errorMessageMode: 'message' }); tmallabHttp.uploadFile(
{
url: Api.UploadOpsProduct,
method: 'POST',
data,
baseURL: import.meta.env.VITE_GLOB_TMALLAB_URL,
},
{ file, data },
);
/** /**
* @description: 任务中心获取列表 * @description: 任务中心获取列表
*/ */
export const taskCenterQueryListApi = (data) => export const taskCenterQueryListApi = (data) => tmallabHttp.post({ url: Api.QueryList, data });
tmallabHttp.post({ url: Api.RevokeExcelUpload, data },{ errorMessageMode: 'message' });
/** /**
* @description: 撤销 * @description: 撤销
*/ */
export const taskCenterRevokeExcelUploadApi = (data) => export const taskCenterRevokeExcelUploadApi = (data) =>
tmallabHttp.post({ url: Api.RevokeExcelUpload, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.RevokeExcelUpload, data }, { errorMessageMode: 'message' });
/** /**
* @description: 任务中心获取列表--平台商品批量页签 * @description: 任务中心获取列表--平台商品批量页签
*/ */
export const platformProBatchGetListApi = (data) => export const platformProBatchGetListApi = (data) =>
tmallabHttp.post({ url: Api.PlatformProBatchList, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.PlatformProBatchList, data }, { errorMessageMode: 'message' });
/** /**
* @description: 任务中心获取列表--平台商品批量页签--操作记录详情 * @description: 任务中心获取列表--平台商品批量页签--操作记录详情
*/ */
export const platformProBatchGetDetailApi = (data) => export const platformProBatchGetDetailApi = (data) =>
tmallabHttp.post({ url: Api.PlatformProBatchGetDetail, data },{ errorMessageMode: 'message' }); tmallabHttp.post({ url: Api.PlatformProBatchGetDetail, data }, { errorMessageMode: 'message' });
...@@ -69,5 +69,5 @@ span.anticon:not(.app-iconify) { ...@@ -69,5 +69,5 @@ span.anticon:not(.app-iconify) {
margin-left: 24px; margin-left: 24px;
} }
.ant-modal-body { .ant-modal-body {
margin-top: 20px; padding: 20px !important;
} }
...@@ -41,7 +41,7 @@ async function bootstrap() { ...@@ -41,7 +41,7 @@ async function bootstrap() {
app.use(Antd); app.use(Antd);
app.mount('#app'); app.mount('#app');
app.use(Antd) app.use(Antd);
} }
bootstrap(); bootstrap();
...@@ -12,6 +12,7 @@ const product: AppRouteModule = { ...@@ -12,6 +12,7 @@ const product: AppRouteModule = {
orderNo: 500, orderNo: 500,
icon: 'ion:grid-outline', icon: 'ion:grid-outline',
title: '商品管理', title: '商品管理',
roles: ['supplier'],
}, },
children: [ children: [
{ {
...@@ -29,7 +30,7 @@ const product: AppRouteModule = { ...@@ -29,7 +30,7 @@ const product: AppRouteModule = {
meta: { meta: {
title: '任务中心', title: '任务中心',
}, },
} },
], ],
}; };
......
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { Input, Button } from 'ant-design-vue'; import { Input, Button } from 'ant-design-vue';
import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue'; import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
import { import {
regionalSpotManageBrandListApi, regionalSpotManageBrandListApi,
regionalSpotManageGetAreaListApi, regionalSpotManageProductListApi,
regionalSpotManageOpsAddProductApi, regionalSpotManageGetAreaListApi,
} from '/@/api/regionalSpotManage'; regionalSpotManageOpsAddProductApi,
import { getAuthCache } from '/@/utils/auth'; } from '/@/api/regionalSpotManage';
const userInfo: any = getAuthCache('USER__INFO__'); import { getAuthCache } from '/@/utils/auth';
const ghsCode = userInfo.supplier.ghsCode; const userInfo: any = getAuthCache('USER__INFO__');
let searchBrand = ref(''); const ghsCode = userInfo.supplier.ghsCode;
let searchItemNo = ref(''); const searchBrand = ref('');
let searchBrandList = ref<any[]>([]); const searchItemNo = ref('');
const handleSearch = async (value) => { const searchBrandList = ref<any[]>([]);
const res = await regionalSpotManageBrandListApi({ brand: value }); const handleSearch = async (value) => {
if (res.code === 20000) { const res = await regionalSpotManageBrandListApi({ brand: value });
searchBrandList.value = res.data; if (res.success) {
} else { searchBrandList.value = res.data;
searchBrandList.value = []; } else {
} searchBrandList.value = [];
}; }
const closeModal = () => { };
emit('close', false); const closeModal = () => {
}; emit('close', false);
const leftData = ref<any[]>([]); };
const leftColumns = [ const leftLoading = ref(false);
{ const leftData = ref<any[]>([]);
title: '商品名称', const leftColumns = [
dataIndex: 'productName', {
key: 'productName', title: '商品名称',
width: '25%', key: 'productName',
align: 'center', width: '25%',
}, align: 'center',
{ title: '品牌', dataIndex: 'brand', key: 'brand', width: '25%', align: 'center' }, },
{ title: '货号', dataIndex: 'goodsNo', key: 'goodsNo', width: '20%', align: 'center' }, { title: '品牌', dataIndex: 'brand', key: 'brand', width: '25%', align: 'center' },
{ title: '规格', dataIndex: 'spec', key: 'spec', width: '20%', align: 'center' }, { title: '货号', dataIndex: 'goodsNo', key: 'goodsNo', width: '20%', align: 'center' },
]; { title: '规格', dataIndex: 'spec', key: 'spec', width: '20%', align: 'center' },
const pagination = ref({ ];
size: 'small', const pagination = ref({
pageSize: 10, size: 'small',
current: 1, pageSize: 10,
total: 0, current: 1,
showTotal: (total) => `共 ${total} 条`, total: 0,
hideOnSinglePage: false, showTotal: (total) => `共 ${total} 条`,
showQuickJumper: true, hideOnSinglePage: false,
showSizeChanger: true, showQuickJumper: true,
pageSizeOptions: ['10', '20', '30', '50', '100'], showSizeChanger: true,
onChange: (current) => { pageSizeOptions: ['10', '20', '30', '50', '100'],
pagination.value.current = current; onChange: (current) => {
getLeftData(); pagination.value.current = current;
}, getLeftData();
onShowSizeChange: (size) => { },
pagination.value.pageSize = size; onShowSizeChange: (size) => {
getLeftData(); pagination.value.pageSize = size;
}, getLeftData();
}); },
const getLeftData = () => { });
leftData.value = [ const reset = () => {
{ searchBrand.value = '';
productName: '测试产品1', searchItemNo.value = '';
brand: '测试品牌1', pagination.value.current = 1;
goodsNo: '213651', getLeftData();
spec: '100ml', };
sysid: '1', const getLeftData = async () => {
}, const param = {
{ pageIndex: pagination.value.current,
productName: '测试产品2', pageSize: pagination.value.pageSize,
brand: '测试品牌2', ghsCode: ghsCode,
goodsNo: '213652', productName: '',
spec: '100ml', brand: searchBrand.value,
sysid: '2', goodsNo: searchItemNo.value,
}, };
{ leftLoading.value = true;
productName: '测试产品3', const res = await regionalSpotManageProductListApi(param);
brand: '测试品牌3', if (res.success) {
goodsNo: '213653', leftData.value = res.data;
spec: '100ml', } else {
sysid: '3', leftData.value = [];
}, }
{ leftLoading.value = false;
productName: '测试产品4', if (rightData.value.length > 0) {
brand: '测试品牌4', for (let i = 0; i < rightData.value.length; i++) {
goodsNo: '213654', if (
spec: '100ml', leftData.value.findIndex(
sysid: '4', (v) =>
}, v.brand + v.goodsNo + v.spec ===
{ rightData.value[i].brand + rightData.value[i].goodsNo + rightData.value[i].spec,
productName: '测试产品5', ) !== -1
brand: '测试品牌5', ) {
goodsNo: '213655', leftData.value.find(
spec: '100ml', (v) =>
sysid: '5', v.brand + v.goodsNo + v.spec ===
choice: true, rightData.value[i].brand + rightData.value[i].goodsNo + rightData.value[i].spec,
}, ).choice = true;
{ }
productName: '测试产品6', }
brand: '测试品牌6', }
goodsNo: '213656', leftData.value = [...leftData.value];
spec: '100ml', pagination.value.total = leftData.value.length;
sysid: '6', };
choice: true, const selectedRowKeys = ref<any[]>([]);
}, const selectedRows = ref<any[]>([]);
]; const rowSelection = computed(() => {
if (rightData.value.length > 0) { return {
for (let i = 0; i < rightData.value.length; i++) { selectedRowKeys: selectedRowKeys.value,
if ( onChange: (RowKeys, Rows) => {
leftData.value.findIndex( selectedRowKeys.value = RowKeys;
(v) => selectedRows.value = Rows;
v.brand + v.goodsNo + v.spec === },
rightData.value[i].brand + rightData.value[i].goodsNo + rightData.value[i].spec, getCheckboxProps: (record) => ({
) !== -1 disabled: record.choice === true,
) { }),
leftData.value.find( };
(v) => });
v.brand + v.goodsNo + v.spec === const toRight = () => {
rightData.value[i].brand + rightData.value[i].goodsNo + rightData.value[i].spec, let arr = JSON.parse(JSON.stringify(selectedRows.value));
).choice = true; rightData.value = [...arr, ...rightData.value];
} for (let i = 0; i < selectedRows.value.length; i++) {
} if (
} leftData.value.findIndex(
leftData.value = [...leftData.value]; (v) =>
pagination.value.total = leftData.value.length; v.brand + v.goodsNo + v.spec ===
}; selectedRows.value[i].brand +
let selectedRowKeys = ref<any[]>([]); selectedRows.value[i].goodsNo +
let selectedRows = ref<any[]>([]); selectedRows.value[i].spec,
const rowSelection = computed(() => { ) !== -1
return { ) {
selectedRowKeys: selectedRowKeys.value, leftData.value.find(
onChange: (RowKeys, Rows) => { (v) =>
selectedRowKeys.value = RowKeys; v.brand + v.goodsNo + v.spec ===
selectedRows.value = Rows; selectedRows.value[i].brand +
}, selectedRows.value[i].goodsNo +
getCheckboxProps: (record) => ({ selectedRows.value[i].spec,
disabled: record.choice === true, ).choice = true;
}), }
}; }
}); leftData.value = [...leftData.value];
const toRight = () => { selectedRowKeys.value = [];
console.log(selectedRows.value); selectedRows.value = [];
let arr = JSON.parse(JSON.stringify(selectedRows.value)); };
rightData.value = [...arr, ...rightData.value]; const rightData = ref<any[]>([]);
for (let i = 0; i < selectedRows.value.length; i++) { const rightSelectedRowKeys = ref<any[]>([]);
if ( const rightSelectedRows = ref<any[]>([]);
leftData.value.findIndex( const rightRowSelection = computed(() => {
(v) => return {
v.brand + v.goodsNo + v.spec === selectedRowKeys: rightSelectedRowKeys.value,
selectedRows.value[i].brand + onChange: (RowKeys, Rows) => {
selectedRows.value[i].goodsNo + rightSelectedRowKeys.value = RowKeys;
selectedRows.value[i].spec, rightSelectedRows.value = Rows;
) !== -1 },
) { };
leftData.value.find( });
(v) => const toLeft = () => {
v.brand + v.goodsNo + v.spec === for (let i = 0; i < rightSelectedRows.value.length; i++) {
selectedRows.value[i].brand + if (
selectedRows.value[i].goodsNo + leftData.value.findIndex(
selectedRows.value[i].spec, (v) =>
).choice = true; v.brand + v.goodsNo + v.spec ===
} rightSelectedRows.value[i].brand +
} rightSelectedRows.value[i].goodsNo +
leftData.value = [...leftData.value]; rightSelectedRows.value[i].spec,
selectedRowKeys.value = []; ) !== -1
selectedRows.value = []; ) {
}; leftData.value.find(
const rightData = ref<any[]>([]); (v) =>
const rightSelectedRowKeys = ref<any[]>([]); v.brand + v.goodsNo + v.spec ===
const rightSelectedRows = ref<any[]>([]); rightSelectedRows.value[i].brand +
const rightRowSelection = computed(() => { rightSelectedRows.value[i].goodsNo +
return { rightSelectedRows.value[i].spec,
selectedRowKeys: rightSelectedRowKeys.value, ).choice = false;
onChange: (RowKeys, Rows) => { rightData.value.splice(
rightSelectedRowKeys.value = RowKeys; rightData.value.findIndex(
rightSelectedRows.value = Rows; (v) =>
}, v.brand + v.goodsNo + v.spec ==
}; rightSelectedRows.value[i].brand +
}); rightSelectedRows.value[i].goodsNo +
const toLeft = () => { rightSelectedRows.value[i].spec,
for (let i = 0; i < rightSelectedRows.value.length; i++) { ),
if ( 1,
leftData.value.findIndex( );
(v) => } else {
v.brand + v.goodsNo + v.spec === rightData.value.splice(
rightSelectedRows.value[i].brand + rightData.value.findIndex(
rightSelectedRows.value[i].goodsNo + (v) =>
rightSelectedRows.value[i].spec, v.brand + v.goodsNo + v.spec ==
) !== -1 rightSelectedRows.value[i].brand +
) { rightSelectedRows.value[i].goodsNo +
leftData.value.find( rightSelectedRows.value[i].spec,
(v) => ),
v.brand + v.goodsNo + v.spec === 1,
rightSelectedRows.value[i].brand + );
rightSelectedRows.value[i].goodsNo + }
rightSelectedRows.value[i].spec, }
).choice = false; leftData.value = [...leftData.value];
rightData.value.splice( rightData.value = [...rightData.value];
rightData.value.findIndex( rightSelectedRowKeys.value = [];
(v) => rightSelectedRows.value = [];
v.brand + v.goodsNo + v.spec == };
rightSelectedRows.value[i].brand + const rowClassName = () => {
rightSelectedRows.value[i].goodsNo + return 'table-back';
rightSelectedRows.value[i].spec, };
), const loading = ref(false);
1, const addressLoading = ref(false);
); const goNext = async () => {
} else { if (!rightData.value.length) return message.error('请先选择商品');
rightData.value.splice( addressVisible.value = true;
rightData.value.findIndex( addressLoading.value = true;
(v) => const res = await regionalSpotManageGetAreaListApi({});
v.brand + v.goodsNo + v.spec == if (res.success) {
rightSelectedRows.value[i].brand + areaList.value = res.data;
rightSelectedRows.value[i].goodsNo + } else {
rightSelectedRows.value[i].spec, areaList.value = [];
), }
1, addressLoading.value = false;
); };
} // ==================================================
} const confirmLoading = ref(false);
leftData.value = [...leftData.value]; const addressVisible = ref(false);
rightData.value = [...rightData.value]; const checkboxValue = ref([]);
rightSelectedRowKeys.value = []; interface AreaIds {
rightSelectedRows.value = []; city?: string;
}; cityId?: number;
const rowClassName = () => { creationTime?: string;
return 'table-back'; creator?: string;
}; id?: number;
let loading = ref(false); province?: string;
let addressLoading = ref(false); provinceId?: number;
const goNext = async () => { }
if (!rightData.value.length) return message.error('请先选择商品'); const areaList = ref<AreaIds[]>([]);
addressVisible.value = true; const handleCancel = () => {
addressLoading.value = true; addressVisibleClose();
const res = await regionalSpotManageGetAreaListApi({}); };
if (res.code === 20000) { const goPrevious = () => {
areaList.value = res.data; addressVisibleClose();
} else { };
areaList.value = []; const addressVisibleClose = () => {
} addressVisible.value = false;
addressLoading.value = false; checkboxValue.value = [];
}; };
// ================================================== const confirm = async () => {
const confirmLoading = ref(false); if (!checkboxValue.value.length) return message.error('请选择现货区域');
const addressVisible = ref(false); const param = ref<{ [key: string]: any }>({
const checkboxValue = ref([]); products: [],
const areaList = ref<any[]>([ areas: '',
{ });
id: '0', param.value.products = rightData.value.map((v) => {
provinceId: '0', return {
province: '北京市', goodsNo: v.goodsNo,
cityId: 0, brand: v.brand,
city: '市辖区', spec: v.spec,
creator: '', ghscode: ghsCode,
creationTime: '', };
}, });
{ param.value.areas = checkboxValue.value;
id: '1', confirmLoading.value = true;
provinceId: '1', const res = await regionalSpotManageOpsAddProductApi(param.value);
province: '河北省', if (res.success) {
cityId: 1, message.success('新增成功');
city: '保定市', addressVisibleClose();
creator: '', emit('close', false, 'refresh');
creationTime: '', } else {
}, message.error(res.message);
{ }
id: '2', confirmLoading.value = false;
provinceId: '2', };
province: '河北省', </script>
cityId: 2,
city: '石家庄市', <template>
creator: '', <a-modal
creationTime: '', :visible="true"
}, title="新增区域现货商品"
{ :width="1200"
id: '3', @cancel="closeModal"
provinceId: '3', :maskClosable="false"
province: '河北省', :keyboard="false"
cityId: 3, >
city: '秦皇岛市', <template #footer>
creator: '', <a-button key="back" @click="closeModal">取消</a-button>
creationTime: '', <a-button key="submit" type="primary" :loading="loading" @click="goNext">下一步</a-button>
}, </template>
{ <div>
id: '4', <span>品牌名称:</span>
provinceId: '4', <a-select
province: '河北省', v-model:value="searchBrand"
cityId: 3, show-search
city: '承德市', placeholder="请输入品牌名称"
creator: '', style="width: 200px"
creationTime: '', :default-active-first-option="false"
}, :show-arrow="false"
]); :filter-option="false"
const handleCancel = () => { :not-found-content="null"
addressVisibleClose(); @search="handleSearch"
}; >
const goPrevious = () => { <a-select-option
addressVisibleClose(); v-for="item in searchBrandList"
}; :key="item.brand"
const addressVisibleClose = () => { :label="item.brand"
addressVisible.value = false; :value="item.brand"
checkboxValue.value = []; >
}; {{ item.brand }}
const confirm = async () => { </a-select-option>
if (!checkboxValue.value.length) return message.error('请选择现货区域'); </a-select>
const param = ref<{ [key: string]: any }>({ <span style="margin-left: 15px">货号:</span>
products: [], <Input
areas: '', v-model:value="searchItemNo"
}); allow-clear
param.value.products = rightData.value.map((v) => { placeholder="请输入货号"
return { style="width: 200px"
goodsNo: v.goodsNo, />
brand: v.brand, <Button @click="reset" style="margin-left: 10px">重置</Button>
spec: v.spec, <Button @click="getLeftData" type="primary" style="margin-left: 10px">查询</Button>
ghscode: ghsCode, </div>
}; <div class="main">
}); <div class="left">
param.value.areas = checkboxValue.value.join; <div class="header">
console.log(param.value); <div>筛选结果商品</div>
confirmLoading.value = true; <span>{{ selectedRowKeys.length }}/{{ pagination.total }}</span>
const res = await regionalSpotManageOpsAddProductApi(param.value); </div>
if (res.code === 20000) { <div class="table">
message.success('新增成功'); <a-table
addressVisibleClose(); bordered
emit('close', false); :data-source="leftData"
} else { :columns="leftColumns"
message.error(res.message); :pagination="pagination"
} :row-selection="rowSelection"
confirmLoading.value = false; :rowKey="(record) => record.brand + record.goodsNo + record.spec"
}; :scroll="{ x: false, y: 280 }"
</script> :rowClassName="rowClassName"
:loading="leftLoading"
<template> >
<a-modal <template #bodyCell="{ column, record }">
:visible="true" <template v-if="column.key === 'productName'">
title="新增区域现货商品" <span>{{ record.chineseName ? record.chineseName : record.englishName }}</span>
:width="1200" </template>
@cancel="closeModal" </template>
:maskClosable="false" </a-table>
:keyboard="false" </div>
> </div>
<template #footer> <div class="operate">
<a-button key="back" @click="closeModal">取消</a-button> <div style="margin-top: 200px; display: flex">
<a-button key="submit" type="primary" :loading="loading" @click="goNext">下一步</a-button> <a-button
</template> @click="toLeft"
<div> type="primary"
<span>品牌名称:</span> :disabled="rightSelectedRowKeys.length === 0"
<a-select style="display: block; margin-bottom: 10px; margin-right: 10px"
v-model:value="searchBrand" >
show-search <template #icon>
placeholder="请输入品牌名称" <LeftOutlined />
style="width: 200px" </template>
:default-active-first-option="false" </a-button>
:show-arrow="false" <a-button
:filter-option="false" @click="toRight"
:not-found-content="null" type="primary"
@search="handleSearch" style="display: block"
> :disabled="selectedRowKeys.length === 0"
<a-select-option >
v-for="item in searchBrandList" <template #icon>
:key="item.value" <RightOutlined />
:label="item.label" </template>
:value="item.value" </a-button>
> </div>
{{ item.label }} </div>
</a-select-option> <div class="right">
</a-select> <div class="header">
<span style="margin-left: 15px">货号:</span> <div>被选中商品</div>
<Input <span>{{ rightSelectedRowKeys.length }}/{{ rightData.length }}</span>
v-model:value="searchItemNo" </div>
allow-clear <div class="table">
placeholder="请输入货号" <a-table
style="width: 200px" :data-source="rightData"
/> :columns="leftColumns"
<Button style="margin-left: 10px">重置</Button> :pagination="false"
<Button @click="getLeftData" type="primary" style="margin-left: 10px">查询</Button> :rowKey="(record) => record.brand + record.goodsNo + record.spec"
</div> :scroll="{ x: false, y: 280 }"
<div class="main"> :rowClassName="rowClassName"
<div class="left"> :row-selection="rightRowSelection"
<div class="header"> >
<div>筛选结果商品</div> <template #bodyCell="{ column, record }">
<span>{{ selectedRowKeys.length }}/{{ pagination.total }}</span> <template v-if="column.key === 'productName'">
</div> <span>{{ record.chineseName ? record.chineseName : record.englishName }}</span>
<div class="table"> </template>
<a-table </template>
bordered </a-table>
:data-source="leftData" </div>
:columns="leftColumns" </div>
:pagination="pagination" </div>
:row-selection="rowSelection" </a-modal>
:rowKey="(record) => record.brand + record.goodsNo + record.spec" <a-modal
:scroll="{ x: false, y: 280 }" v-model:visible="addressVisible"
:rowClassName="rowClassName" title="新增区域现货商品"
:loading="loading" @cancel="handleCancel"
> @ok="confirm"
<!-- <template #bodyCell="{ column, record }"> :width="1200"
<template v-if="column.key === 'productName'"> :maskClosable="false"
<span>{{ record.chineseName ? record.chineseName : record.englishName }}</span> :keyboard="false"
</template> >
</template> --> <template #footer>
</a-table> <a-button :loading="confirmLoading" @click="handleCancel">取消</a-button>
</div> <a-button :loading="confirmLoading" @click="goPrevious">上一步</a-button>
</div> <a-button type="primary" :loading="confirmLoading" @click="confirm">提交</a-button>
<div class="operate"> </template>
<div style="margin-top: 200px; display: flex"> <a-alert type="warning">
<a-button <template #message>
@click="toLeft" <span style="color: red">特别提醒:</span
type="primary" >北京市-直辖市;天津市-直辖市。本次设置为,北京市-直辖市;四川省-成都市。提交后,商品现货区域将更新为
:disabled="rightSelectedRowKeys.length === 0" 北京市-直辖市;天津市-直辖市;四川省-成都市。
style="display: block; margin-bottom: 10px; margin-right: 10px" </template>
> </a-alert>
<template #icon> <a-spin v-if="addressLoading" style="height: 150px; width: 100%; line-height: 150px" />
<LeftOutlined /> <div v-else>
</template> <p style="margin-top: 15px">选择现货区域:</p>
</a-button> <a-checkbox-group v-model:value="checkboxValue" style="width: 100%">
<a-button <a-row>
@click="toRight" <a-col :span="6" v-for="(item, index) in areaList" :key="index">
type="primary" <a-checkbox :value="item.cityId">{{ item.province }}-{{ item.city }}</a-checkbox>
style="display: block" </a-col>
:disabled="selectedRowKeys.length === 0" </a-row>
> </a-checkbox-group>
<template #icon> </div>
<RightOutlined /> </a-modal>
</template> </template>
</a-button>
</div> <style lang="less" scoped>
</div> .main {
<div class="right"> display: flex;
<div class="header"> justify-content: space-around;
<div>被选中商品</div> width: 100%;
<span>{{ rightSelectedRowKeys.length }}/{{ rightData.length }}</span> margin-top: 15px;
</div> .left {
<div class="table"> width: 45%;
<a-table border: 1px solid #ddd;
:data-source="rightData" height: 450px;
:columns="leftColumns" .header {
:pagination="false" display: flex;
:rowKey="(record) => record.brand + record.goodsNo + record.spec" justify-content: space-between;
:scroll="{ x: false, y: 280 }" align-items: center;
:rowClassName="rowClassName" padding: 0 10px;
:row-selection="rightRowSelection" height: 60px;
/> background: #f3f6f9;
</div> }
</div> }
</div> .right {
</a-modal> width: 45%;
<a-modal border: 1px solid #ddd;
v-model:visible="addressVisible" height: 450px;
title="新增区域现货商品" .header {
@cancel="handleCancel" display: flex;
@ok="confirm" justify-content: space-between;
:width="1200" align-items: center;
:maskClosable="false" padding: 0 10px;
:keyboard="false" height: 60px;
> background: #f3f6f9;
<template #footer> }
<a-button :loading="confirmLoading" @click="handleCancel">取消</a-button> }
<a-button :loading="confirmLoading" @click="goPrevious">上一步</a-button> .operate {
<a-button type="primary" :loading="confirmLoading" @click="confirm">提交</a-button> width: 10%;
</template> height: 450px;
<a-alert type="warning"> display: flex;
<template #message> justify-content: center;
<span style="color: red">特别提醒:</span align-content: center;
>北京市-直辖市;天津市-直辖市。本次设置为,北京市-直辖市;四川省-成都市。提交后,商品现货区域将更新为 }
北京市-直辖市;天津市-直辖市;四川省-成都市。 }
</template> /deep/.table-back {
</a-alert> background-color: #fff;
<a-spin v-if="addressLoading" style="height: 150px; width: 100%; line-height: 150px" /> }
<div v-else> </style>
<p style="margin-top: 15px">选择现货区域:</p>
<a-checkbox-group v-model:value="checkboxValue" style="width: 100%">
<a-row>
<a-col :span="6" v-for="(item, index) in areaList" :key="index">
<a-checkbox :value="item.id">{{ item.province }}-{{ item.city }}</a-checkbox>
</a-col>
</a-row>
</a-checkbox-group>
</div>
</a-modal>
</template>
<style lang="less" scoped>
.main {
display: flex;
justify-content: space-around;
width: 100%;
margin-top: 15px;
.left {
width: 45%;
border: 1px solid #ddd;
height: 450px;
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
height: 60px;
background: #f3f6f9;
}
}
.right {
width: 45%;
border: 1px solid #ddd;
height: 450px;
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
height: 60px;
background: #f3f6f9;
}
}
.operate {
width: 10%;
height: 450px;
display: flex;
justify-content: center;
align-content: center;
}
}
/deep/.table-back {
background-color: #fff;
}
</style>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
const config = import.meta.env const config = import.meta.env;
import { import { taskCenterQueryListApi } from '/@/api/regionalSpotManage';
taskCenterQueryListApi, onMounted(async () => {
} from '/@/api/regionalSpotManage'; getList();
onMounted(async () => { });
getList() let list = ref<any[]>([]);
}); let listLoading = ref(false);
let list = ref<any[]>([]) const downLoad = (url) => {
let listLoading = ref(false) window.open(config.VITE_GLOB_TMALLAB_URL + '/system/' + url, '_blank');
const downLoad = (url) => { };
window.open(config.VITE_GLOB_API_URL + '/system/' + url, '_blank') const getList = async () => {
} listLoading.value = true;
const getList = async () => { const res = await taskCenterQueryListApi({ type: 1 });
listLoading.value = true if (res.success) {
const res = await taskCenterQueryListApi({type:1}) list.value = res.data;
if (res.code === 20000) { } else {
list.value = res.data list.value = [];
} else { }
list.value = [] listLoading.value = false;
} };
listLoading.value = false </script>
}
</script> <template>
<div>
<template> <a-button @click="getList" type="primary">刷新数据</a-button>
<div> </div>
<a-button @click="getList" type="primary">刷新数据</a-button> <a-table
</div> :data-source="list"
<a-table :loading="listLoading"
:data-source="list" bordered
:loading="listLoading" :rowKey="(record) => record.sysid"
bordered style="margin-top: 15px"
:rowKey="(record) => record.sysid" >
style="margin-top: 15px" <a-table-column title="操作时间" align="center" :width="100">
> <template #default="{ record }">
<a-table-column title="操作时间" align="center" :width="100"> {{ record.createTime }}
<template v-slot="{record}"> </template>
{{ record.createTime }} </a-table-column>
</template> <a-table-column title="类型" align="center" :width="100">
</a-table-column> <template #default="{ record }">
<a-table-column title="类型" align="center" :width="100"> {{ record.type }}
<template v-slot="{record}"> </template>
{{ record.type }} </a-table-column>
</template> <a-table-column title="导出状态" align="center" :width="100">
</a-table-column> <template #default="{ record }">
<a-table-column title="导出状态" align="center" :width="100"> <p>{{ record.status == 0 ? '待进行 ' : record.status == 1 ? '进行中' : '已完成' }}</p>
<template v-slot="{record}"> </template>
<p>{{ record.status == 0 ? '待进行 ': (record.status == 1 ? '进行中' : '已完成') }}</p> </a-table-column>
</template> <a-table-column title="数据量" align="center" :width="100">
</a-table-column> <template #default="{ record }">
<a-table-column title="数据量" align="center" :width="100"> {{ record.successNum }}
<template v-slot="{record}"> </template>
{{ record.successNum }} </a-table-column>
</template> <a-table-column title="操作人" align="center" :width="100">
</a-table-column> <template #default="{ record }">
<a-table-column title="操作人" align="center" :width="100"> {{ record.createName }}
<template v-slot="{record}"> </template>
{{ record.createName }} </a-table-column>
</template> <a-table-column title="操作" align="center" :width="200">
</a-table-column> <template #default="{ record }">
<a-table-column title="操作" align="center" :width="200"> <a-button v-if="record.fileUrl" type="link" @click="downLoad(record.fileUrl)"
<template v-slot="{record}"> >下载文件</a-button
<Button v-if="record.fileUrl" type="link" @click="downLoad(record.fileUrl)">下载文件</Button> >
<span v-else>——</span> <span v-else>——</span>
</template> </template>
</a-table-column> </a-table-column>
</a-table> </a-table>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped></style>
</style>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { import {
Form, Form,
FormItem, FormItem,
Input, Input,
Button, Button,
Select, Select,
SelectOption, SelectOption,
Row, Row,
Col, Col,
message, message,
} from 'ant-design-vue'; } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue'; import { UploadOutlined } from '@ant-design/icons-vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { getAuthCache } from '/@/utils/auth'; import { getAuthCache } from '/@/utils/auth';
import { import {
regionalSpotManageBrandListApi, regionalSpotManageBrandListApi,
regionalSpotManageListApi, regionalSpotManageGroupListApi,
regionalSpotManageGetAreaListApi, regionalSpotManageListApi,
regionalSpotManageGetGhsAreaListApi, regionalSpotManageGetAreaListApi,
regionalSpotManageOpsDeleteProductApi, regionalSpotManageGetGhsAreaListApi,
regionalSpotManageOpsEditProductApi, regionalSpotManageOpsDeleteProductApi,
regionalSpotManageUploadOpsProductApi, regionalSpotManageOpsEditProductApi,
} from '/@/api/regionalSpotManage'; regionalSpotManageUploadOpsProductApi,
import addProductModal from './addProduct.vue'; } from '/@/api/regionalSpotManage';
const config = import.meta.env; import addProductModal from './addProduct.vue';
const userInfo: any = getAuthCache('USER__INFO__'); const config = import.meta.env;
const ghsCode = userInfo.supplier.ghsCode; const userInfo: any = getAuthCache('USER__INFO__');
const router = useRouter(); const ghsCode = userInfo.supplier.ghsCode;
const list = ref<any[]>([]); const ghsName = userInfo.supplier.ghsName;
onMounted(async () => { const router = useRouter();
getList(); const list = ref<any[]>([]);
getAllAreaList(); onMounted(async () => {
}); getList();
const searchForm = ref<{ getAllAreaList();
brandList: any; getGroupOption();
goodsNo: any; });
areaIds: any; const searchForm = ref<{
types: any; brands: any;
}>({ goodsNo: any;
brandList: [], areaIds: any;
goodsNo: '', types: any;
areaIds: [], }>({
types: [], brands: [],
}); goodsNo: '',
const areaIdsOption = ref([ areaIds: [],
{ label: '区域1', value: '区域1' }, types: [],
{ label: '区域2', value: '区域2' }, });
]); interface AreaIds {
const typesOption = ref([ city?: string;
{ label: '组1', value: '组1' }, cityId?: number;
{ label: '组2', value: '组2' }, creationTime?: string;
]); creator?: string;
let searchBrandList = ref<any[]>([]); id?: number;
const handleSearch = async (value) => { province?: string;
const res = await regionalSpotManageBrandListApi({ brand: value }); provinceId?: number;
if (res.code === 20000) { }
searchBrandList.value = res.data; const areaIdsOption = ref<AreaIds[]>([]);
} else { const typesOption = ref([]);
searchBrandList.value = []; const searchBrandList = ref<any[]>([]);
} const handleSearch = async (value) => {
}; const res = await regionalSpotManageBrandListApi({ brand: value });
let listLoading = ref(false); if (res.success) {
const pagination = ref({ searchBrandList.value = res.data;
pageSize: 10, } else {
current: 1, searchBrandList.value = [];
total: 0, }
showTotal: (total) => `共 ${total} 条`, };
hideOnSinglePage: false, const listLoading = ref(false);
showQuickJumper: true, const pagination = ref({
showSizeChanger: true, pageSize: 10,
pageSizeOptions: ['10', '20', '30', '50', '100'], current: 1,
onChange: (current) => { total: 0,
pagination.value.current = current; showTotal: (total) => `共 ${total} 条`,
getList(); hideOnSinglePage: false,
}, showQuickJumper: true,
onShowSizeChange: (size) => { showSizeChanger: true,
pagination.value.pageSize = size; pageSizeOptions: ['10', '20', '30', '50', '100'],
getList(); onChange: (current) => {
}, pagination.value.current = current;
}); getList();
const getList = async () => { },
const pager = ref({ onShowSizeChange: (size) => {
pageIndex: 1, pagination.value.pageSize = size;
pageSize: 10, getList();
}); },
const param = ref({ });
...searchForm.value, const getList = async () => {
...pager.value, const pager = ref({
}); pageIndex: 1,
param.value.areaIds = param.value.areaIds ? param.value.areaIds : []; pageSize: 10,
param.value.types = param.value.types ? param.value.types : []; });
listLoading.value = true; const param = ref({
const res = await regionalSpotManageListApi(param.value); ...searchForm.value,
if (res.code === 20000) { ...pager.value,
list.value = res.data; });
pagination.value.total = res.data[0].total; param.value.areaIds = param.value.areaIds ? param.value.areaIds : [];
} else { param.value.types = param.value.types ? param.value.types : [];
list.value = []; listLoading.value = true;
pagination.value.total = 0; const res = await regionalSpotManageListApi(param.value);
} if (res.success) {
listLoading.value = false; list.value = res.data;
list.value = [ pagination.value.total = res.data[0].total;
{ } else {
productName: '测试商品', list.value = [];
brand: '测试品牌', pagination.value.total = 0;
goodsNo: '45641', }
spec: '100ml', listLoading.value = false;
productStatus: '上架', };
sysid: '1', const onRset = () => {
}, searchForm.value.brands = [];
{ searchForm.value.goodsNo = '';
productName: 'ffff', searchForm.value.areaIds = [];
brand: 'fff', searchForm.value.types = [];
goodsNo: 'fff', getList();
spec: 'ff', };
productStatus: '上架', const onSearch = () => {
sysid: '2', pagination.value.current = 1;
}, getList();
]; };
};
const onRset = () => { const showModal = ref(false);
searchForm.value.brandList = []; const addProduct = () => {
searchForm.value.goodsNo = ''; showModal.value = true;
searchForm.value.areaIds = []; };
searchForm.value.types = []; // 关闭新增商品弹窗
getList(); const closeVisible = (val, action) => {
}; showModal.value = val;
const onSearch = () => { if (action) {
pagination.value.pageSize = 1; onSearch();
getList(); }
}; };
let showModal = ref(false); const curItem = ref<{ [key: string]: any }>({});
const addProduct = () => {
showModal.value = true; // =========查看区域现货 statr ===========
}; const loading1 = ref(false);
// 关闭新增商品弹窗 const visible = ref(false);
const closeVisible = (val) => { const regionalSpotGoods = ref([]);
showModal.value = val; const viewCurrent = async (val) => {
}; curItem.value = val;
visible.value = true;
let curItem = ref<{ [key: string]: any }>({}); const param = ref<{ [key: string]: any }>({
products: [
// =========查看区域现货 statr =========== {
const loading1 = ref(false); goodsNo: val.goodsNo,
const visible = ref(false); brand: val.brand,
const regionalSpotGoods = ref([]); spec: val.spec,
const viewCurrent = async (val) => { ghscode: ghsCode,
curItem.value = val; },
visible.value = true; ],
const param = ref<{ [key: string]: any }>({ });
products: [ loading1.value = true;
{ const result = await getAreaList(param.value);
goodsNo: val.goodsNo, regionalSpotGoods.value = result;
brand: val.brand, loading1.value = false;
spec: val.spec, };
ghscode: ghsCode, const getAreaList = async (param) => {
}, const res = await regionalSpotManageGetGhsAreaListApi(param);
], if (res.success) {
}); return res.data;
console.log(param.value); } else {
loading1.value = true; return [];
const result = await getAreaList(param.value); }
regionalSpotGoods.value = result; };
loading1.value = false; // ==========查看区域现货 end =============
};
const getAreaList = async (param) => { const selectedRowKeys = ref([]);
const res = await regionalSpotManageGetGhsAreaListApi(param); const selectedRows = ref<any[]>([]);
if (res.code === 20000) { const onSelectChange = (Keys, Rows) => {
return res.data; selectedRowKeys.value = Keys;
} else { selectedRows.value = Rows;
return []; };
} // ===============增加区域 start=======================
}; const addVisible = ref(false);
// ==========查看区域现货 end ============= const addAreaLoading = ref(false);
const addCheckboxValue = ref<number[]>([]);
let selectedRowKeys = ref([]); const addArea = async (row) => {
let selectedRows = ref<any[]>([]); curItem.value = row;
const onSelectChange = (Keys, Rows) => { addVisible.value = true;
selectedRowKeys.value = Keys; addAreaLoading.value = true;
selectedRows.value = Rows; const param = ref<{ [key: string]: any }>({
}; products: [
// ===============增加区域 start======================= {
let addVisible = ref(false); goodsNo: row.goodsNo,
let addAreaLoading = ref(false); brand: row.brand,
let addCheckboxValue = ref(['0']); spec: row.spec,
const addArea = async (row) => { ghscode: ghsCode,
curItem.value = row; },
addVisible.value = true; ],
addAreaLoading.value = true; });
const param = ref<{ [key: string]: any }>({ const result = await getAreaList(param.value);
products: [ delAreaList.value = result;
{ const curArr = delAreaList.value.map((it) => it.cityCode);
goodsNo: row.goodsNo, for (const k of allAreaList.value) {
brand: row.brand, if (curArr.includes(k.cityId)) {
spec: row.spec, addCheckboxValue.value.push(k.cityId);
ghscode: ghsCode, k.disabled = true;
}, }
], }
}); addAreaLoading.value = false;
const result = await getAreaList(param.value); };
delAreaList.value = result; const addVisibleCancel = () => {
const curArr = delAreaList.value.map((it) => it.id); addVisible.value = false;
for (const k of allAreaList.value) { addCheckboxValue.value = [];
if (curArr.includes(k.id)) { };
addCheckboxValue.value.push(k.id); const confirmAddLoading = ref(false);
k.disabled = true; const confirmAddArea = async () => {
} const param = ref<{ [key: string]: any }>({
} products: [
addAreaLoading.value = false; {
}; goodsNo: curItem.value.goodsNo,
const addVisibleCancel = () => { brand: curItem.value.brand,
addVisible.value = false; spec: curItem.value.spec,
addCheckboxValue.value = []; ghscode: ghsCode,
}; },
let confirmAddLoading = ref(false); ],
const confirmAddArea = async () => { areas: addCheckboxValue.value,
const param = ref<{ [key: string]: any }>({ });
products: [ confirmAddLoading.value = true;
{ const res = await regionalSpotManageOpsEditProductApi(param.value);
goodsNo: curItem.value.goodsNo, if (res.success) {
brand: curItem.value.brand, message.success('添加区域成功');
spec: curItem.value.spec, addVisibleCancel();
ghscode: ghsCode, } else {
}, message.error(res.message);
], }
areas: addCheckboxValue.value.join, confirmAddLoading.value = false;
}); };
confirmAddLoading.value = true; // ===============增加区域 end=======================
const res = await regionalSpotManageOpsEditProductApi(param.value);
if (res.success) { // ================区域现货商品删除 start=====================
message.success('添加区域成功'); const delVisible = ref(false);
} else { const delLoading = ref(false);
message.error(res.message); const deleteNum = ref(0);
} const radioValue = ref(1);
confirmAddLoading.value = false; const delAreaList = ref<any[]>([]); //已添加的区域
}; const delCheckboxValue = ref([]);
// ===============增加区域 end======================= const del = async (val) => {
curItem.value = val;
// ================区域现货商品删除 start===================== deleteNum.value = 1;
let delVisible = ref(false); delVisible.value = true;
let delLoading = ref(false); const param = ref<{ [key: string]: any }>({
let deleteNum = ref(0); products: [
let radioValue = ref(1); {
let delAreaList = ref<any[]>([ goodsNo: val.goodsNo,
{ brand: val.brand,
id: '0', spec: val.spec,
provinceId: '0', ghscode: ghsCode,
province: '北京市', },
cityId: 0, ],
city: '市辖区', });
creator: '', delLoading.value = true;
creationTime: '', const res = await getAreaList(param.value);
}, if (res) {
{ delAreaList.value = res;
id: '1', }
provinceId: '1', delLoading.value = false;
province: '河北省', };
cityId: 1, const delVisibleCancel = () => {
city: '保定市', delVisible.value = false;
creator: '', deleteNum.value = 0;
creationTime: '', radioValue.value = 1;
}, delCheckboxValue.value = [];
]); //已添加的区域 isBatchDel.value = false;
let delCheckboxValue = ref([]); };
const del = async (val) => { const delConfirLoading = ref(false);
curItem.value = val; const confirmDel = async () => {
deleteNum.value = 1; if (!delAreaList.value.length) return message.error('暂无可删除区域');
delVisible.value = true; if (radioValue.value === 2 && !delCheckboxValue.value.length)
const param = ref<{ [key: string]: any }>({ return message.error('请选择需要删除的现货区域');
products: [ const param = ref<{ [key: string]: any }>({
{ products: [],
goodsNo: val.goodsNo, areas: '',
brand: val.brand, isAll: false,
spec: val.spec, });
ghscode: ghsCode, if (isBatchDel.value) {
}, param.value.products = selectedRows.value.map((v) => {
], return {
}); goodsNo: v.goodsNo,
console.log(param.value); brand: v.brand,
// delLoading.value = true spec: v.spec,
// const result = await getAreaList(param.value) ghscode: ghsCode,
// delAreaList.value = result };
// delLoading.value = false });
}; } else {
const delVisibleCancel = () => { param.value.products = [
delVisible.value = false; {
deleteNum.value = 0; goodsNo: curItem.value.goodsNo,
radioValue.value = 1; brand: curItem.value.brand,
delCheckboxValue.value = []; spec: curItem.value.spec,
isBatchDel.value = false; ghscode: ghsCode,
}; },
let delConfirLoading = ref(false); ];
const confirmDel = async () => { }
if (radioValue.value === 2 && !delCheckboxValue.value.length) if (radioValue.value === 1) {
return message.error('请选择需要删除的现货区域'); param.value.isAll = true;
const param = ref<{ [key: string]: any }>({ param.value.areas = delAreaList.value.map((v) => v.cityCode);
products: [], } else if (radioValue.value === 2) {
areas: '', param.value.areas = delCheckboxValue.value;
isAll: false, }
}); delConfirLoading.value = true;
if (isBatchDel.value) { const res = await regionalSpotManageOpsDeleteProductApi(param.value);
param.value.products = selectedRows.value.map((v) => { if (res.success) {
return { message.success('删除成功');
goodsNo: v.goodsNo, } else {
brand: v.brand, message.success(res.message);
spec: v.spec, }
ghscode: ghsCode, delConfirLoading.value = false;
}; };
}); // 批量删除
} else { const isBatchDel = ref(false);
param.value.products = [ const batchDel = async () => {
{ if (!selectedRowKeys.value.length) return message.error('请勾选商品');
goodsNo: curItem.value.goodsNo, isBatchDel.value = true;
brand: curItem.value.brand, deleteNum.value = selectedRows.value.length;
spec: curItem.value.spec, delVisible.value = true;
ghscode: ghsCode, const param = ref<{ [key: string]: any }>({
}, products: [],
]; });
} param.value.products = selectedRows.value.map((v) => {
if (radioValue.value === 1) { return {
param.value.isAll = true; goodsNo: v.goodsNo,
param.value.areas = delAreaList.value.map((v) => v.id); brand: v.brand,
} else if (radioValue.value === 2) { spec: v.spec,
param.value.areas = delCheckboxValue.value; ghscode: ghsCode,
} };
delConfirLoading.value = true; });
const res = await regionalSpotManageOpsDeleteProductApi(param.value); delLoading.value = true;
if (res.success) { const res = await getAreaList(param.value);
message.success('删除成功'); if (res.success) {
} else { delAreaList.value = res.data;
message.success(res.message); }
} delLoading.value = false;
delConfirLoading.value = false; };
}; // ================区域现货商品删除 end=====================
// 批量删除
let isBatchDel = ref(false); const allAreaList = ref<any[]>([]);
const batchDel = () => { const getAllAreaList = async () => {
if (!selectedRowKeys.value.length) return message.error('请勾选商品'); const res = await regionalSpotManageGetAreaListApi({});
isBatchDel.value = true; if (res.success) {
deleteNum.value = selectedRows.value.length; allAreaList.value = res.data;
delVisible.value = true; areaIdsOption.value = JSON.parse(JSON.stringify(res.data));
const param = ref<{ [key: string]: any }>({ } else {
products: [], allAreaList.value = [];
}); }
param.value.products = selectedRows.value.map((v) => { };
return { const getGroupOption = async () => {
goodsNo: v.goodsNo, const res = await regionalSpotManageGroupListApi({});
brand: v.brand, if (res.success) {
spec: v.spec, typesOption.value = res.data;
ghscode: ghsCode, } else {
}; typesOption.value = [];
}); }
// delLoading.value = true };
// const result = await getAreaList(param.value) // =====================批量导入 start=======================
// delAreaList.value = result const productExcelList = ref<any[]>([]);
// delLoading.value = false const importVisible = ref(false);
}; const impotrCheckboxValue = ref<any[]>([]);
// ================区域现货商品删除 end===================== const batchImport = () => {
importVisible.value = true;
let allAreaList = ref<any[]>([ allAreaList.value.forEach((v) => {
{ v.disabled = false;
id: '0', });
provinceId: '0', };
province: '北京市', const productExcelBeforeUpload = (file, fileList) => {
cityId: 0, const isLt8M = file.size / 1024 / 1024 <= 8;
city: '市辖区', const extension = file.name.substring(file.name.lastIndexOf('.') + 1);
creator: '', if (!isLt8M) {
creationTime: '', message.error('上传文件大小不能超过 8MB!');
disabled: true, return false;
}, }
{ if (extension !== 'xls' && extension !== 'xlsx') {
id: '1', message.error('只能上传excel的文件');
provinceId: '1', return false;
province: '河北省', }
cityId: 1, let curFileList = [...fileList];
city: '保定市', curFileList = curFileList.slice(-1);
creator: '', productExcelList.value = curFileList;
creationTime: '', return false;
}, };
{ const productExcelRemove = () => {
id: '2', productExcelList.value = [];
provinceId: '2', };
province: '河北省', const downLoad = () => {
cityId: 2, window.open(
city: '石家庄市', config.VITE_GLOB_TMALLAB_URL + '/system/resources/区域现货商品上传模板.xlsx',
creator: '', '_blank',
creationTime: '', );
}, };
{ let importLoading = ref(false);
id: '3', const confirmImport = async () => {
provinceId: '3', if (!productExcelList.value.length) return message.error('请上传文件');
province: '河北省', if (!impotrCheckboxValue.value.length) return message.error('请选择现货区域');
cityId: 3, // const param: FormData = new FormData();
city: '秦皇岛市', // param.append('ghsCode', ghsCode);
creator: '', // param.append('ghsName', ghsName);
creationTime: '', // param.append('file', productExcelList.value[0]);
}, // param.append('areaIds', impotrCheckboxValue.value.join(',') as any);
{ importLoading.value = true;
id: '4', const res: any = await regionalSpotManageUploadOpsProductApi(
provinceId: '4', {
province: '河北省', ghsCode: ghsCode,
cityId: 3, ghsName: ghsName,
city: '承德市', areaIds: impotrCheckboxValue.value,
creator: '', },
creationTime: '', productExcelList.value[0],
}, );
]); if (res.data.success) {
const getAllAreaList = async () => { message.success('批量导入成功');
const res = await regionalSpotManageGetAreaListApi({}); importCancel();
if (res.success) { } else {
allAreaList.value = res.data; message.error(res.data.message);
} else { }
allAreaList.value = []; importLoading.value = false;
} };
}; const importCancel = () => {
importVisible.value = false;
// =====================批量导入 start======================= impotrCheckboxValue.value = [];
let productExcelList = ref<any[]>([]); productExcelList.value = [];
let importVisible = ref(false); };
const impotrCheckboxValue = ref([]); // =====================批量导入 end=======================
const batchImport = () => { const goTaskCenter = () => {
importVisible.value = true; router.push({
allAreaList.value.forEach((v) => { path: '/product/taskCenter',
v.disabled = false; });
}); };
}; </script>
const productExcelBeforeUpload = (file, fileList) => {
const isLt8M = file.size / 1024 / 1024 <= 8; <template>
const extension = file.name.substring(file.name.lastIndexOf('.') + 1); <div>
if (!isLt8M) { <div class="body-box">
message.error('上传文件大小不能超过 8MB!'); <Form
return false; :model="searchForm"
} :label-col="{ span: 6 }"
if (extension !== 'xls' && extension !== 'xlsx') { :wrapper-col="{ span: 18 }"
message.error('只能上传excel的文件'); class="top-search"
return false; >
} <Row :gutter="20">
let curFileList = [...fileList]; <Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24">
curFileList = curFileList.slice(-1); <FormItem label="品牌名称" name="brandList">
productExcelList.value = curFileList; <!-- <Input v-model:value="searchForm.brands" allow-clear placeholder="请输入品牌名称" /> -->
return false; <a-select
}; v-model:value="searchForm.brands"
const productExcelRemove = () => { show-search
productExcelList.value = []; mode="multiple"
}; placeholder="请输入品牌名称"
const downLoad = () => { style="width: 100%"
window.open(config.VITE_GLOB_API_URL, '_blank'); :default-active-first-option="false"
}; :show-arrow="false"
let importLoading = ref(false); :filter-option="false"
const confirmImport = async () => { :not-found-content="null"
if (!productExcelList.value.length) return message.error('请上传文件'); :maxTagCount="1"
if (!impotrCheckboxValue.value.length) return message.error('请选择现货区域'); @search="handleSearch"
const param: FormData = new FormData(); >
param.append('ghsCode', ghsCode); <a-select-option
param.append('file', productExcelList.value[0]); v-for="item in searchBrandList"
param.append('areaIds', impotrCheckboxValue.value.join(',')); :key="item.brand"
importLoading.value = true; :label="item.brand"
const res = await regionalSpotManageUploadOpsProductApi(param); :value="item.brand"
if (res.code === 20000) { >
message.success('批量导入成功'); {{ item.brand }}
} else { </a-select-option>
message.error(res.message); </a-select>
} </FormItem>
importLoading.value = false; </Col>
}; <Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24">
const importCancel = () => { <FormItem label="货号" name="goodsNo">
importVisible.value = false; <Input v-model:value="searchForm.goodsNo" allow-clear placeholder="请输入货号" />
impotrCheckboxValue.value = []; </FormItem>
productExcelList.value = []; </Col>
}; <Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24">
// =====================批量导入 end======================= <FormItem label="现货区域" name="areaIds">
const goTaskCenter = () => { <Select
router.push({ v-model:value="searchForm.areaIds"
path: '/taskCenter', allowClear
}); mode="multiple"
}; placeholder="请选择现货区域"
</script> :maxTagCount="1"
style="width: 100%"
<template> >
<div> <SelectOption
<div class="body-box"> v-for="(item, index) in areaIdsOption"
<Form :key="index"
:model="searchForm" :value="item.cityId"
:label-col="{ span: 6 }" >{{ item.province }}-{{ item.city }}</SelectOption
:wrapper-col="{ span: 18 }" >
class="top-search" </Select>
> </FormItem>
<Row :gutter="20"> </Col>
<Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24"> <Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24">
<FormItem label="品牌名称" name="brandList"> <FormItem label="商品分组" name="types">
<!-- <Input v-model:value="searchForm.brandList" allow-clear placeholder="请输入品牌名称" /> --> <Select
<a-select v-model:value="searchForm.types"
v-model:value="searchForm.brandList" allowClear
show-search mode="multiple"
mode="multiple" placeholder="请选择商品分组"
placeholder="请输入品牌名称" :maxTagCount="1"
style="width: 100%" style="width: 100%"
:default-active-first-option="false" >
:show-arrow="false" <SelectOption v-for="(item, index) in typesOption" :key="index" :value="item">{{
:filter-option="false" item
:not-found-content="null" }}</SelectOption>
@search="handleSearch" </Select>
> </FormItem>
<a-select-option </Col>
v-for="item in searchBrandList" <Col :span="24" style="display: flex; justify-content: space-between">
:key="item.value" <div>
:label="item.label" <Button type="primary" style="margin: 0 5px" @click="onSearch">查询</Button>
:value="item.value" <Button style="margin: 0 5px" @click="onRset">重置</Button>
> <Button type="primary" @click="addProduct" style="margin: 0 5px">新增商品</Button>
{{ item.label }} <Button type="primary" @click="batchImport" style="margin: 0 5px">批量导入</Button>
</a-select-option> <Button type="primary" @click="batchDel" style="margin: 0 5px">批量删除</Button>
</a-select> </div>
</FormItem> <Button @click="goTaskCenter" style="margin: 0 5px">任务中心日志</Button>
</Col> </Col>
<Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24"> </Row>
<FormItem label="货号" name="goodsNo"> </Form>
<Input v-model:value="searchForm.goodsNo" allow-clear placeholder="请输入货号" /> <a-table
</FormItem> :data-source="list"
</Col> :loading="listLoading"
<Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24"> bordered
<FormItem label="现货区域" name="areaIds"> :pagination="pagination"
<Select :rowKey="(record) => record.brand + record.goodsNo + record.spec"
v-model:value="searchForm.areaIds" :row-selection="{
allowClear selectedRowKeys: selectedRowKeys,
mode="multiple" onChange: onSelectChange,
placeholder="请选择现货区域" columnWidth: 65,
style="width: 100%" }"
> style="margin-top: 15px"
<SelectOption >
v-for="(item, index) in areaIdsOption" <a-table-column title="商品名称" align="center" :width="100">
:key="index" <template #default="{ record }">
:value="item.value" {{ record.productName }}
>{{ item.label }}</SelectOption </template>
> </a-table-column>
</Select> <a-table-column title="品牌" align="center" :width="100">
</FormItem> <template #default="{ record }">
</Col> {{ record.brand }}
<Col :xxl="4" :xl="6" :lg="8" :sm="12" :xs="24"> </template>
<FormItem label="商品分组" name="types"> </a-table-column>
<Select <a-table-column title="货号" align="center" :width="100">
v-model:value="searchForm.types" <template #default="{ record }">
allowClear {{ record.goodsNo }}
mode="multiple" </template>
placeholder="请选择商品分组" </a-table-column>
style="width: 100%" <a-table-column title="规格" align="center" :width="100">
> <template #default="{ record }">
<SelectOption {{ record.spec }}
v-for="(item, index) in typesOption" </template>
:key="index" </a-table-column>
:value="item.value" <a-table-column title="当前现货区域" align="center" :width="100">
>{{ item.label }}</SelectOption <template #default="{ record }">
> <Button type="link" @click="viewCurrent(record)">查看区域现货</Button>
</Select> </template>
</FormItem> </a-table-column>
</Col> <a-table-column title="上架状态" align="center" :width="100">
<Col :span="24" style="display: flex; justify-content: space-between"> <template #default="{ record }">
<div> {{ record.productStatus }}
<Button type="primary" style="margin: 0 5px" @click="onSearch">查询</Button> </template>
<Button style="margin: 0 5px" @click="onRset">重置</Button> </a-table-column>
<Button type="primary" @click="addProduct" style="margin: 0 5px">新增商品</Button> <a-table-column title="操作" align="center" :width="200">
<Button type="primary" @click="batchImport" style="margin: 0 5px">批量导入</Button> <template #default="{ record }">
<Button type="primary" @click="batchDel" style="margin: 0 5px">批量删除</Button> <Button type="link" @click="addArea(record)">增加区域</Button>
</div> <Button type="link" style="margin-left: 5px" @click="del(record)">删除</Button>
<Button @click="goTaskCenter" style="margin: 0 5px">任务中心日志</Button> </template>
</Col> </a-table-column>
</Row> </a-table>
</Form> </div>
<a-table <addProductModal v-if="showModal" @close="closeVisible" />
:data-source="list" <a-modal
:loading="listLoading" v-model:visible="visible"
bordered title="商品可提供现货区域查看"
:pagination="pagination" :width="600"
:rowKey="(record) => record.sysid" @ok="visible = false"
:row-selection="{ :footer="null"
selectedRowKeys: selectedRowKeys, :maskClosable="false"
onChange: onSelectChange, okText="提交"
columnWidth: 65, >
}" <div>商品名称:{{ curItem.productName }}</div>
style="margin-top: 15px" <div>商品品牌:{{ curItem.brand }}</div>
> <div>商品货号:{{ curItem.goodsNo }}</div>
<a-table-column title="商品名称" align="center" :width="100"> <div>商品规格:{{ curItem.spec }}</div>
<template v-slot="{ record }"> <a-table
{{ record.productName }} :data-source="regionalSpotGoods"
</template> bordered
</a-table-column> :loading="loading1"
<a-table-column title="品牌" align="center" :width="100"> :pagination="false"
<template v-slot="{ record }"> :rowKey="(record) => record.sysid"
{{ record.brand }} style="margin-top: 15px"
</template> >
</a-table-column> <a-table-column title="区域" align="center" :width="100">
<a-table-column title="货号" align="center" :width="100"> <template #default="{ record }">{{ record.provinceName }}-{{ record.cityName }}</template>
<template v-slot="{ record }"> </a-table-column>
{{ record.goodsNo }} <a-table-column title="添加时间" align="center" :width="100">
</template> <template #default="{ record }">
</a-table-column> {{ record.createTime }}
<a-table-column title="规格" align="center" :width="100"> </template>
<template v-slot="{ record }"> </a-table-column>
{{ record.spec }} <a-table-column title="添加人" align="center" :width="100">
</template> <template #default="{ record }">
</a-table-column> {{ record.createName }}
<a-table-column title="当前现货区域" align="center" :width="100"> </template>
<template v-slot="{ record }"> </a-table-column>
<Button type="link" @click="viewCurrent(record)">查看区域现货</Button> </a-table>
</template> </a-modal>
</a-table-column> <!-- 删除 -->
<a-table-column title="上架状态" align="center" :width="100"> <a-modal
<template v-slot="{ record }"> v-model:visible="delVisible"
{{ record.productStatus }} title="区域现货商品删除"
</template> :width="650"
</a-table-column> :maskClosable="false"
<a-table-column title="操作" align="center" :width="200"> :keyboard="false"
<template #default="{ record }"> @cancel="delVisibleCancel"
<Button type="link" @click="addArea(record)">增加区域</Button> @ok="confirmDel"
<Button type="link" style="margin-left: 5px" @click="del(record)">删除</Button> :confirmLoading="delConfirLoading"
</template> okText="提交"
</a-table-column> >
</a-table> <p
</div> >您已选中 <span style="color: #1684fc">{{ deleteNum }}条</span> 商品</p
<addProductModal v-if="showModal" @close="closeVisible" /> >
<a-modal <a-spin v-if="delLoading" style="height: 150px; width: 100%; line-height: 150px" />
v-model:visible="visible" <p v-else
title="商品可提供现货区域查看" >选择需要删除的现货区域:
:width="600" <a-radio-group v-model:value="radioValue">
@ok="visible = false" <a-radio :value="1">全部区域</a-radio>
:footer="null" <a-radio :value="2">部分区域</a-radio>
:maskClosable="false" </a-radio-group>
okText="提交" <a-checkbox-group
> v-model:value="delCheckboxValue"
<div style="margin-top: -35px">商品名称:{{ curItem.productName }}</div> :disabled="radioValue === 1"
<div>商品品牌:{{ curItem.brand }}</div> style="width: 100%; margin-top: 15px"
<div>商品货号:{{ curItem.goodsNo }}</div> >
<div>商品规格:{{ curItem.spec }}</div> <a-row>
<a-table <a-col :span="6" v-for="(item, index) in delAreaList" :key="index">
:data-source="regionalSpotGoods" <a-checkbox :value="item.cityCode"
bordered >{{ item.provinceName }}-{{ item.cityName }}</a-checkbox
:loading="loading1" >
:pagination="false" </a-col>
:rowKey="(record) => record.sysid" </a-row>
style="margin-top: 15px" </a-checkbox-group>
> </p>
<a-table-column title="区域" align="center" :width="100"> </a-modal>
<template v-slot="{ record }"> {{ record.provinceName }}-{{ record.cityName }} </template> <!-- 增加区域 -->
</a-table-column> <a-modal
<a-table-column title="添加时间" align="center" :width="100"> v-model:visible="addVisible"
<template v-slot="{ record }"> title="现货商品增加区域"
{{ record.createTime }} :width="700"
</template> :maskClosable="false"
</a-table-column> @cancel="addVisibleCancel"
<a-table-column title="添加人" align="center" :width="100"> @ok="confirmAddArea"
<template v-slot="{ record }"> okText="提交"
{{ record.createName }} :confirmLoading="confirmAddLoading"
</template> >
</a-table-column> <div>商品名称:{{ curItem.productName }}</div>
</a-table> <div>商品品牌:{{ curItem.brand }}</div>
</a-modal> <div>商品货号:{{ curItem.goodsNo }}</div>
<!-- 删除 --> <div>商品规格:{{ curItem.spec }}</div>
<a-modal <p style="margin-top: 15px">选择可提供现货的区域:</p>
v-model:visible="delVisible" <a-checkbox-group v-model:value="addCheckboxValue" style="width: 100%">
title="区域现货商品删除" <a-row>
:width="650" <a-col :span="6" v-for="(item, index) in allAreaList" :key="index">
:maskClosable="false" <a-checkbox :value="item.cityId" :disabled="item.disabled"
:keyboard="false" >{{ item.province }}-{{ item.city }}</a-checkbox
@cancel="delVisibleCancel" >
@ok="confirmDel" </a-col>
:confirmLoading="delConfirLoading" </a-row>
okText="提交" </a-checkbox-group>
> </a-modal>
<p <!-- 批量导入 -->
>您已选中 <span style="color: #1684fc">{{ deleteNum }}条</span> 商品</p <a-modal
> v-model:visible="importVisible"
<a-spin v-if="delLoading" style="height: 150px; width: 100%; line-height: 150px" /> title="区域现货商品批量导入"
<p v-else :width="700"
>选择需要删除的现货区域: :maskClosable="false"
<a-radio-group v-model:value="radioValue"> okText="提交"
<a-radio :value="1">全部区域</a-radio> @ok="confirmImport"
<a-radio :value="2">部分区域</a-radio> @cancel="importCancel"
</a-radio-group> :confirmLoading="importLoading"
<a-checkbox-group >
v-model:value="delCheckboxValue" <a-alert type="warning">
:disabled="radioValue === 1" <template #message>
style="width: 100%; margin-top: 15px" <span style="color: red">特别提醒:</span
> >若商品之前已设置现货区域,则本次设置为在之前设置基础上新增。例如,原来商品设置为
<a-row> 北京市-直辖市;天津市-直辖市。本次设置为,北京市-直辖市;四川省-成都市。提交后,商品现货区域将更新为
<a-col :span="6" v-for="(item, index) in delAreaList" :key="index"> 北京市-直辖市;天津市-直辖市;四川省-成都市。
<a-checkbox :value="item.id">{{ item.province }}-{{ item.city }}</a-checkbox> </template>
</a-col> </a-alert>
</a-row> <div style="margin-top: 15px; display: flex; align-items: center">
</a-checkbox-group> <span>上传商品文件:</span>
</p> <a-upload
</a-modal> accept=".xls,.xlsx"
<!-- 增加区域 --> :file-list="productExcelList"
<a-modal :before-upload="productExcelBeforeUpload"
v-model:visible="addVisible" @remove="productExcelRemove"
title="现货商品增加区域" >
:width="700" <a-button><upload-outlined />上传文件</a-button>
:maskClosable="false" </a-upload>
@cancel="addVisibleCancel" <span style="margin-left: 15px">
@ok="confirmAddArea" 下载
okText="提交" <a @click="downLoad">区域现货商品上传模板</a>
:confirmLoading="confirmAddLoading" </span>
> </div>
<div style="margin-top: -35px">商品名称:{{ curItem.productName }}</div> <p style="margin-top: 15px">选择现货区域:</p>
<div>商品品牌:{{ curItem.brand }}</div> <a-checkbox-group v-model:value="impotrCheckboxValue" style="width: 100%">
<div>商品货号:{{ curItem.goodsNo }}</div> <a-row>
<div>商品规格:{{ curItem.spec }}</div> <a-col :span="6" v-for="(item, index) in allAreaList" :key="index">
<p style="margin-top: 15px">选择可提供现货的区域:</p> <a-checkbox :value="item.cityId" :disabled="item.disabled"
<a-checkbox-group v-model:value="addCheckboxValue" style="width: 100%"> >{{ item.province }}-{{ item.city }}</a-checkbox
<a-row> >
<a-col :span="6" v-for="(item, index) in allAreaList" :key="index"> </a-col>
<a-checkbox :value="item.id" :disabled="item.disabled" </a-row>
>{{ item.province }}-{{ item.city }}</a-checkbox </a-checkbox-group>
> </a-modal>
</a-col> </div>
</a-row> </template>
</a-checkbox-group>
</a-modal> <style lang="less" scoped>
<!-- 批量导入 --> .body-box {
<a-modal .top-search {
v-model:visible="importVisible" margin-top: 15px;
title="区域现货商品批量导入" }
:width="700" }
:maskClosable="false" </style>
okText="提交"
@ok="confirmImport"
@cancel="importCancel"
:confirmLoading="importLoading"
>
<a-alert type="warning">
<template #message>
<span style="color: red">特别提醒:</span
>若商品之前已设置现货区域,则本次设置为在之前设置基础上新增。例如,原来商品设置为
北京市-直辖市;天津市-直辖市。本次设置为,北京市-直辖市;四川省-成都市。提交后,商品现货区域将更新为
北京市-直辖市;天津市-直辖市;四川省-成都市。
</template>
</a-alert>
<div style="margin-top: 15px; display: flex; align-items: center">
<span>上传商品文件:</span>
<a-upload
accept=".xls,.xlsx"
:file-list="productExcelList"
:before-upload="productExcelBeforeUpload"
@remove="productExcelRemove"
>
<a-button><upload-outlined />上传文件</a-button>
</a-upload>
<span style="margin-left: 15px">
下载
<a @click="downLoad">区域现货商品上传模板</a>
</span>
</div>
<p style="margin-top: 15px">选择现货区域:</p>
<a-checkbox-group v-model:value="impotrCheckboxValue" style="width: 100%">
<a-row>
<a-col :span="6" v-for="(item, index) in allAreaList" :key="index">
<a-checkbox :value="item.id" :disabled="item.disabled"
>{{ item.province }}-{{ item.city }}</a-checkbox
>
</a-col>
</a-row>
</a-checkbox-group>
</a-modal>
</div>
</template>
<style lang="less" scoped>
.body-box {
.top-search {
margin-top: 15px;
}
}
</style>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { import {
platformProBatchGetListApi, platformProBatchGetListApi,
platformProBatchGetDetailApi platformProBatchGetDetailApi,
} from '/@/api/regionalSpotManage'; } from '/@/api/regionalSpotManage';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
onMounted(async () => { onMounted(async () => {
getList() getList();
}); });
let list = ref<any[]>([ let list = ref<any[]>([]);
{ let listLoading = ref(false);
createTime: '2024/12/12 12:22:22', const pagination = ref({
operateModule: '平台商品管理-议价商品', pageSize: 10,
type: '批量导入议价商品', current: 1,
operateNum: 8882, total: 0,
successNum: 8882, showTotal: (total) => `共 ${total} 条`,
failNum: 0, hideOnSinglePage: false,
operateName: '赵欣雨' showQuickJumper: true,
} showSizeChanger: true,
]) pageSizeOptions: ['10', '20', '30', '50', '100'],
let listLoading = ref(false) onChange: (current) => {
const pagination = ref({ pagination.value.current = current;
pageSize: 10, getList();
current: 1, },
total: 0, onShowSizeChange: (size) => {
showTotal: total => `共 ${total} 条`, pagination.value.pageSize = size;
hideOnSinglePage: false, getList();
showQuickJumper: true, },
showSizeChanger: true, });
pageSizeOptions: ['10', '20', '30', '50', '100'], const search = () => {
onChange: (current) => { pagination.value.current = 1;
pagination.value.current = current getList();
getList() };
}, const getList = async () => {
onShowSizeChange: (size) => { const param = ref<{ [key: string]: any }>({
pagination.value.pageSize = size currentPage: pagination.value.current,
getList() pageSize: pagination.value.pageSize,
} });
}) listLoading.value = true;
const search = () => { const res = await platformProBatchGetListApi(param.value);
pagination.value.current = 1 if (res.success) {
getList() list.value = res.data;
} pagination.value.total = res.data[0].total;
const getList = async () => { } else {
const param = ref<{ [key: string]: any }>({ list.value = [];
currentPage: pagination.value.current, pagination.value.total = 0;
pageSize: pagination.value.pageSize }
}) listLoading.value = false;
listLoading.value = true };
const res = await platformProBatchGetListApi(param) let curItem = ref<{ [key: string]: any }>({});
if (res.code === 20000) { let visible = ref(false);
list.value = res.data let operationList = ref<any[]>([]);
pagination.value.total = res.data[0].total let detailLoading = ref(false);
} else { const viewRecord = (item) => {
list.value = [] curItem.value = item;
pagination.value.total = 0 visible.value = true;
} getDetails(item);
listLoading.value = false };
} const getDetails = async (item) => {
let curItem = ref<{ [key: string]: any }>({}); const param = ref<{ [key: string]: any }>({
let visible = ref(false) currentPage: 1,
let operationList = ref<any[]>([]) pageSize: 10,
let detailLoading = ref(false) sysid: item.sysid,
const viewRecord = (item) => { type: '',
curItem.value = item });
visible.value = true detailLoading.value = true;
getDetails(item) const res = await platformProBatchGetDetailApi(param.value);
} if (res.success) {
const getDetails = async (item) => { operationList.value = res.data;
const param = ref<{ [key: string]: any }>({ } else {
sysid: item.sysid, operationList.value = [];
type: '' }
}) detailLoading.value = false;
detailLoading.value = true };
const res = await platformProBatchGetDetailApi(param)
if (res.code === 20000) { // =================导出========================
operationList.value = res.data let exportLoading = ref(false);
} else { const exportExcel = async () => {
operationList.value = [] const param = ref<{ [key: string]: any }>({
} sysid: curItem.value.sysid,
detailLoading.value = false type: '',
} });
exportLoading.value = true;
// =================导出======================== const res = await platformProBatchGetDetailApi(param.value);
let exportLoading = ref(false) if (res.success) {
const exportExcel = async () => { handleDownload(res.data);
handleDownload([ } else {
{ message.error('暂无数据');
"brand": "生工", }
"category": "", exportLoading.value = false;
"createTime": "2024-03-29 14:42:35", };
"discount": null, const handleDownload = (list) => {
"expirationDate": null, import('/@/vendor/Export2Excel').then((excel) => {
"failReason": "该商品在商品目录不存在;", let tHeader = [
"identificationType": "商品议价", '商品名称',
"itemNo": "G508013-0001", '品牌',
"negotiationPrice": 5000, '货号',
"operateSysid": 13877, '包装规格',
"platforms": [ '平台',
"北京协和医院" '状态',
], '失败原因',
"productName": "微孔板迷你离心机,500~3000 rpm", '执行时间',
"spec": "1 /PK", ];
"status": false, let filterVal = [
"sysid": 83466873, 'productName',
"total": 32, 'brand',
"type": 2 'itemNo',
} 'spec',
]) 'platforms',
const param = ref<{ [key: string]: any }>({ 'status',
sysid: curItem.value.sysid, 'failReason',
type: '' 'createTime',
}) ];
exportLoading.value = true list.forEach((item) => {
const res = await platformProBatchGetDetailApi(param) if (item.status) {
if (res.code === 20000) { item.status = '成功';
handleDownload(res.data) } else {
} else { item.status = '失败';
message.error('暂无数据') }
} if (item.platforms) {
exportLoading.value = false item.platforms = item.platforms.join(',');
} } else {
const handleDownload = (list) => { item.platforms = '';
import('/@/vendor/Export2Excel').then(excel => { }
let tHeader = ['商品名称', '品牌', '货号', '包装规格', '平台', '状态', '失败原因', '执行时间'] });
let filterVal = ['productName', 'brand', 'itemNo', 'spec', 'platforms', 'status', 'failReason', 'createTime'] const data = formatJson(filterVal, list);
list.forEach(item => { excel.export_json_to_excel({
if(item.status) { header: tHeader,
item.status = '成功' data: data,
} else { filename: '操作记录详情',
item.status = '失败' autoWidth: false,
} bookType: 'xlsx',
if(item.platforms) { XlsWidth: [],
item.platforms = item.platforms.join(',') searchList: null,
} else { });
item.platforms = '' });
} };
}); const formatJson = (filterVal, jsonData) => {
const data = formatJson(filterVal, list) return jsonData.map((v) =>
excel.export_json_to_excel({ filterVal.map((j) => {
header: tHeader as any, return v[j];
data: data as any, }),
filename: '操作记录详情' as any, );
autoWidth: true as any, };
bookType: 'xlsx' as any, </script>
XlsWidth: null as any,
searchList: [] as any <template>
}) <div>
}) <a-button @click="search" type="primary">刷新数据</a-button>
} </div>
const formatJson = (filterVal, jsonData) => { <a-table
return jsonData.map(v => filterVal.map(j => { :data-source="list"
return v[j] :loading="listLoading"
})) :pagination="pagination"
} bordered
</script> :rowKey="(record) => record.sysid"
style="margin-top: 15px"
<template> >
<div> <a-table-column title="操作时间" align="center" :width="100">
<a-button @click="search" type="primary">刷新数据</a-button> <template #default="{ record }">
</div> {{ record.createTime }}
<a-table </template>
:data-source="list" </a-table-column>
:loading="listLoading" <a-table-column title="功能模块" align="center" :width="100">
:pagination="pagination" <template #default="{ record }">
bordered {{ record.operateModule }}
:rowKey="(record) => record.sysid" </template>
style="margin-top: 15px" </a-table-column>
> <a-table-column title="类型" align="center" :width="100">
<a-table-column title="操作时间" align="center" :width="100"> <template #default="{ record }">
<template v-slot="{record}"> {{ record.type }}
{{ record.createTime }} </template>
</template> </a-table-column>
</a-table-column> <a-table-column title="操作数量" align="center" :width="100">
<a-table-column title="功能模块" align="center" :width="100"> <template #default="{ record }">
<template v-slot="{record}"> <a-button v-if="record.operateNum" type="link" @click="viewRecord(record)">{{
{{ record.operateModule }} record.operateNum
</template> }}</a-button>
</a-table-column> <span v-else>/</span>
<a-table-column title="类型" align="center" :width="100"> </template>
<template v-slot="{record}"> </a-table-column>
{{ record.type }} <a-table-column title="解析成功数量" align="center" :width="100">
</template> <template #default="{ record }">
</a-table-column> <span v-if="record.successNum">{{ record.successNum }}</span>
<a-table-column title="操作数量" align="center" :width="100"> <span v-else>/</span>
<template v-slot="{record}"> </template>
<a-button v-if="record.operateNum" type="link" @click="viewRecord(record)">{{ record.operateNum }}</a-button> </a-table-column>
<span v-else>/</span> <a-table-column title="解析失败数量" align="center" :width="100">
</template> <template #default="{ record }">
</a-table-column> <span v-if="record.failNum">{{ record.failNum }}</span>
<a-table-column title="解析成功数量" align="center" :width="100"> <span v-else>/</span>
<template v-slot="{record}"> </template>
<span v-if="record.successNum">{{ record.successNum }}</span> </a-table-column>
<span v-else>/</span> <a-table-column title="操作人" align="center" :width="100">
</template> <template #default="{ record }">
</a-table-column> {{ record.operateName }}
<a-table-column title="解析失败数量" align="center" :width="100"> </template>
<template v-slot="{record}"> </a-table-column>
<span v-if="record.failNum">{{ record.failNum }}</span> </a-table>
<span v-else>/</span> <a-modal
</template> v-model:visible="visible"
</a-table-column> title="操作记录详情"
<a-table-column title="操作人" align="center" :width="100"> :width="1200"
<template v-slot="{record}"> :maskClosable="false"
{{ record.operateName }} :keyboard="false"
</template> >
</a-table-column> <template #footer>
</a-table> <a-button type="primary" :loading="exportLoading" @click="exportExcel">导出数据</a-button>
<a-modal v-model:visible="visible" title="操作记录详情" :width="1200" :maskClosable="false" :keyboard="false"> </template>
<template #footer> <a-table
<a-button type="primary" :loading="exportLoading" @click="exportExcel">导出数据</a-button> :data-source="operationList"
</template> :loading="detailLoading"
<a-table bordered
:data-source="operationList" :rowKey="(record) => record.sysid"
:loading="detailLoading" >
bordered <a-table-column title="商品名称" align="center" :width="100">
:rowKey="(record) => record.sysid" <template #default="{ record }">
style="margin-top: -15px" {{ record.productName }}
> </template>
<a-table-column title="商品名称" align="center" :width="100"> </a-table-column>
<template v-slot="{record}"> <a-table-column title="品牌" align="center" :width="100">
{{ record.productName }} <template #default="{ record }">
</template> {{ record.brand }}
</a-table-column> </template>
<a-table-column title="品牌" align="center" :width="100"> </a-table-column>
<template v-slot="{record}"> <a-table-column title="货号" align="center" :width="100">
{{ record.brand }} <template #default="{ record }">
</template> {{ record.itemNo }}
</a-table-column> </template>
<a-table-column title="货号" align="center" :width="100"> </a-table-column>
<template v-slot="{record}"> <a-table-column title="包装规格" align="center" :width="100">
{{ record.itemNo }} <template #default="{ record }">
</template> {{ record.spec }}
</a-table-column> </template>
<a-table-column title="包装规格" align="center" :width="100"> </a-table-column>
<template v-slot="{record}"> <a-table-column title="平台" align="center" :width="150">
{{ record.spec }} <template #default="{ record }">
</template> <span
</a-table-column> v-if="record.platforms && record.platforms.length > 1"
<a-table-column title="平台" align="center" :width="150"> :title="record.platforms.join(',')"
<template v-slot="{record}"> >{{ record.platforms[0] + '...' }}</span
<span v-if="record.platforms && record.platforms.length > 1" :title="record.platforms.join(',')">{{ record.platforms[0] + '...' }}</span> >
<span v-else>{{ record.platforms ? record.platforms[0] : '' }}</span> <span v-else>{{ record.platforms ? record.platforms[0] : '' }}</span>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="状态" align="center" :width="100"> <a-table-column title="状态" align="center" :width="100">
<template v-slot="{record}"> <template #default="{ record }">
{{ record.status ? '成功' : '失败' }} {{ record.status ? '成功' : '失败' }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="失败原因" :width="150"> <a-table-column title="失败原因" :width="150">
<template v-slot="{record}"> <template #default="{ record }">
<span class="opinionClass" :title="record.failReason">{{ record.failReason }}</span> <span class="opinionClass" :title="record.failReason">{{ record.failReason }}</span>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="执行时间" align="center" :width="100"> <a-table-column title="执行时间" align="center" :width="100">
<template v-slot="{record}"> <template #default="{ record }">
{{ record.createTime }} {{ record.createTime }}
</template> </template>
</a-table-column> </a-table-column>
</a-table> </a-table>
</a-modal> </a-modal>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.opinionClass { .opinionClass {
word-break: break-all; word-break: break-all;
text-overflow: ellipsis; text-overflow: ellipsis;
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
} }
</style> </style>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
const config = import.meta.env; const config = import.meta.env;
import { import {
taskCenterQueryListApi, taskCenterQueryListApi,
taskCenterRevokeExcelUploadApi, taskCenterRevokeExcelUploadApi,
} from '/@/api/regionalSpotManage'; } from '/@/api/regionalSpotManage';
onMounted(async () => { onMounted(async () => {
getList(); getList();
}); });
let list = ref<any[]>([]); let list = ref<any[]>([]);
let listLoading = ref(false); let listLoading = ref(false);
const downLoad = (url) => { const downLoad = (url) => {
window.open(config.VITE_GLOB_API_URL + '/system/excelFile/' + url, '_blank'); window.open(config.VITE_GLOB_TMALLAB_URL + '/system/excelFile/' + url, '_blank');
}; };
const downloadFail = (record) => { const downloadFail = (record) => {
if (record.failNum === 0) return; if (record.failNum === 0) return;
let href = let href =
config.VITE_GLOB_API_URL + config.VITE_GLOB_TMALLAB_URL +
'/excel/excelNew/fail/download?sysid=' + '/excel/excelNew/fail/download?sysid=' +
record.sysid + record.sysid +
'&type=' + '&type=' +
record.type.slice(2, 6); record.type.slice(2, 6);
window.open(href, 'blank'); window.open(href, 'blank');
}; };
const cancel = async (record) => { const cancel = async (record) => {
const param = ref<{ [key: string]: any }>({ const param = ref<{ [key: string]: any }>({
sysid: record.sysid, sysid: record.sysid,
}); });
const res = await taskCenterRevokeExcelUploadApi(param.value); const res = await taskCenterRevokeExcelUploadApi(param.value);
if (res.code === 20000) { if (res.success) {
message.success('操作成功'); message.success('操作成功');
getList(); getList();
} else { } else {
message.error(res.message); message.error(res.message);
} }
}; };
const getList = async () => { const getList = async () => {
listLoading.value = true; listLoading.value = true;
const res = await taskCenterQueryListApi({ type: 0 }); const res = await taskCenterQueryListApi({ type: 0 });
if (res.code === 20000) { if (res.success) {
list.value = res.data; list.value = res.data;
} else { } else {
list.value = []; list.value = [];
} }
listLoading.value = false; listLoading.value = false;
}; };
</script> </script>
<template> <template>
<div> <div>
<a-button @click="getList" type="primary">刷新数据</a-button> <a-button @click="getList" type="primary">刷新数据</a-button>
</div> </div>
<a-table <a-table
:data-source="list" :data-source="list"
:loading="listLoading" :loading="listLoading"
bordered bordered
:rowKey="(record) => record.sysid" :rowKey="(record) => record.sysid"
style="margin-top: 15px" style="margin-top: 15px"
> >
<a-table-column title="操作时间" align="center" :width="100"> <a-table-column title="操作时间" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.createTime }} {{ record.createTime }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="类型" align="center" :width="100"> <a-table-column title="类型" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.type }} {{ record.type }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="状态" align="center" :width="100"> <a-table-column title="状态" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
<p>{{ <p>{{
record.isRevoke record.isRevoke
? '已撤销' ? '已撤销'
: record.status == 0 : record.status == 0
? '待进行' ? '待进行'
: record.status == 1 : record.status == 1
? '进行中' ? '进行中'
: '已完成' : '已完成'
}}</p> }}</p>
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="操作数据" align="center" :width="100"> <a-table-column title="操作数据" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.sproductNumpec }} {{ record.productNum }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="成功数据" align="center" :width="100"> <a-table-column title="成功数据" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.successNum }} {{ record.successNum }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="错误数据" align="center" :width="100"> <a-table-column title="错误数据" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.failNum }} {{ record.failNum }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="操作人" align="center" :width="100"> <a-table-column title="操作人" align="center" :width="100">
<template #default="{ record }"> <template #default="{ record }">
{{ record.createName }} {{ record.createName }}
</template> </template>
</a-table-column> </a-table-column>
<a-table-column title="操作" align="center" :width="200"> <a-table-column title="操作" align="center" :width="200">
<template #default="{ record }"> <template #default="{ record }">
<Button type="link" @click="downLoad(record.fileUrl)">下载源文件</Button> <a-button type="link" @click="downLoad(record.fileUrl)">下载源文件</a-button>
<Button type="link" v-if="record.failNum" @click="downloadFail(record)" <a-button type="link" v-if="record.failNum" @click="downloadFail(record)"
>下载错误数据</Button >下载错误数据</a-button
> >
<Button type="link" v-if="record.status == 0 && !record.isRevoke" @click="cancel(record)" <a-button type="link" v-if="record.status == 0 && !record.isRevoke" @click="cancel(record)"
>撤销</Button >撤销</a-button
> >
</template> </template>
</a-table-column> </a-table-column>
</a-table> </a-table>
</template> </template>
<style lang="less" scoped></style> <style lang="less" scoped></style>
<script lang="ts" setup> <script lang="ts" setup>
import ManageList from './components/list.vue'; import { ref, onMounted } from 'vue';
</script> import { regionalSpotManageGetStatusApi } from '/@/api/regionalSpotManage';
import ManageList from './components/list.vue';
<template> const show = ref(false);
<ManageList /> const loading = ref(false);
</template> onMounted(async () => {
loading.value = true;
<style lang="less" scoped> const res = await regionalSpotManageGetStatusApi().catch(() => (loading.value = false));
if (res.success) {
</style> show.value = true;
}
loading.value = false;
});
</script>
<template>
<div>
<!-- <ManageList /> -->
<a-spin v-if="loading" style="height: 150px; width: 100%; line-height: 150px" />
<ManageList v-if="show && !loading" />
<div v-if="!show && !loading" class="status">
<img src="../../assets/images/logo.png" alt="" srcset="" />
</div>
</div>
</template>
<style lang="less" scoped>
.status {
height: 100vh;
img {
width: 100%;
height: 100vh;
object-fit: contain;
}
}
</style>
...@@ -56,6 +56,7 @@ declare global { ...@@ -56,6 +56,7 @@ declare global {
interface ImportMeta { interface ImportMeta {
env: { env: {
VITE_GLOB_API_URL?: string; VITE_GLOB_API_URL?: string;
VITE_GLOB_TMALLAB_URL?: string;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment