新增:产品详情页面
							parent
							
								
									a5d6d18b6a
								
							
						
					
					
						commit
						4f89eb6ba9
					
				|  | @ -14,30 +14,35 @@ export interface ProductVO { | |||
| 
 | ||||
| // 查询产品列表
 | ||||
| export const getProductPage = async (params) => { | ||||
|   return await request.get({ url: `/crm/product/page`, params }) | ||||
|   return await request.get({url: `/crm/product/page`, params}) | ||||
| } | ||||
| 
 | ||||
| // 查询产品详情
 | ||||
| export const getProduct = async (id: number) => { | ||||
|   return await request.get({ url: `/crm/product/get?id=` + id }) | ||||
|   return await request.get({url: `/crm/product/get?id=` + id}) | ||||
| } | ||||
| 
 | ||||
| // 新增产品
 | ||||
| export const createProduct = async (data: ProductVO) => { | ||||
|   return await request.post({ url: `/crm/product/create`, data }) | ||||
|   return await request.post({url: `/crm/product/create`, data}) | ||||
| } | ||||
| 
 | ||||
| // 修改产品
 | ||||
| export const updateProduct = async (data: ProductVO) => { | ||||
|   return await request.put({ url: `/crm/product/update`, data }) | ||||
|   return await request.put({url: `/crm/product/update`, data}) | ||||
| } | ||||
| 
 | ||||
| // 删除产品
 | ||||
| export const deleteProduct = async (id: number) => { | ||||
|   return await request.delete({ url: `/crm/product/delete?id=` + id }) | ||||
|   return await request.delete({url: `/crm/product/delete?id=` + id}) | ||||
| } | ||||
| 
 | ||||
| // 导出产品 Excel
 | ||||
| export const exportProduct = async (params) => { | ||||
|   return await request.download({ url: `/crm/product/export-excel`, params }) | ||||
|   return await request.download({url: `/crm/product/export-excel`, params}) | ||||
| } | ||||
| 
 | ||||
| // 查询产品操作日志
 | ||||
| export const getOperateLogPage = async (params: any) => { | ||||
|   return await request.get({url: '/crm/product/operate-log-page', params}) | ||||
| } | ||||
|  |  | |||
|  | @ -517,6 +517,16 @@ const remainingRouter: AppRouteRecordRaw[] = [ | |||
|           hidden: true | ||||
|         }, | ||||
|         component: () => import('@/views/crm/contact/detail/index.vue') | ||||
|       }, | ||||
|       { | ||||
|         path: 'product/detail/:id', | ||||
|         name: 'CrmProductDetail', | ||||
|         meta: { | ||||
|           title: '产品详情', | ||||
|           noCache: true, | ||||
|           hidden: true | ||||
|         }, | ||||
|         component: () => import('@/views/crm/product/detail/index.vue') | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
|  |  | |||
|  | @ -1,71 +0,0 @@ | |||
| <template> | ||||
|   <Dialog v-model="dialogVisible" :max-height="500" :scroll="true" title="产品详情"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="产品名称"> | ||||
|         {{ detailData.name }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="创建时间"> | ||||
|         {{ formatDate(detailData.createTime) }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="状态"> | ||||
|         <dict-tag :type="DICT_TYPE.CRM_PRODUCT_STATUS" :value="detailData.status" /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="产品分类"> | ||||
|         {{ productCategoryList?.find((c) => c.id === detailData.categoryId)?.name }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="产品编码"> | ||||
|         {{ detailData.no }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="产品描述"> | ||||
|         {{ detailData.description }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="负责人"> | ||||
|         {{ detailData.ownerUserId }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="单位"> | ||||
|         <dict-tag :type="DICT_TYPE.PRODUCT_UNIT" :value="detailData.unit" /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="价格"> | ||||
|         {{ fenToYuan(detailData.price) }}元 | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| // TODO 芋艿:统一改成,独立 tab | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import * as ProductCategoryApi from '@/api/crm/product/productCategory' | ||||
| import * as ProductApi from '@/api/crm/product' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import { fenToYuan } from '@/utils' | ||||
| import { getSimpleUserList, UserVO } from '@/api/system/user' | ||||
| 
 | ||||
| defineOptions({ name: 'CrmProductDetail' }) | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| 
 | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
| const detailLoading = ref(false) // 表单的加载中 | ||||
| const detailData = ref() // 详情数据 | ||||
| 
 | ||||
| /** 打开弹窗 */ | ||||
| const open = async (data: ProductApi.ProductVO) => { | ||||
|   dialogVisible.value = true | ||||
|   // 设置数据 | ||||
|   detailLoading.value = true | ||||
|   try { | ||||
|     detailData.value = data | ||||
|   } finally { | ||||
|     detailLoading.value = false | ||||
|   } | ||||
| } | ||||
| defineExpose({ open }) // 提供 open 方法,用于打开弹窗 | ||||
| 
 | ||||
| const productCategoryList = ref([]) // 产品分类树 | ||||
| const userList = ref<UserVO[]>([]) // 系统用户 | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   productCategoryList.value = await ProductCategoryApi.getProductCategoryList({}) | ||||
|   userList.value = await getSimpleUserList() | ||||
| }) | ||||
| </script> | ||||
|  | @ -10,7 +10,7 @@ | |||
|       <el-row> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="产品名称" prop="name"> | ||||
|             <el-input v-model="formData.name" placeholder="请输入产品名称" /> | ||||
|             <el-input v-model="formData.name" placeholder="请输入产品名称"/> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|  | @ -57,7 +57,7 @@ | |||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="产品编码" prop="no"> | ||||
|             <el-input v-model="formData.no" placeholder="请输入产品编码" /> | ||||
|             <el-input v-model="formData.no" placeholder="请输入产品编码"/> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|  | @ -74,7 +74,7 @@ | |||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="产品描述" prop="description"> | ||||
|             <el-input v-model="formData.description" placeholder="请输入产品描述" /> | ||||
|             <el-input v-model="formData.description" placeholder="请输入产品描述"/> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"> | ||||
|  | @ -98,17 +98,17 @@ | |||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import {DICT_TYPE, getIntDictOptions} from '@/utils/dict' | ||||
| import * as ProductApi from '@/api/crm/product' | ||||
| import * as ProductCategoryApi from '@/api/crm/product/productCategory' | ||||
| import { defaultProps, handleTree } from '@/utils/tree' | ||||
| import { getSimpleUserList, UserVO } from '@/api/system/user' | ||||
| import { useUserStore } from '@/store/modules/user' | ||||
| import { fenToYuan, yuanToFen } from '@/utils' | ||||
| import {defaultProps, handleTree} from '@/utils/tree' | ||||
| import {getSimpleUserList, UserVO} from '@/api/system/user' | ||||
| import {useUserStore} from '@/store/modules/user' | ||||
| import {fenToYuan, yuanToFen} from '@/utils' | ||||
| 
 | ||||
| defineOptions({ name: 'CrmProductForm' }) | ||||
| defineOptions({name: 'CrmProductForm'}) | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const {t} = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
|  | @ -128,12 +128,12 @@ const formData = ref({ | |||
|   ownerUserId: -1 | ||||
| }) | ||||
| const formRules = reactive({ | ||||
|   name: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }], | ||||
|   no: [{ required: true, message: '产品编码不能为空', trigger: 'blur' }], | ||||
|   status: [{ required: true, message: '状态不能为空', trigger: 'change' }], | ||||
|   categoryId: [{ required: true, message: '产品分类ID不能为空', trigger: 'blur' }], | ||||
|   ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], | ||||
|   price: [{ required: true, message: '价格不能为空', trigger: 'blur' }] | ||||
|   name: [{required: true, message: '产品名称不能为空', trigger: 'blur'}], | ||||
|   no: [{required: true, message: '产品编码不能为空', trigger: 'blur'}], | ||||
|   status: [{required: true, message: '状态不能为空', trigger: 'change'}], | ||||
|   categoryId: [{required: true, message: '产品分类ID不能为空', trigger: 'blur'}], | ||||
|   ownerUserId: [{required: true, message: '负责人不能为空', trigger: 'blur'}], | ||||
|   price: [{required: true, message: '价格不能为空', trigger: 'blur'}] | ||||
| }) | ||||
| 
 | ||||
| const formRef = ref() // 表单 Ref | ||||
|  | @ -149,7 +149,7 @@ const open = async (type: string, id?: number) => { | |||
|     formLoading.value = true | ||||
|     try { | ||||
|       formData.value = await ProductApi.getProduct(id) | ||||
|       formData.value.price = fenToYuan(formData.value.price) | ||||
|       formData.value.price = Number(fenToYuan(formData.value.price)) | ||||
|     } finally { | ||||
|       formLoading.value = false | ||||
|     } | ||||
|  | @ -157,7 +157,7 @@ const open = async (type: string, id?: number) => { | |||
|     formData.value.ownerUserId = userId | ||||
|   } | ||||
| } | ||||
| defineExpose({ open }) // 提供 open 方法,用于打开弹窗 | ||||
| defineExpose({open}) // 提供 open 方法,用于打开弹窗 | ||||
| 
 | ||||
| /** 提交表单 */ | ||||
| const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 | ||||
|  |  | |||
|  | @ -0,0 +1,56 @@ | |||
| <template> | ||||
|   <div> | ||||
|     <div class="flex items-start justify-between"> | ||||
|       <div> | ||||
|         <el-col> | ||||
|           <el-row> | ||||
|             <span class="text-xl font-bold">{{ product.name }}</span> | ||||
|           </el-row> | ||||
|         </el-col> | ||||
|       </div> | ||||
|       <div> | ||||
|         <!-- 右上:按钮 --> | ||||
|         <el-button @click="openForm('update', product.id)" v-hasPermi="['crm:product:update']"> | ||||
|           编辑 | ||||
|         </el-button> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <ContentWrap class="mt-10px"> | ||||
|     <el-descriptions :column="5" direction="vertical"> | ||||
|       <el-descriptions-item label="产品类别"> | ||||
|         {{ productCategoryList?.find((c) => c.id === product.categoryId)?.name }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="产品单位"> | ||||
|         <dict-tag :type="DICT_TYPE.PRODUCT_UNIT" :value="product.unit"/> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="产品价格">{{ fenToYuan(product.price) }}元</el-descriptions-item> | ||||
|       <el-descriptions-item label="产品编码">{{ product.no }}</el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|   </ContentWrap> | ||||
|   <!-- 表单弹窗:添加/修改 --> | ||||
|   <ProductForm ref="formRef" @success="emit('refresh')"/> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import ProductForm from '@/views/crm/product/ProductForm.vue' | ||||
| import {DICT_TYPE} from "@/utils/dict"; | ||||
| import {fenToYuan} from "@/utils"; | ||||
| import * as ProductApi from "@/api/crm/product"; | ||||
| import * as ProductCategoryApi from '@/api/crm/product/productCategory' | ||||
| 
 | ||||
| 
 | ||||
| //操作修改 | ||||
| const formRef = ref() | ||||
| const openForm = (type: string, id?: number) => { | ||||
|   formRef.value.open(type, id) | ||||
| } | ||||
| const {product} = defineProps<{ product: ProductApi.ProductVO }>() | ||||
| const emit = defineEmits(['refresh']) // 定义 success 事件,用于操作成功后的回调 | ||||
| 
 | ||||
| /** 初始化 */ | ||||
| const productCategoryList = ref([]) // 产品分类树 | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   productCategoryList.value = await ProductCategoryApi.getProductCategoryList({}) | ||||
| }) | ||||
| </script> | ||||
|  | @ -0,0 +1,45 @@ | |||
| <template> | ||||
|   <ContentWrap> | ||||
|     <el-collapse v-model="activeNames"> | ||||
|       <el-collapse-item name="basicInfo"> | ||||
|         <template #title> | ||||
|           <span class="text-base font-bold">基本信息</span> | ||||
|         </template> | ||||
|         <el-descriptions :column="4"> | ||||
|           <el-descriptions-item label="产品名称">{{ product.name }}</el-descriptions-item> | ||||
|           <el-descriptions-item label="产品编码">{{ product.no }}</el-descriptions-item> | ||||
|           <el-descriptions-item label="价格">{{ fenToYuan(product.price) }}元</el-descriptions-item> | ||||
|           <el-descriptions-item label="产品描述">{{ product.description }}</el-descriptions-item> | ||||
|           <el-descriptions-item label="产品类型"> | ||||
|             {{ productCategoryList?.find((c) => c.id === product.categoryId)?.name }} | ||||
|           </el-descriptions-item> | ||||
|           <el-descriptions-item label="是否上下架"> | ||||
|             <dict-tag :type="DICT_TYPE.CRM_PRODUCT_STATUS" :value="product.status"/> | ||||
|           </el-descriptions-item> | ||||
|           <el-descriptions-item label="单位"> | ||||
|             <dict-tag :type="DICT_TYPE.PRODUCT_UNIT" :value="product.unit"/> | ||||
|           </el-descriptions-item> | ||||
|         </el-descriptions> | ||||
|       </el-collapse-item> | ||||
|     </el-collapse> | ||||
|   </ContentWrap> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import {DICT_TYPE} from '@/utils/dict' | ||||
| import * as ProductApi from '@/api/crm/product' | ||||
| import {fenToYuan} from '@/utils' | ||||
| import * as ProductCategoryApi from '@/api/crm/product/productCategory' | ||||
| 
 | ||||
| const {product} = defineProps<{ | ||||
|   product: ProductApi.ProductVO | ||||
| }>() | ||||
| 
 | ||||
| // 展示的折叠面板 | ||||
| const activeNames = ref(['basicInfo']) | ||||
| 
 | ||||
| /** 初始化 */ | ||||
| const productCategoryList = ref([]) // 产品分类树 | ||||
| onMounted(async () => { | ||||
|   productCategoryList.value = await ProductCategoryApi.getProductCategoryList({}) | ||||
| }) | ||||
| </script> | ||||
|  | @ -0,0 +1,64 @@ | |||
| <template> | ||||
|   <ProductDetailsHeader :product="product" :loading="loading" @refresh="getProductData(id)"/> | ||||
|   <el-col> | ||||
|     <el-tabs> | ||||
|       <el-tab-pane label="详细资料"> | ||||
|         <ProductDetailsInfo :product="product"/> | ||||
|       </el-tab-pane> | ||||
|       <el-tab-pane label="操作日志"> | ||||
|         <OperateLogV2 :log-list="logList"/> | ||||
|       </el-tab-pane> | ||||
|     </el-tabs> | ||||
|   </el-col> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import {useTagsViewStore} from '@/store/modules/tagsView' | ||||
| import {OperateLogV2VO} from '@/api/system/operatelog' | ||||
| import * as ProductApi from '@/api/crm/product' | ||||
| import ProductDetailsHeader from '@/views/crm/product/detail/ProductDetailsHeader.vue' | ||||
| import ProductDetailsInfo from '@/views/crm/product/detail/ProductDetailsInfo.vue' | ||||
| 
 | ||||
| defineOptions({name: 'CrmProductDetail'}) | ||||
| 
 | ||||
| const route = useRoute() | ||||
| const id = Number(route.params.id) // 编号 | ||||
| const loading = ref(true) // 加载中 | ||||
| const product = ref<ProductApi.ProductVO>({} as ProductApi.ProductVO) // 详情 | ||||
| 
 | ||||
| /** 获取详情 */ | ||||
| const getProductData = async (id: number) => { | ||||
|   loading.value = true | ||||
|   try { | ||||
|     product.value = await ProductApi.getProduct(id) | ||||
|     await getOperateLog(id) | ||||
|   } finally { | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 获取操作日志 | ||||
|  */ | ||||
| const logList = ref<OperateLogV2VO[]>([]) // 操作日志列表 | ||||
| const getOperateLog = async (productId: number) => { | ||||
|   if (!productId) { | ||||
|     return | ||||
|   } | ||||
|   const data = await ProductApi.getOperateLogPage({ | ||||
|     bizId: productId | ||||
|   }) | ||||
|   logList.value = data.list | ||||
| } | ||||
| 
 | ||||
| /** 初始化 */ | ||||
| const {delView} = useTagsViewStore() // 视图操作 | ||||
| const {currentRoute} = useRouter() // 路由 | ||||
| onMounted(async () => { | ||||
|   if (!id) { | ||||
|     ElMessage.warning('参数错误,产品不能为空!') | ||||
|     delView(unref(currentRoute)) | ||||
|     return | ||||
|   } | ||||
|   await getProductData(id) | ||||
| }) | ||||
| </script> | ||||
|  | @ -28,10 +28,17 @@ | |||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> | ||||
|         <el-button @click="handleQuery"> | ||||
|           <Icon icon="ep:search" class="mr-5px"/> | ||||
|           搜索 | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon icon="ep:refresh" class="mr-5px"/> | ||||
|           重置 | ||||
|         </el-button> | ||||
|         <el-button type="primary" @click="openForm('create')" v-hasPermi="['crm:product:create']"> | ||||
|           <Icon icon="ep:plus" class="mr-5px" /> 新增 | ||||
|           <Icon icon="ep:plus" class="mr-5px"/> | ||||
|           新增 | ||||
|         </el-button> | ||||
|         <el-button | ||||
|           type="success" | ||||
|  | @ -40,7 +47,8 @@ | |||
|           :loading="exportLoading" | ||||
|           v-hasPermi="['crm:product:export']" | ||||
|         > | ||||
|           <Icon icon="ep:download" class="mr-5px" /> 导出 | ||||
|           <Icon icon="ep:download" class="mr-5px"/> | ||||
|           导出 | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|  | @ -49,27 +57,33 @@ | |||
|   <!-- 列表 --> | ||||
|   <ContentWrap> | ||||
|     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"> | ||||
|       <el-table-column label="产品名称" align="center" prop="name" /> | ||||
|       <el-table-column label="产品类型" align="center" prop="categoryName" /> | ||||
|       <el-table-column label="产品单位" align="center" prop="unit"> | ||||
|       <el-table-column label="产品名称" align="center" prop="name" width="160"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.PRODUCT_UNIT" :value="scope.row.unit" /> | ||||
|           <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)"> | ||||
|             {{ scope.row.name }} | ||||
|           </el-link> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="产品编码" align="center" prop="no" /> | ||||
|       <el-table-column label="产品类型" align="center" prop="categoryName" width="160"/> | ||||
|       <el-table-column label="产品单位" align="center" prop="unit"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.PRODUCT_UNIT" :value="scope.row.unit"/> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="产品编码" align="center" prop="no"/> | ||||
|       <el-table-column | ||||
|         label="价格(元)" | ||||
|         align="center" | ||||
|         prop="price" | ||||
|         :formatter="fenToYuanFormat" | ||||
|       /> | ||||
|       <el-table-column label="产品描述" align="center" prop="description" /> | ||||
|       <el-table-column label="产品描述" align="center" prop="description"/> | ||||
|       <el-table-column label="是否上下架" align="center" prop="status"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.CRM_PRODUCT_STATUS" :value="scope.row.status" /> | ||||
|           <dict-tag :type="DICT_TYPE.CRM_PRODUCT_STATUS" :value="scope.row.status"/> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="负责人" align="center" prop="ownerUserName" /> | ||||
|       <el-table-column label="负责人" align="center" prop="ownerUserName"/> | ||||
|       <el-table-column | ||||
|         label="更新时间" | ||||
|         align="center" | ||||
|  | @ -77,7 +91,7 @@ | |||
|         :formatter="dateFormatter" | ||||
|         width="180px" | ||||
|       /> | ||||
|       <el-table-column label="创建" align="center" prop="creatorName" /> | ||||
|       <el-table-column label="创建" align="center" prop="creatorName"/> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         align="center" | ||||
|  | @ -85,16 +99,8 @@ | |||
|         :formatter="dateFormatter" | ||||
|         width="180px" | ||||
|       /> | ||||
|       <el-table-column label="操作" align="center" width="160"> | ||||
|       <el-table-column label="操作" align="center" fixed="right" width="160"> | ||||
|         <template #default="scope"> | ||||
|           <el-button | ||||
|             v-hasPermi="['crm:product:query']" | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="openDetail(scope.row)" | ||||
|           > | ||||
|             详情 | ||||
|           </el-button> | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|  | @ -124,24 +130,21 @@ | |||
|   </ContentWrap> | ||||
| 
 | ||||
|   <!-- 表单弹窗:添加/修改 --> | ||||
|   <ProductForm ref="formRef" @success="getList" /> | ||||
|   <!-- 表单弹窗:详情 --> | ||||
|   <ProductDetail ref="detailRef" @success="getList" /> | ||||
|   <ProductForm ref="formRef" @success="getList"/> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { dateFormatter } from '@/utils/formatTime' | ||||
| import {DICT_TYPE, getIntDictOptions} from '@/utils/dict' | ||||
| import {dateFormatter} from '@/utils/formatTime' | ||||
| import download from '@/utils/download' | ||||
| import * as ProductApi from '@/api/crm/product' | ||||
| import ProductForm from './ProductForm.vue' | ||||
| import ProductDetail from './ProductDetail.vue' | ||||
| import { fenToYuanFormat } from '@/utils/formatter' | ||||
| import {fenToYuanFormat} from '@/utils/formatter' | ||||
| 
 | ||||
| defineOptions({ name: 'CrmProduct' }) | ||||
| defineOptions({name: 'CrmProduct'}) | ||||
| 
 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const {t} = useI18n() // 国际化 | ||||
| 
 | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(0) // 列表的总页数 | ||||
|  | @ -184,10 +187,11 @@ const formRef = ref() | |||
| const openForm = (type: string, id?: number) => { | ||||
|   formRef.value.open(type, id) | ||||
| } | ||||
| /** 详情操作 */ | ||||
| const detailRef = ref() | ||||
| const openDetail = (data: ProductApi.ProductVO) => { | ||||
|   detailRef.value.open(data) | ||||
| 
 | ||||
| /** 打开详情 */ | ||||
| const {currentRoute, push} = useRouter() | ||||
| const openDetail = (id: number) => { | ||||
|   push({name: 'CrmProductDetail', params: {id}}) | ||||
| } | ||||
| 
 | ||||
| /** 删除按钮操作 */ | ||||
|  | @ -200,7 +204,8 @@ const handleDelete = async (id: number) => { | |||
|     message.success(t('common.delSuccess')) | ||||
|     // 刷新列表 | ||||
|     await getList() | ||||
|   } catch {} | ||||
|   } catch { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** 导出按钮操作 */ | ||||
|  | @ -218,6 +223,14 @@ const handleExport = async () => { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| /** 监听路由变化更新列表 */ | ||||
| watch( | ||||
|   () => currentRoute.value, | ||||
|   () => { | ||||
|     getList() | ||||
|   } | ||||
| ) | ||||
| 
 | ||||
| /** 初始化 **/ | ||||
| onMounted(async () => { | ||||
|   await getList() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 anhaohao
						anhaohao