huangxw 10 tháng trước cách đây
mục cha
commit
fd079205eb

+ 23 - 0
src/api/cdt/orders/index.ts

@@ -13,3 +13,26 @@ export const testOrderList = (query?: any): any => {
         params: query
     });
 };
+/**
+ * 查询订单状态统计
+ * @param query
+ * @returns {*}
+ */
+export const testOrderListCount = (query?: any): any => {
+    return request({
+        url: '/dgtmedicine/testOrder/statusCount',
+        method: 'get',
+        params: query
+    });
+};
+/**
+ * 获取检测订单详细信息
+ * @param query
+ * @returns {*}
+ */
+export const getTestOrderDetail = (orderId?: any): any => {
+    return request({
+        url: `/dgtmedicine/testOrder/getInfo/${orderId}`,
+        method: 'get'
+    });
+};

+ 4 - 0
src/assets/styles/element-ui.scss

@@ -160,3 +160,7 @@
      color: var(--el-color-primary);
   }
 }
+
+.small-btn-font.el-button--small {
+  font-size: 14px;
+}

+ 1 - 5
src/views/cdt/menus/detail/index.vue

@@ -33,7 +33,7 @@
                         </el-descriptions-item>
                         <el-descriptions-item label="产品图:">
                             <template v-for="(item, index) in form?.proImg.split(',')" :key="index">
-                                <el-image style="width: 100px; height: 100px" :src="item" fit="cover" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :initial-index="index" :preview-src-list="[item]"></el-image>
+                                <el-image style="width: 100px; height: 100px;margin-right: 12px;" :src="item" fit="cover" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :initial-index="index" :preview-src-list="[item]"></el-image>
                             </template>
                         </el-descriptions-item>
                     </el-descriptions>
@@ -70,7 +70,6 @@
 </template>
 
 <script setup name="Menus-detail" lang="ts">
-import { TransferItems } from '../../models';
 import NP from 'number-precision';
 import { colNoData } from '@/utils/noData';
 import { debounce } from 'lodash';
@@ -78,10 +77,7 @@ import { getTestPackage, getTestPackageItems } from '@/api/cdt/menus';
 const { query }: any = useRoute();
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { dm_package_type, dm_permit_type, vip_level } = toRefs<any>(proxy?.useDict('dm_package_type', 'dm_permit_type', 'vip_level'));
-// 字典
-const TransferItemsRef = ref<any>();
 const router = useRouter();
-const showSelectItems = ref(false);
 const form = ref<any>({
    items: [],
    priceDetail: [],

+ 2 - 0
src/views/cdt/models/index.ts

@@ -1,2 +1,4 @@
 export { default as TransferItems } from './transferItems.vue'; // 选择检测项目
 export { default as rowItems } from './rowItems.vue'; // 查看检测项目
+export { default as menuInfo } from './menuInfo.vue'; // 套餐信息
+export { default as orderInfo } from './orderInfo.vue'; // 订单信息

+ 91 - 0
src/views/cdt/models/menuInfo.vue

@@ -0,0 +1,91 @@
+<template>
+    <div>
+        <div class="info-title">套餐基本信息</div>
+        <el-descriptions :column="4">
+            <el-descriptions-item label="套餐名称:">{{ form?.name || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="套餐类型:">{{ selectDictLabel(dm_package_type, form?.publicFlag) || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="制定规则:">{{ selectDictLabel(dm_permit_type,form?.permitType ) }}</el-descriptions-item>
+            <el-descriptions-item v-if="form?.permitType === '1'" label="适用类型:">{{ selectDictLabels(vip_level, form?.permit, ',') || '-' }}</el-descriptions-item>
+            <el-descriptions-item v-if="form?.permitType === '2'" label="适用企业:">{{ form?.permitCpyNames.toString()|| '-' }}</el-descriptions-item>
+            <el-descriptions-item label="检测周期:">{{ form?.period || '-' }}天</el-descriptions-item>
+            <el-descriptions-item label="上架数量:">{{ form?.totalCount || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="执行标准:">{{ form?.standard || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="送样信息:" :span="2">{{ form?.description || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="购买须知:" :span="2">{{ form?.purchaseNotes || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="失效日期:">{{ form?.validUntil || '-' }}</el-descriptions-item>
+        </el-descriptions>
+        <el-divider />
+        <el-descriptions :column="4" direction="vertical">
+            <el-descriptions-item label="封面图:">
+                <el-image style="width: 100px; height: 100px" :src="form?.coverImg" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :preview-src-list="[form?.coverImg]" fit="cover"></el-image>
+            </el-descriptions-item>
+            <el-descriptions-item v-if="form?.proImg" label="产品图:">
+                <template v-for="(item, index) in form?.proImg.split(',')" :key="index">
+                    <el-image style="width: 100px; height: 100px;margin-right: 12px;" :src="item" fit="cover" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :initial-index="index" :preview-src-list="[item]"></el-image>
+                </template>
+            </el-descriptions-item>
+        </el-descriptions>
+        <el-divider />
+        <div class="info-title mb-16 d-flex">
+            <span>检测项目明细</span>
+            <span class="f-s-14">(共{{itemsInfo?.length}}项, 合计{{ totalCountPrice }}元)</span>
+        </div>
+        <vxe-table ref="tableRightRef" border :data="itemsInfo" :column-config="{ resizable: true }">
+            <vxe-column type="seq" width="60" title="序号" align="center" />
+            <vxe-column title="检测项目" align="center" field="name" min-width="100" :formatter="colNoData" />
+            <vxe-column title="单价(元、批次)" align="center" field="price" min-width="100" :formatter="colNoData" />
+            <vxe-column title="备注" align="center" field="description" min-width="100" :formatter="colNoData" />
+        </vxe-table>
+    </div>
+</template>
+<script setup lang="ts">
+import { propTypes } from '@/utils/propTypes';
+
+import NP from 'number-precision';
+import { colNoData } from '@/utils/noData';
+import { debounce } from 'lodash';
+import { getTestPackage, getTestPackageItems } from '@/api/cdt/menus';
+const props = defineProps({
+    info: propTypes.any.def({})
+});
+const { query }: any = useRoute();
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { dm_package_type, dm_permit_type, vip_level } = toRefs<any>(proxy?.useDict('dm_package_type', 'dm_permit_type', 'vip_level'));
+const router = useRouter();
+const form = ref<any>({
+   items: [],
+   priceDetail: [],
+   permitCpys: [],
+});
+const getDetail = async () => {
+    proxy?.$modal.loading('加载中...');
+    const res = await getTestPackage(props?.info?.packageId).finally(() => {
+        proxy?.$modal.closeLoading();
+    });
+    if (!res || res.code !== 200) return;
+    console.log(res);
+    form.value = {
+        ...res.data
+    };
+};
+const itemsInfo = ref<any>([]);
+const getItems = async () => {
+    const res = await getTestPackageItems({
+        pageNum: 1,
+        pageSize: 1000,
+        packageId: props?.info?.packageId
+    });
+    if (!res || res.code !== 200) return;
+    itemsInfo.value = res.rows;
+};
+// 合计价格
+const totalCountPrice = computed(() => {
+    return itemsInfo.value.reduce((total: number, item: any) => {
+        return NP.plus(total, item.price);
+    }, 0);
+});
+onMounted(() => {
+    getDetail()
+    getItems()
+});
+</script>

+ 71 - 0
src/views/cdt/models/orderInfo.vue

@@ -0,0 +1,71 @@
+<template>
+    <div>
+        <div class="info-title f-w-5 mb-15">订单信息</div>
+        <vxe-table ref="vxeTableRef" border :data="info?.testOrderDetailList" :merge-cells="mergeCells">
+            <vxe-column title="订单号" fixed="left" width="120">
+                <template #default>{{ info?.orderNo }}</template>
+            </vxe-column>
+            <vxe-column title="企业名称" min-width="100">
+                <template #default>
+                    <div>{{ info?.cpyName }}</div>
+                    <div class="c-999 f-s-12">{{ info?.creditCode }}</div>
+                </template>
+            </vxe-column>
+            <vxe-column title="会员级别" width="100">
+                <template #default>
+                    {{ info?.vipLevelName }}
+                </template>
+            </vxe-column>
+            <vxe-column title="套餐详情" min-width="100">
+                <template #default="{ row }">
+                    {{ row?.packageName }}
+                </template>
+            </vxe-column>
+            <vxe-column title="购买数量" width="90">
+                <template #default="{ row }">
+                    {{ row?.quantity }}
+                </template>
+            </vxe-column>
+            <vxe-column title="实收款" width="100">
+                <template #default="{ row }">{{ row?.amount }}元</template>
+            </vxe-column>
+            <vxe-column title="下单人" min-width="100">
+                <template #default>
+                    <div>{{ info?.createName }}</div>
+                </template>
+            </vxe-column>
+            <vxe-column title="下单时间" min-width="100">
+                <template #default>
+                    <div>{{ info?.createTime }}</div>
+                </template>
+            </vxe-column>
+            <vxe-column title="订单状态" width="100">
+                <template #default>
+                    <div>{{ selectDictLabel(test_order_status_bg, info?.status) }}</div>
+                </template>
+            </vxe-column>
+        </vxe-table>
+    </div>
+</template>
+<script setup lang="ts">
+import { propTypes } from '@/utils/propTypes';
+import { VxeTablePropTypes } from 'vxe-table';
+import { colNoData } from '@/utils/noData';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { test_order_status_bg } = toRefs<any>(proxy?.useDict('test_order_status_bg'));
+const vxeTableRef = ref<any>(null);
+const list = ref<any[]>([]);
+const props = defineProps({
+    info: propTypes.any.def({})
+});
+// 合并表格
+const mergeCells = ref<VxeTablePropTypes.MergeCells>([
+    { row: 0, col: 0, rowspan: 2, colspan: 0 },
+    { row: 0, col: 1, rowspan: 2, colspan: 0 },
+    { row: 0, col: 2, rowspan: 2, colspan: 0 },
+    { row: 0, col: 6, rowspan: 2, colspan: 0 },
+    { row: 0, col: 7, rowspan: 2, colspan: 0 },
+    { row: 0, col: 8, rowspan: 2, colspan: 0 }
+]);
+</script>
+<style lang="scss" scoped></style>

+ 43 - 0
src/views/cdt/orders/detail/index.vue

@@ -0,0 +1,43 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln">
+            <div class="d-flex a-c pd-16">
+                <div class="f-s-20 c-333 f-w-7 mr-10">订单详情</div>
+                <el-button @click="router.go(-1)" type="primary" text>
+                    <el-icon>
+                        <Back />
+                    </el-icon>
+                    返回上一级
+                </el-button>
+            </div>
+            <div v-if="orderItem" class="flex1 over-auto pl-16 pr-16 pb-16">
+                <el-tabs v-model="activeName" type="card" class="demo-tabs">
+                    <el-tab-pane label="订单信息" name="info">
+                        <orderInfo :info="orderItem"></orderInfo>
+                    </el-tab-pane>
+                    <el-tab-pane label="套餐信息" name="log">
+                        <menuInfo :info="orderItem?.testOrderDetailList[0]"></menuInfo>
+                    </el-tab-pane>
+                </el-tabs>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="Member-detail" lang="ts">
+import { getTestOrderDetail } from '@/api/cdt/orders';
+import { orderInfo, menuInfo } from '../../models';
+const { query }:any = useRoute()
+const router = useRouter();
+const activeName = ref('log');
+// 获取详细信息
+const orderItem = ref<any>(null);
+const getDetail = async () => {
+    const res = await getTestOrderDetail(query?.orderId);
+    if (!res || res.code !== 200) return;
+    orderItem.value = res.data;
+};
+onMounted(() => {
+    getDetail()
+});
+</script>

+ 69 - 21
src/views/cdt/orders/index.vue

@@ -3,7 +3,7 @@
         <div class="bg-fff flex1 ov-hd d-flex flex-cln">
             <div class="pd-16 border-bottom">
                 <div class="f-s-20 c-333 f-w-7 mb-12">订单管理</div>
-                <searchTabs v-model="queryParams.publicFlag" @change="handleQuery" :list="test_order_status" key-label="name" key-value="type" key-count="num"></searchTabs>
+                <searchTabs v-model="queryParams.status" @change="handleQuery" :list="tabs"></searchTabs>
             </div>
             <div class="flex1 ov-hd pd-16 d-flex flex-cln">
                 <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
@@ -12,19 +12,19 @@
                     </el-form-item>
                     <el-form-item label="下单时间段" prop="dateRange">
                         <div class="d-flex" style="width: 180px">
-                            <DateRange v-model="queryParams.dateRange" v-model:start-date="queryParams.startDate" v-model:end-date="queryParams.endDate"></DateRange>
+                            <DateRange v-model="queryParams.dateRange" v-model:start-date="queryParams.startDate" v-model:end-date="queryParams.endDate" @change="handleQuery"></DateRange>
                         </div>
                     </el-form-item>
-                    <el-form-item label="套餐名称:" prop="keyword">
-                        <el-input v-model="queryParams.keyword" placeholder="请输入套餐名称关键字" clearable style="width: 160px" @keyup.enter="handleQuery" />
+                    <el-form-item label="套餐名称:" prop="packageName">
+                        <el-input v-model="queryParams.packageName" placeholder="请输入套餐名称关键字" clearable style="width: 160px" @keyup.enter="handleQuery" />
                     </el-form-item>
-                    <el-form-item label="会员等级" prop="permitType">
-                        <el-select style="width: 160px" v-model="queryParams.permitType" clearable placeholder="请选择会员等级" @change="handleQuery">
+                    <el-form-item label="会员等级" prop="vipLevel">
+                        <el-select style="width: 160px" v-model="queryParams.vipLevel" clearable placeholder="请选择会员等级" @change="handleQuery">
                             <el-option v-for="item in vip_level" :key="item.value" :label="item.label" :value="item.value"></el-option>
                         </el-select>
                     </el-form-item>
-                    <el-form-item label="买家名称:" prop="createByName">
-                        <el-input v-model="queryParams.createByName" placeholder="搜买家名称及关键字" clearable style="width: 160px" @keyup.enter="handleQuery" />
+                    <el-form-item label="买家名称:" prop="cpyName">
+                        <el-input v-model="queryParams.cpyName" placeholder="搜买家名称及关键字" clearable style="width: 160px" @keyup.enter="handleQuery" />
                     </el-form-item>
                     <el-form-item>
                         <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -34,15 +34,42 @@
                 <div class="flex1 ov-hd">
                     <vxe-table :loading="loading" border :data="list" min-height="0" max-height="100%">
                         <!-- 序号 -->
-                        <vxe-column type="seq" width="60" title="序号" align="center" />
-                        <vxe-column title="订单号" field="orderNo" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="套餐名称" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="买家" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="会员等级" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="检测项目" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="检测周期" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="订单周期" field="packageName" min-width="100" :formatter="colNoData" />
-                        <vxe-column title="实付款" field="packageName" min-width="100" :formatter="colNoData" />
+                        <vxe-column type="seq" width="60" title="序号" fixed="left" align="center" />
+                        <vxe-column title="订单号" field="orderNo" fixed="left" min-width="100" :formatter="colNoData" />
+                        <vxe-column title="套餐名称" min-width="100">
+                            <template #default="{ row }">{{ row?.testOrderDetailList[0]?.packageName }}</template>
+                        </vxe-column>
+                        <vxe-column title="买家" field="cpyName" min-width="100" :formatter="colNoData" />
+                        <vxe-column title="会员等级" field="vipLevelName" min-width="100" :formatter="colNoData" />
+                        <vxe-column title="检测项目" min-width="200">
+                            <template #default="{ row }">
+                                <div>
+                                    {{ row?.testOrderDetailList[0]?.itemNames }}等{{ row?.testOrderDetailList[0]?.itemCount }}项
+                                    <el-button @click="queryRowItems(row?.testOrderDetailList[0])" type="primary" text>点击查看详情{{ '>' }}</el-button>
+                                </div>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="检测周期" width="90">
+                            <template #default="{ row }">{{ row?.testOrderDetailList[0]?.period }}个工作日</template>
+                        </vxe-column>
+                        <vxe-column title="实付款" width="90">
+                            <template #default="{ row }">{{ row?.totalAmount }}元</template>
+                        </vxe-column>
+                        <vxe-column title="下单人" field="createName" width="90" :formatter="colNoData" />
+                        <vxe-column title="下单时间" field="createTime" width="130" :formatter="colNoData" />
+                        <vxe-column title="订单状态" width="100" fixed="right">
+                            <template #default="{ row }">
+                                <div class="c-primary">{{ selectDictLabel(test_order_status_bg, row?.status) }}</div>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="订单备注" field="remark" min-width="100" fixed="right" :formatter="colNoData" />
+                        <vxe-column title="操作" width="180" fixed="right">
+                            <template #default="{ row }">
+                                <el-button text class="small-btn-font" type="primary" size="small">添加备注</el-button>
+                                <span></span>
+                                <el-button @click="router.push({ path: 'order-detail', query: { orderId: row?.id} })" text class="small-btn-font" type="primary" size="small">查看详情</el-button>
+                            </template>
+                        </vxe-column>
                     </vxe-table>
                 </div>
             </div>
@@ -50,31 +77,38 @@
             <div class="pd-5"></div>
         </div>
     </div>
+    <rowItems v-if="showRowItems" v-model:show="showRowItems" :packageId="rowId"></rowItems>
 </template>
 <script setup name="orders" lang="ts">
-import { testOrderList } from '@/api/cdt/orders';
+import { testOrderList, testOrderListCount } from '@/api/cdt/orders';
 import { colNoData } from '@/utils/noData';
 import { DateRange, searchTabs } from '@/views/models';
 import NP from 'number-precision';
+import { rowItems } from '../models';
+import { debounce } from 'lodash';
+import { selectDictLabel } from '@/utils/ruoyi';
+const router = useRouter();
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { dm_package_type, dm_permit_type, vip_level, test_order_status } = toRefs<any>(proxy?.useDict('dm_package_type', 'dm_permit_type', 'vip_level', 'test_order_status'));
+const { dm_package_type, dm_permit_type, vip_level, test_order_status_bg } = toRefs<any>(proxy?.useDict('dm_package_type', 'dm_permit_type', 'vip_level', 'test_order_status_bg'));
 const queryParams = ref<any>({
     pageNum: 1,
     pageSize: 10,
+    status: '2',
     dateRange: []
 });
 const queryFormRef = ref<any>();
+const showRowItems = ref(false);
 const loading = ref(false);
 const total = ref(0);
 const list = ref<any>([]);
-const getList = async () => {
+const getList = debounce(async () => {
     loading.value = true;
     const res = await testOrderList(queryParams.value);
     if (!res || res.code !== 200) return;
     list.value = res.rows;
     total.value = res.total;
     loading.value = false;
-};
+}, 500);
 const handleQuery = () => {
     queryParams.value.pageNum = 1;
     getList();
@@ -83,7 +117,21 @@ const resetQuery = () => {
     queryFormRef.value?.resetFields();
     handleQuery();
 };
+const rowId = ref('');
+const queryRowItems = (row: any) => {
+    rowId.value = row?.packageId;
+    showRowItems.value = true;
+};
+// 获取tabs统计数据
+const tabs = ref<any[]>([]);
+const getTabsCount = debounce(async () => {
+    const res = await testOrderListCount();
+    if (!res || res.code !== 200) return;
+    // this.tabsList = res.rows;
+    tabs.value = res.data.map(({ status, statusCount }: any) => ({ label: selectDictLabel(test_order_status_bg.value, status), value: status, count: statusCount }));
+}, 500);
 onMounted(() => {
     getList();
+    getTabsCount()
 });
 </script>