浏览代码

feat(product-manage):竞品监控添加创建、导入、导出功能
--其余文件添加useResponse方法

xinyan 10 月之前
父节点
当前提交
09bf3be513

+ 3 - 3
src/auto-imports.d.ts

@@ -74,12 +74,12 @@ declare global {
   const useId: typeof import('vue')['useId']
   const useLink: typeof import('vue-router')['useLink']
   const useModel: typeof import('vue')['useModel']
-  const usePagination: typeof import('../../../../../../../@/utils/usePagination')['usePagination']
-  const useResponse: typeof import('../../../../../../../@/utils/useResponse')['useResponse']
+  const usePagination: typeof import('../../../../../../@/utils/usePagination')['usePagination']
+  const useResponse: typeof import('../../../../../../@/utils/useResponse')['useResponse']
   const useRoute: typeof import('vue-router')['useRoute']
   const useRouter: typeof import('vue-router')['useRouter']
   const useSlots: typeof import('vue')['useSlots']
-  const useTableData: typeof import('../../../../../../../@/utils/useTableData')['useTableData']
+  const useTableData: typeof import('../../../../../../@/utils/useTableData')['useTableData']
   const useTemplateRef: typeof import('vue')['useTemplateRef']
   const watch: typeof import('vue')['watch']
   const watchEffect: typeof import('vue')['watchEffect']

+ 4 - 4
src/views/product-manage/competitor-monitor/api.ts

@@ -11,9 +11,9 @@ export function getTableData(query: any) {
   });
 }
 
-export function createProductMonitor(body: any) {
+export function createCompetitorMonitor(body: any) {
   return request({
-    url: '/api/choice/reviews_monitor/',
+    url: apiPrefix,
     method: 'POST',
     data: body
   });
@@ -71,7 +71,7 @@ export function batchDeleteRow(body: any) {
 // 导入
 export function upload(body: any){
   return request({
-    url: '/api/choice/reviews_monitor/import_data/',
+    url: apiPrefix +'import_data/',
     method: 'POST',
     data: body,
   });
@@ -80,7 +80,7 @@ export function upload(body: any){
 // 导出
 export function exportData(query: any) {
   return request({
-    url: '/api/choice/reviews_monitor/export_data/',
+    url: apiPrefix + 'export_data/',
     method: 'GET',
     params: query,
     responseType: 'blob'

+ 39 - 26
src/views/product-manage/competitor-monitor/component/DataTable.vue

@@ -9,13 +9,14 @@ import { Delete, Download, InfoFilled, Plus, Refresh, Upload } from '@element-pl
 import { ElMessage } from 'element-plus';
 import { usePagination } from '/@/utils/usePagination';
 import { useTableData } from '/@/utils/useTableData';
+import { useResponse } from '/@/utils/useResponse';
 import { CompetitorMonitorColumns } from '/@/views/product-manage/Columns';
 import DataTableSlot from './DataTableSlot.vue';
 import PermissionButton from '/src/components/PermissionButton/index.vue';
 import ImportButton from '/src/components/ImportButton/index.vue';
 import VerticalDivider from '/src/components/VerticalDivider/index.vue';
 import EditDrawer from './EditDrawer.vue';
-import CreateDialog from '/@/views/product-manage/product-monitor/component/createDialog.vue';
+import CreateDialog from '/@/views/product-manage/competitor-monitor/component/createDialog.vue';
 import * as api from '../api';
 
 
@@ -117,33 +118,26 @@ function handleRefresh() {
 }
 
 async function handleDownload() {
-  const confirmed = await ElMessageBox.confirm('是否确认导出当前时间内所有数据项?', '警告', {
-    confirmButtonText: '确定',
-    cancelButtonText: '取消',
-    type: 'warning'
-  });
-
-  if (confirmed) {
     gridOptions.loading = true;
     try {
       const query = {
-        country_code: queryParameter?.country,
-        goods__brand: queryParameter?.brand,
-        goods__tag: queryParameter?.group,
-        status: queryParameter?.status,
-        shop_id: queryParameter?.shop,
-        asin: queryParameter?.asin,
-        goods__sku: queryParameter?.sku,
-        platform_number: queryParameter?.platformId,
-        goods__all_ratings: queryParameter?.scoreNumber,
-        goods__all_reviews: queryParameter?.commentNumber,
-        goods__all_score: queryParameter?.displayScore
+				country_code: queryParameter?.country,
+				goods__brand: queryParameter?.brand,
+				goods__tag: queryParameter?.group,
+				status: queryParameter?.status,
+				shop_id: queryParameter?.shop,
+				asin: queryParameter?.asin,
+				goods__sku: queryParameter?.sku,
+				platform_number: queryParameter?.platformId,
+				goods__all_ratings: queryParameter?.scoreNumber,
+				goods__all_reviews: queryParameter?.commentNumber,
+				goods__all_score: queryParameter?.displayScore
       };
       const response = await api.exportData(query);
       const url = window.URL.createObjectURL(new Blob([ response.data ]));
       const link = document.createElement('a');
       link.href = url;
-      link.setAttribute('download', '品监控数据.xlsx');
+      link.setAttribute('download', '品监控数据.xlsx');
       document.body.appendChild(link);
       link.click();
       ElMessage.success('数据导出成功!');
@@ -153,7 +147,6 @@ async function handleDownload() {
     } finally {
       gridOptions.loading = false; // 结束加载状态
     }
-  }
 }
 
 async function batchDelete() {
@@ -271,11 +264,31 @@ defineExpose({ fetchList });
           <Refresh />
         </el-icon>
       </el-button>
-      <el-button circle class="mr-3 toolbar-btn" @click="handleDownload">
-        <el-icon>
-          <Download />
-        </el-icon>
-      </el-button>
+			<el-popconfirm
+				width="220"
+				:icon="InfoFilled"
+				icon-color="#626AEF"
+				title="是否确认导出当前时间内所有数据项?"
+				@confirm="handleDownload"
+			>
+				<template #reference>
+					<el-button circle class="mr-3 toolbar-btn">
+						<el-icon>
+							<Download />
+						</el-icon>
+					</el-button>
+				</template>
+				<template #actions="{ confirm, cancel }">
+					<el-button size="small" @click="cancel">No!</el-button>
+					<el-button
+						type="danger"
+						size="small"
+						@click="confirm"
+					>
+						Yes?
+					</el-button>
+				</template>
+			</el-popconfirm>
     </template>
     <template #top>
       <div class="mb-2"></div>

+ 1 - 0
src/views/product-manage/competitor-monitor/component/EditDrawer.vue

@@ -7,6 +7,7 @@
 
 import { ElMessage, FormInstance, FormRules } from 'element-plus';
 import { Close, Finished } from '@element-plus/icons-vue';
+import { useResponse } from '/@/utils/useResponse';
 import { DictionaryStore } from '/@/stores/dictionary';
 import * as api from '../api';
 

+ 158 - 0
src/views/product-manage/competitor-monitor/component/createDialog.vue

@@ -0,0 +1,158 @@
+<script lang="ts" setup>
+/**
+ * @Name: EditDrawer.vue
+ * @Description: 竞品监控-创建对话框
+ * @Author: xinyan
+ */
+
+import { ElMessage, FormInstance, FormRules } from 'element-plus';
+import { DictionaryStore } from '/@/stores/dictionary';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from '../api';
+
+const shopOptions = <Ref>inject('shopOptions');
+const groupOptions = <Ref>inject('groupOptions');
+const statusOptions = [{ label: '正常', value: 1 }];
+const { data: staticData } = DictionaryStore();
+
+const loading = ref(false);
+const createOpen = defineModel({ default: false });
+
+const emit = defineEmits(['refresh']);
+
+interface RuleForm {
+	asin: any;
+	sku: any;
+	country: any;
+	shop: any;
+	group: any;
+	status: any;
+	frequency: any;
+	description: any;
+}
+
+const ruleFormRef = ref<FormInstance>();
+const ruleForm = reactive<RuleForm>({
+	asin: '',
+	country: '',
+	shop: '',
+	group: '',
+	status: 1,
+	frequency: 6,
+	description: '',
+});
+
+const rules = reactive<FormRules<RuleForm>>({
+	asin: [{ required: true, message: '请输入ASIN', trigger: 'blur' }],
+	country: [{ required: true, message: '请选择国家', trigger: 'change' }],
+	shop: [{ required: true, message: '请输入店铺', trigger: 'blur' }],
+	group: [{ required: true, message: '请输入分组', trigger: 'blur' }],
+	// status: [{ message: '请选择状态', trigger: 'blur' }],
+	// frequency: [ { message: '请选择更新频率', trigger: 'blur' } ]
+});
+
+const submitForm = async (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	await formEl.validate(async (valid, fields) => {
+		if (valid) {
+			const body = {
+				asin: ruleForm.asin,
+				country_code: ruleForm.country,
+				shop_name: ruleForm.shop,
+				tag: ruleForm.group,
+				freq: ruleForm.frequency,
+				status: ruleForm.status,
+				// description: ruleForm.description,
+			};
+			const res = await useResponse(api.createCompetitorMonitor, body, loading);
+			if (res.code === 2000) {
+				ElMessage.success('创建成功');
+				createOpen.value = false;
+				emit('refresh');
+			}
+		} else {
+			// createOpen.value = false;
+			ElMessage.error('创建失败,请检查表单');
+		}
+	});
+};
+
+const resetForm = (formEl: FormInstance | undefined) => {
+	if (!formEl) return;
+	formEl.resetFields();
+};
+</script>
+
+<template>
+	<el-dialog v-model="createOpen" :close-on-click-modal="false" :close-on-press-escape="false" :title="`商品监控 - 创建 `" style="width: 40%">
+		<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" class="mx-2.5 mt-5" label-position="top" label-width="auto" status-icon>
+			<el-row :gutter="20">
+				<el-col :span="24">
+					<el-form-item class="font-medium" label="ASIN" prop="asin">
+						<el-input v-model="ruleForm.asin" placeholder="不再支持批量创建(批量创建使用Excel导入),请填写单个asin" />
+					</el-form-item>
+				</el-col>
+
+				<el-col :span="12">
+					<el-form-item class="font-medium" label="国 家" prop="country">
+						<el-select v-model="ruleForm.country" placeholder="请选择国家">
+							<el-option v-for="item in staticData.country_code" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+					</el-form-item>
+				</el-col>
+
+				<el-col :span="12">
+					<el-form-item class="font-medium" label="店 铺" prop="shop">
+						<!--<el-select v-model="ruleForm.shop" placeholder="请选择店铺">-->
+						<!--	<el-option v-for="item in shopOptions" :key="item.id" :label="item.name" :value="item.id" />-->
+						<!--</el-select>-->
+						<el-input v-model="ruleForm.shop" placeholder="请输入店铺" />
+					</el-form-item>
+				</el-col>
+
+				<el-col :span="12">
+					<el-form-item class="font-medium" label="分 组" prop="group">
+						<el-select v-model="ruleForm.group" placeholder="请选择分组">
+							<el-option v-for="item in groupOptions" :label="item.tag" :value="item.tag" />
+						</el-select>
+					</el-form-item>
+				</el-col>
+
+				<el-col :span="12">
+					<el-form-item class="font-medium" label="更新频率" prop="frequency">
+						<el-input-number v-model="ruleForm.frequency" min="3" />
+					</el-form-item>
+				</el-col>
+
+				<el-col :span="12">
+					<el-form-item class="font-medium" label="状态" prop="status">
+						<el-select v-model="ruleForm.status" disabled>
+							<el-option
+								v-for="item in statusOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							/>
+						</el-select>
+					</el-form-item>
+				</el-col>
+
+				<!--<el-col :span="12">-->
+				<!--	<el-form-item class="font-medium" label="备注" prop="description">-->
+				<!--		<el-input v-model="ruleForm.description" maxlength="200" placeholder="请输入备注信息" show-word-limit type="textarea" />-->
+				<!--	</el-form-item>-->
+				<!--</el-col>-->
+			</el-row>
+		</el-form>
+		<template #footer>
+			<el-button :loading="loading" type="primary" @click="submitForm(ruleFormRef)">确 定</el-button>
+			<el-button @click="resetForm(ruleFormRef)">重 置</el-button>
+		</template>
+	</el-dialog>
+</template>
+
+<style scoped>
+:deep(.el-drawer .el-drawer__header) {
+	border: none !important;
+}
+</style>

+ 1 - 0
src/views/product-manage/product-monitor/component/DataTable.vue

@@ -9,6 +9,7 @@ import { Delete, Download, InfoFilled, Plus, Refresh, Upload } from '@element-pl
 import { ElMessage } from 'element-plus';
 import { usePagination } from '/@/utils/usePagination';
 import { useTableData } from '/@/utils/useTableData';
+import { useResponse } from '/@/utils/useResponse';
 import { ProductMonitorColumns } from '/@/views/product-manage/Columns';
 import DataTableSlot from '/@/views/product-manage/product-monitor/component/DataTableSlot.vue';
 import PermissionButton from '/src/components/PermissionButton/index.vue';

+ 1 - 0
src/views/product-manage/product-monitor/component/EditDrawer.vue

@@ -8,6 +8,7 @@
 import { ElMessage, FormInstance, FormRules } from 'element-plus';
 import { Close, Finished } from '@element-plus/icons-vue';
 import { DictionaryStore } from '/@/stores/dictionary';
+import { useResponse } from '/@/utils/useResponse';
 import * as api from '../api';
 
 const { data: staticData } = DictionaryStore();

+ 10 - 9
src/views/product-manage/product-monitor/component/createDialog.vue

@@ -1,12 +1,13 @@
 <script lang="ts" setup>
 /**
  * @Name: EditDrawer.vue
- * @Description: 商品监控-行编辑
- * @Author: Cheney
+ * @Description: 商品监控-创建对话框
+ * @Author: xinyan
  */
 
 import { ElMessage, FormInstance, FormRules } from 'element-plus';
 import { DictionaryStore } from '/@/stores/dictionary';
+import { useResponse } from '/@/utils/useResponse';
 import * as api from '../api';
 
 const shopOptions = <Ref>inject('shopOptions');
@@ -66,7 +67,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
 					tag: ruleForm.group,
 				},
 				freq: ruleForm.frequency,
-				description: ruleForm.description,
+				// description: ruleForm.description,
 			};
 			const res = await useResponse(api.createProductMonitor, body, loading);
 			if (res.code === 2000){
@@ -75,7 +76,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
 				emit('refresh');
 			}
 		} else {
-			createOpen.value = false;
+			// createOpen.value = false;
 			ElMessage.error('创建失败,请检查表单');
 		}
 	});
@@ -133,11 +134,11 @@ const resetForm = (formEl: FormInstance | undefined) => {
 					</el-form-item>
 				</el-col>
 
-				<el-col :span="12">
-					<el-form-item class="font-medium" label="备注" prop="description">
-						<el-input v-model="ruleForm.description" type="textarea" placeholder="请输入备注信息" maxlength="200" show-word-limit />
-					</el-form-item>
-				</el-col>
+				<!--<el-col :span="12">-->
+				<!--	<el-form-item class="font-medium" label="备注" prop="description">-->
+				<!--		<el-input v-model="ruleForm.description" type="textarea" placeholder="请输入备注信息" maxlength="200" show-word-limit />-->
+				<!--	</el-form-item>-->
+				<!--</el-col>-->
 			</el-row>
 		</el-form>
 		<template #footer>