caiyuqin пре 11 месеци
родитељ
комит
c31e2b64c6
27 измењених фајлова са 6897 додато и 2983 уклоњено
  1. 2 0
      src/types/auto-imports.d.ts
  2. 246 95
      src/views/consoleManage/financeDataManage/costVerificationData/costVerificationDataDetail.vue
  3. 252 140
      src/views/consoleManage/financeDataManage/costVerificationData/index.vue
  4. 247 140
      src/views/consoleManage/financeDataManage/meetData/index.vue
  5. 240 97
      src/views/consoleManage/financeDataManage/meetData/meetDataDetail.vue
  6. 243 140
      src/views/consoleManage/financeDataManage/operatingProfitData/index.vue
  7. 255 140
      src/views/consoleManage/financeDataManage/personCheckData/index.vue
  8. 243 97
      src/views/consoleManage/financeDataManage/personCheckData/personCheckDataDetail.vue
  9. 247 140
      src/views/consoleManage/financeDataManage/receivableData/index.vue
  10. 263 98
      src/views/consoleManage/financeDataManage/receivableData/receivableDataDetail.vue
  11. 267 97
      src/views/consoleManage/personDataManage/channelPersonData/channelPersonDataDetail.vue
  12. 280 140
      src/views/consoleManage/personDataManage/channelPersonData/index.vue
  13. 255 140
      src/views/consoleManage/personDataManage/salesmanDept/index.vue
  14. 267 97
      src/views/consoleManage/personDataManage/salesmanDept/salesmanDeptDetail.vue
  15. 117 0
      src/views/consoleManage/personDataManage/salesmanDept/salesmanDeptDetailPerson.vue
  16. 280 140
      src/views/consoleManage/personDataManage/salesmanReport/index.vue
  17. 267 97
      src/views/consoleManage/personDataManage/salesmanReport/salesmanReportDetail.vue
  18. 280 140
      src/views/consoleManage/personDataManage/telemarketingPersonData/index.vue
  19. 267 97
      src/views/consoleManage/personDataManage/telemarketingPersonData/telemarketingPersonDataDetail.vue
  20. 270 97
      src/views/consoleManage/taskDataManage/channelData/channelDataDetail.vue
  21. 318 140
      src/views/consoleManage/taskDataManage/channelData/index.vue
  22. 303 97
      src/views/consoleManage/taskDataManage/companyData/companyDataDetail.vue
  23. 312 140
      src/views/consoleManage/taskDataManage/companyData/index.vue
  24. 318 140
      src/views/consoleManage/taskDataManage/salesmanData/index.vue
  25. 270 97
      src/views/consoleManage/taskDataManage/salesmanData/salesmanDataDetail.vue
  26. 318 140
      src/views/consoleManage/taskDataManage/telemarketingData/index.vue
  27. 270 97
      src/views/consoleManage/taskDataManage/telemarketingData/telemarketingDataDetail.vue

+ 2 - 0
src/types/auto-imports.d.ts

@@ -21,6 +21,8 @@ declare global {
   const dictLists: typeof import('../utils/composables/dictService')['dictLists']
   const dictionaryMatch: typeof import('../utils/composables/dictService')['dictionaryMatch']
   const download: typeof import('../utils/composables/fileProcessing')['download']
+  const downloadByData: typeof import('../utils/composables/download')['downloadByData']
+  const downloadByUrl: typeof import('../utils/composables/download')['downloadByUrl']
   const effectScope: typeof import('vue')['effectScope']
   const formatFileSize: typeof import('../utils/composables/fileProcessing')['formatFileSize']
   const getActivePinia: typeof import('pinia')['getActivePinia']

+ 246 - 95
src/views/consoleManage/financeDataManage/costVerificationData/costVerificationDataDetail.vue

@@ -1,117 +1,268 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "costVerDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "保险公司",
+      width: "300",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "审核类型",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "licenseNo",
+      label: "车牌号",
+      width: "300",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "提交审核时间",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "审核时间",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "状态",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "审核时长",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "审核人",
+      width: "180",
     }
-  })
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("costVerificationDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 252 - 140
src/views/consoleManage/financeDataManage/costVerificationData/index.vue

@@ -1,170 +1,282 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "costVerId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "保险公司",
+      width: "",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "待审核",
+      width: "240",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "已审核",
+      width: "240",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "sumPremium",
+      label: "自动审核",
+      width: "240",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "人工审核",
+      width: "240",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "平均审核时常",
+      width: "240",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("costVerificationData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/financeDataManage/costVerificationData/costVerificationDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "costVerificationDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 247 - 140
src/views/consoleManage/financeDataManage/meetData/index.vue

@@ -1,170 +1,277 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120"  @getList="getList" tableheight='auto' :showSummary='true'>
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 999,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "meetDataId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "时间",
+      width: "",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "应收",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumOrderNum",
+      label: "未开票",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumPremium",
+      label: "已开票",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "djPremium",
+      label: "已结算",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "未结算",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("meetData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/financeDataManage/meetData/meetDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "meetDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 240 - 97
src/views/consoleManage/financeDataManage/meetData/meetDataDetail.vue

@@ -1,117 +1,260 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "telemarketingDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "业务员",
+      width: "180",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "180",
+    },
+    {
+      prop: "orderNo",
+      label: "银行卡号",
+      width: "",
+    },
+    {
+      prop: "licenseNo",
+      label: "银行",
+      width: "180",
+    },
+    {
+      prop: "orderTypeName",
+      label: "状态",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "提现金额",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumPremium",
+      label: "付款人",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "付款时间",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("meetDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 243 - 140
src/views/consoleManage/financeDataManage/operatingProfitData/index.vue

@@ -1,170 +1,273 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120"  @getList="getList" tableheight='auto' :showSummary='true' :showOperation='false'>
+ 
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 999,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "meetDataId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "时间",
+      width: "",
+    },
+     {
+      prop: "sumOrderNum",
+      label: "保费",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumOrderNum",
+      label: "应收",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumOrderNum",
+      label: "应付",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumPremium",
+      label: "利润",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "djPremium",
+      label: "实收",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "实付",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("operatingProfitData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/systemManage/logManage/logDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 255 - 140
src/views/consoleManage/financeDataManage/personCheckData/index.vue

@@ -1,170 +1,285 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "personCheckId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "",
+    },
+    {
+      prop: "sumPremium",
+      label: "已审订单",
+      width: "180",
+    },
+    {
+      prop: "djPremium",
+      label: "待审订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "平均审核时常",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dszPremium",
+      label: "驳回订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jszPremium",
+      label: "修改订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("personCheckData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/financeDataManage/personCheckData/personCheckDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "personCheckDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 243 - 97
src/views/consoleManage/financeDataManage/personCheckData/personCheckDataDetail.vue

@@ -1,117 +1,263 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanReportDetId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "订单号",
+      width: "",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "orderNo",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "licenseNo",
+      label: "提交审核时间",
+      width: "180",
+    },
+    {
+      prop: "orderTypeName",
+      label: "审核时间",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "审核结果",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "审核时长",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "审核人",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "手机号",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanReportDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 247 - 140
src/views/consoleManage/financeDataManage/receivableData/index.vue

@@ -1,170 +1,277 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120"  @getList="getList" tableheight='auto' :showSummary='true'>
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 999,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "receivableId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "时间",
+      width: "",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "应收",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumOrderNum",
+      label: "未开票",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "sumPremium",
+      label: "已开票",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "djPremium",
+      label: "已结算",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "未结算",
+      width: "240",
+      align: "right",
+      sortable: true,
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("receivableData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/financeDataManage/receivableData/receivableDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "receivableDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 263 - 98
src/views/consoleManage/financeDataManage/receivableData/receivableDataDetail.vue

@@ -1,117 +1,282 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
-      </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <el-table :data="tableData" border style="width: 100%" :header-cell-style="tableHeaderColor">
+      <el-table-column prop="insuranceCompany" label="保险公司" align='center' width='200' fixed />
+      <el-table-column prop="region" label="地区" align='center' width='200' fixed>
+        <template #default="props">
+          <div style='{background:red}'>22{{props.row.region}}</div>
+        </template>
+      </el-table-column>
+      <el-table-column label="应收" align='center'>
+        <el-table-column prop="receivableTotal" label="总计" align='center' width='200' />
+        <el-table-column prop="receivableServiceFee" label="手续费" align='center' width='200' />
+        <el-table-column prop="receivableFollowFee" label="跟单费" align='center' width='200' />
+      </el-table-column>
+      <el-table-column label="未开票" align='center'>
+        <el-table-column prop="uninvoicedTotal" label="总计" align='center' width='200' />
+        <el-table-column prop="uninvoicedServiceFee" label="手续费" align='center' width='200' />
+        <el-table-column prop="uninvoicedFollowFee" label="跟单费" align='center' width='200' />
+      </el-table-column>
+      <el-table-column label="已开票" align='center'>
+        <el-table-column prop="uninvoicedTotal" label="总计" align='center' width='200' />
+        <el-table-column prop="uninvoicedServiceFee" label="手续费" align='center' width='200' />
+        <el-table-column prop="uninvoicedFollowFee" label="跟单费" align='center' width='200' />
+      </el-table-column>
+      <el-table-column label="未结算" align='center'>
+        <el-table-column prop="uninvoicedTotal" label="总计" align='center' width='200' />
+        <el-table-column prop="uninvoicedServiceFee" label="手续费" align='center' width='200' />
+        <el-table-column prop="uninvoicedFollowFee" label="跟单费" align='center' width='200' />
+      </el-table-column>
+      <el-table-column label="已结算" align='center'>
+        <el-table-column prop="uninvoicedTotal" label="总计" align='center' width='200' />
+        <el-table-column prop="uninvoicedServiceFee" label="手续费" align='center' width='200' />
+        <el-table-column prop="uninvoicedFollowFee" label="跟单费" align='center' width='200' />
+      </el-table-column>
+    </el-table>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "receivableDelId",
+  //查询
+  queryFormFields: [],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+let label = ["保险公司", "应收", "已开票", "已结算"];
+const tableHeaderColor = ({ row, column, rowIndex, columnIndex }) => {
+  if (!label.includes(column.label)) {
+    return {
+      backgroundColor: "#FFF",
+    };
+  }
+};
+
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("receivableDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([
+  {
+    insuranceCompany: "华泰财险",
+    region: "华泰财险",
+    receivableTotal: "32,799,333.89",
+    receivableServiceFee: "997,993.89",
+    receivableFollowFee: "329,333.89",
+    uninvoicedTotal: "329,333.89",
+    uninvoicedServiceFee: "329,333.89",
+    uninvoicedFollowFee: "329,333.89",
+  },
+  {
+    insuranceCompany: "华泰财险",
+    region: "华泰财险",
+    receivableTotal: "32,799,333.89",
+    receivableServiceFee: "327,333.89",
+    receivableFollowFee: "329,333.89",
+    uninvoicedTotal: "329,333.89",
+    uninvoicedServiceFee: "329,333.89",
+    uninvoicedFollowFee: "329,333.89",
+  },
+  {
+    insuranceCompany: "华泰财险",
+    region: "华泰财险",
+    receivableTotal: "32,799,333.89",
+    receivableServiceFee: "799,333.89",
+    receivableFollowFee: "329,333.89",
+    uninvoicedTotal: "329,333.89",
+    uninvoicedServiceFee: "329,333.89",
+    uninvoicedFollowFee: "329,333.89",
+  },
+]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  // tableData.value = data.records;
+  // pageInfo.value.pageNum = data.current;
+  // pageInfo.value.pageSize = data.size;
+  // pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 267 - 97
src/views/consoleManage/personDataManage/channelPersonData/channelPersonDataDetail.vue

@@ -1,117 +1,287 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "channelPersonDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "业务员",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "保险公司",
+      width: "120",
+    },
+    {
+      prop: "licenseNo",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("channelPersonDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 280 - 140
src/views/consoleManage/personDataManage/channelPersonData/index.vue

@@ -1,170 +1,310 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "channelPersonId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "所在地区",
+      width: "180",
+    },
+    {
+      prop: "djPremium",
+      label: "承保订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dszPremium",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jszPremium",
+      label: "单均保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次登录",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次签单",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "人员状态",
+      width: "180",
+    },
+     {
+      prop: "jsyPremium",
+      label: "账号状态",
+      width: "180",
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("channelPersonData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/personDataManage/channelPersonData/channelPersonDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "channelPersonDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 255 - 140
src/views/consoleManage/personDataManage/salesmanDept/index.vue

@@ -1,170 +1,285 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanDeptId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "类型",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "名称",
+      width: "200",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "",
+    },
+    {
+      prop: "sumPremium",
+      label: "所在地区",
+      width: "180",
+    },
+    {
+      prop: "djPremium",
+      label: "出单人力",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dszPremium",
+      label: "承保订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jszPremium",
+      label: "出单人数",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanDept");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/personDataManage/salesmanDept/salesmanDeptDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "salesmanDeptDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 267 - 97
src/views/consoleManage/personDataManage/salesmanDept/salesmanDeptDetail.vue

@@ -1,117 +1,287 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanDeptDetId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "业务员",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "保险公司",
+      width: "120",
+    },
+    {
+      prop: "licenseNo",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanDeptDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 117 - 0
src/views/consoleManage/personDataManage/salesmanDept/salesmanDeptDetailPerson.vue

@@ -0,0 +1,117 @@
+<template>
+  <div class="logDetail">
+    <el-descriptions :column="2">
+      <template #title>
+        <div class="title">
+          <div class="icon">
+            <el-icon><List /></el-icon>
+          </div>
+          <p>{{ detailData?.operationContent }}</p>
+        </div>
+      </template>
+      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
+      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
+      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
+      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
+    </el-descriptions>
+    <el-row :gutter="20" class="content">
+      <el-col :span="11">
+        <p>变更前</p>
+        <div class="list">
+          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
+            <el-col :span="6">{{ item.name }}</el-col>
+            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
+          </el-row>
+        </div>
+      </el-col>
+      <el-divider direction="vertical" style="height: 100%"></el-divider>
+      <el-col :span="11">
+        <p>变更后</p>
+        <div class="list">
+          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
+            <el-col :span="6">{{ item.name }}</el-col>
+            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
+          </el-row>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import api from '@/api'
+import { useRoute, useRouter } from 'vue-router'
+import { ElMessage } from "element-plus";
+
+const myRoute = useRoute()
+const myRouter = useRouter()
+
+let detailData = ref(undefined)
+
+const initDetail = () => {
+  api.logApi.selectById(myRoute.query.id).then((res: any) => {
+    if(res.code == 200) {
+      detailData.value = res.data
+    } else {
+      ElMessage({
+        message: res.msg,
+        type: 'warning'
+      })
+    }
+  })
+}
+
+onMounted(() => {
+  initDetail()
+})
+
+</script>
+
+<style scoped lang="scss">
+.logDetail{
+  padding: 24px;
+  background: #FFFFFF;
+  width: 100%;
+  height: calc(100vh - 120px);
+  .title{
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    .icon{
+      width: 30px;
+      height: 30px;
+      border-radius: 50%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: #1A85FA;
+      color: #FFFFFF;
+      font-size: 20px;
+      margin-right: 10px;
+    }
+  }
+  .content{
+    height: calc(100% - 120px);
+    overflow: hidden;
+    p{
+      text-align: center;
+      background: #F0F0F0;
+      margin: 0;
+      padding: 16px 0;
+    }
+    .list{
+      height: calc(100% - 80px);
+      overflow-y: auto;
+      overflow-x: hidden;
+      .list-item{
+        margin: 14px 0;
+        padding: 0 20px;
+        display: flex;
+      }
+    }
+  }
+  :deep(.el-descriptions) {
+    width: 50%;
+  }
+}
+</style>

+ 280 - 140
src/views/consoleManage/personDataManage/salesmanReport/index.vue

@@ -1,170 +1,310 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanReportId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "所在地区",
+      width: "180",
+    },
+    {
+      prop: "djPremium",
+      label: "承保订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dszPremium",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jszPremium",
+      label: "单均保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次登录",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次签单",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "人员状态",
+      width: "180",
+    },
+     {
+      prop: "jsyPremium",
+      label: "账号状态",
+      width: "180",
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanReport");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/personDataManage/salesmanReport/salesmanReportDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "salesmanReportDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 267 - 97
src/views/consoleManage/personDataManage/salesmanReport/salesmanReportDetail.vue

@@ -1,117 +1,287 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanReportDetId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "业务员",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "保险公司",
+      width: "120",
+    },
+    {
+      prop: "licenseNo",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanReportDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 280 - 140
src/views/consoleManage/personDataManage/telemarketingPersonData/index.vue

@@ -1,170 +1,310 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "telemarketingId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "所在地区",
+      width: "180",
+    },
+    {
+      prop: "djPremium",
+      label: "承保订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dsyPremium",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "dszPremium",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jszPremium",
+      label: "单均保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次登录",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "上次签单",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+    {
+      prop: "jsyPremium",
+      label: "人员状态",
+      width: "180",
+    },
+     {
+      prop: "jsyPremium",
+      label: "账号状态",
+      width: "180",
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("telemarketingPersonData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/personDataManage/telemarketingPersonData/telemarketingPersonDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "telemarketingPersonDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 267 - 97
src/views/consoleManage/personDataManage/telemarketingPersonData/telemarketingPersonDataDetail.vue

@@ -1,117 +1,287 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "telemarketingDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "业务员",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "保险公司",
+      width: "120",
+    },
+    {
+      prop: "licenseNo",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "出单佣金",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("telemarketingPersonDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 270 - 97
src/views/consoleManage/taskDataManage/channelData/channelDataDetail.vue

@@ -1,117 +1,290 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "channelDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "licenseNo",
+      label: "订单号",
+      width: "120",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "状态",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保险公司",
+      width: "180",
+    },
+     {
+      prop: "recordTime",
+      label: "合作保险公司",
+      width: "300",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("channelDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 318 - 140
src/views/consoleManage/taskDataManage/channelData/index.vue

@@ -1,170 +1,348 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
-
-}
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "channelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "报价订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "代客录单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "PC报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dszPremium",
+      label: "APP报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jszPremium",
+      label: "待缴费",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保失败",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保通过率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "承保率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录待审核",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录审核通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+  ],
 });
-let option = ref([])
-const timeChange = (val) => {
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/taskDataManage/channelData/channelDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("channelData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "channelDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 303 - 97
src/views/consoleManage/taskDataManage/companyData/companyDataDetail.vue

@@ -1,117 +1,323 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "companyDataDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "保险公司",
+      width: "180",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "报价订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "代客录单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "PC报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dszPremium",
+      label: "APP报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jszPremium",
+      label: "待缴费",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保不通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保通过率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "承保率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录待审核",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录审核通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("companyDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 312 - 140
src/views/consoleManage/taskDataManage/companyData/index.vue

@@ -1,170 +1,342 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "companyDataId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "保险公司",
+      width: "180",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "合作保险公司",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "报价订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "代客录单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "PC报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dszPremium",
+      label: "APP报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jszPremium",
+      label: "待缴费",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保不通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保通过率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "承保率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录待审核",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录审核通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+  ],
+});
 
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
-});
-let option = ref([])
-const timeChange = (val) => {
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("companyData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/taskDataManage/companyData/companyDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "companyDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 318 - 140
src/views/consoleManage/taskDataManage/salesmanData/index.vue

@@ -1,170 +1,348 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
-
-}
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "报价订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "代客录单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "PC报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dszPremium",
+      label: "APP报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jszPremium",
+      label: "待缴费",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保失败",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保通过率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "承保率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录待审核",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录审核通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+  ],
 });
-let option = ref([])
-const timeChange = (val) => {
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/taskDataManage/salesmanData/salesmanDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "salesmanDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 270 - 97
src/views/consoleManage/taskDataManage/salesmanData/salesmanDataDetail.vue

@@ -1,117 +1,290 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "salesmanDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "licenseNo",
+      label: "订单号",
+      width: "120",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "状态",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保险公司",
+      width: "180",
+    },
+     {
+      prop: "recordTime",
+      label: "合作保险公司",
+      width: "300",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("salesmanDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 318 - 140
src/views/consoleManage/taskDataManage/telemarketingData/index.vue

@@ -1,170 +1,348 @@
 <template>
   <div class="log">
-    <el-form label-width="100" label-position="left" :model="form">
-      <el-row :gutter="20">
-        <el-col :span="8">
-          <el-form-item label="操作人">
-            <el-input v-model="form.operator" placeholder="请输入操作人姓名查找"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作时间">
-            <el-date-picker
-              v-model="form.operatingTime"
-              type="daterange"
-              range-separator="至"
-              start-placeholder="开始时间"
-              end-placeholder="结束时间"
-              format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD"
-              @change="timeChange"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作功能">
-            <el-select v-model="form.function" placeholder="请选择">
-              <el-option label="工能1" value="1" key="1"></el-option>
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item label="操作内容">
-            <el-input v-model="form.content" placeholder="请输入"></el-input>
-          </el-form-item>
-        </el-col>
-        <el-col :span="16" style="display: flex; align-items: center; justify-content: flex-end">
-          <el-button type="primary" @click="search">查询</el-button>
-          <el-button plain type="primary" @click="reset">重置</el-button>
-        </el-col>
-      </el-row>
-    </el-form>
-    <el-table
-      :data="tableData"
-      height="600"
-      style="margin-top: 24px"
-    >
-      <el-table-column label="操作人" prop="createBy" width="200"></el-table-column  >
-      <el-table-column label="操作时间" prop="createTime" width="240"></el-table-column>
-      <el-table-column label="操作功能" prop="moduleName"></el-table-column>
-      <el-table-column label="操作内容" prop="operationContent"></el-table-column>
-      <el-table-column label="类型" prop="operatorName" width="150"></el-table-column>
-      <el-table-column label="操作" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="detail(scope.row)">查看详情</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <div class="pagination">
-      <el-pagination
-        v-model:current-page="pages"
-        v-model:page-size="size"
-        :page-sizes="[10, 20, 30, 40]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="total"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      ></el-pagination>
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
     </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList">
+      <template v-slot:operation="scope">
+        <el-button type="primary" link @click='agreementEdit(scope.operationData.id)'>明细</el-button>
+      </template>
+
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
+      </template>
+
+      <template #customSlot="{  bodyCell: { scope, column } }">
+        <template v-if="column.prop == 'sumOrderNum'">
+          {{ scope.row.sumOrderNum }} 笔
+        </template>
+      </template>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
-import api from '@/api'
-import {ElMessage} from "element-plus";
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
+import { ElMessage } from "element-plus";
 
-const myRouter = useRouter()
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
 
-let activeName = ref('first')
-const handleClick = () => {
-
-}
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "telemarketingId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "sumOrderNum",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "sumPremium",
+      label: "报价订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "djPremium",
+      label: "代客录单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dsyPremium",
+      label: "PC报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "dszPremium",
+      label: "APP报价中",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jszPremium",
+      label: "待缴费",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保失败",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "核保通过率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "承保率",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录订单",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录待审核",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
+    {
+      prop: "jsyPremium",
+      label: "补录审核通过",
+      width: "180",
+      align: "right",
+      sortable: true,
+      component: "customSlot",
+    },
 
-let form = ref({})
-const tableProps = ref({
-  value: "id",
-  label: "name",
-  children: "children",
-  checkStrictly: true,
+    {
+      prop: "jsyPremium",
+      label: "管理人",
+      width: "180",
+    },
+  ],
 });
-let option = ref([])
-const timeChange = (val) => {
 
-}
-// 搜索
-const search = () => {
-  pages.value = 1
-  size.value = 10
-  initData()
-}
-const reset = () => {
-  form.value = {}
-  pages.value = 1
-  size.value = 10
-  initData()
-}
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
 
-// 列表
-let tableData = ref([])
-const detail = (row) => {
-  myRouter.push({
-    path: '/consoleManage/taskDataManage/telemarketingData/telemarketingDataDetail',
-    query: {
-      id: row.id
-    }
-  })
-}
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
 
-// 分页
-let pages = ref(1)
-let size = ref(10)
-let total = ref(0)
-const handleSizeChange = (size) => {
-  size.value = size
-  initData()
-}
-const handleCurrentChange = (page) => {
-  pages.value = page
-  initData()
-}
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("telemarketingData");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
 
-const initData = () => {
-  api.logApi.list({
-    pages: pages.value,
-    size: size.value,
-    ...form.value
-  }).then((res: any) => {
-    if(res.code === 200) {
-      tableData.value = res.data.records
-      total.value = res.data.total
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManagePageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initData()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
+
+const agreementEdit = (id) => {
+  router.push({
+    name: "telemarketingDataDetail",
+    query: {
+      id: id,
+    },
+  });
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.log{
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  background: #FFFFFF;
+  background: #ffffff;
   padding: 24px;
   overflow-y: auto;
-  .pagination{
-    margin-top: 24px;
+  .query-btn {
+    margin-left: 20px;
+  }
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
     display: flex;
-    align-items: center;
     justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>

+ 270 - 97
src/views/consoleManage/taskDataManage/telemarketingData/telemarketingDataDetail.vue

@@ -1,117 +1,290 @@
 <template>
-  <div class="logDetail">
-    <el-descriptions :column="2">
-      <template #title>
-        <div class="title">
-          <div class="icon">
-            <el-icon><List /></el-icon>
-          </div>
-          <p>{{ detailData?.operationContent }}</p>
-        </div>
+  <div class="log">
+    <div class='btn-box'>
+      <el-button type="primary" plain class='query-btn'
+        @click='dialogShow'>{{selectedKeys.length?`已选${selectedKeys.length}项`:'筛选条件'}}</el-button>
+      <div class='query-btn'>
+        <DowButton @endAnim='downloadFile'></DowButton>
+      </div>
+    </div>
+    <QueryForm :option="listOption" @query='query' @delSelect='delSelect' ref='queryFormRef'></QueryForm>
+
+    <!-- 表格 -->
+    <ComplexTable :tableData="tableData" :showSelect='false' :columns="listOption.columns" :showIndex="false"
+      :columnwidth="120" :pageInfo="pageInfo" @getList="getList" :showOperation='false'>
+      <template v-slot:search="scope">
+        <Sort :scope="scope.slotData" :globalSortKey="globalSortKey" :globalSortOrder="globalSortOrder"
+          @update:sort="handleSortUpdate"></Sort>
       </template>
-      <el-descriptions-item label="操作功能:" label-align="right" align="left" label-width="100">{{ detailData?.moduleName }}</el-descriptions-item>
-      <el-descriptions-item label="操作类型:" label-align="right" align="left" label-width="100">{{ detailData?.operatorName }}</el-descriptions-item>
-      <el-descriptions-item label="操作人:" label-align="right" align="left" label-width="100">{{ detailData?.createBy }}</el-descriptions-item>
-      <el-descriptions-item label="操作时间:" label-align="right" align="left" label-width="100">{{ detailData?.createTime }}</el-descriptions-item>
-    </el-descriptions>
-    <el-row :gutter="20" class="content">
-      <el-col :span="11">
-        <p>变更前</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.fieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-      <el-divider direction="vertical" style="height: 100%"></el-divider>
-      <el-col :span="11">
-        <p>变更后</p>
-        <div class="list">
-          <el-row class="list-item" :gutter="20" v-for="item in detailData?.compareResultList" :key="item">
-            <el-col :span="6">{{ item.name }}</el-col>
-            <el-col :span="18" style="color: #606266">{{ item.newFieldContent }}</el-col>
-          </el-row>
-        </div>
-      </el-col>
-    </el-row>
+    </ComplexTable>
+
+    <FilterDialog :show='isShow' @close='isShow=false' @sure='filterSure' ref='filterDialogRef' @selectedKeys='selected'
+      routerKey='routerKey'>
+    </FilterDialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import api from '@/api'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from "vue-router";
+import api from "@/api";
+import QueryForm from "../../components/queryForm.vue";
+import FilterDialog from "../../components/filterDialog.vue";
+import DowButton from "../../components/button.vue";
+import Sort from "../../components/sort.vue";
+import useUserStore from "@/store/modules/message";
+import PageInfo from "@/api/types/agreementTypes";
 import { ElMessage } from "element-plus";
 
-const myRoute = useRoute()
-const myRouter = useRouter()
-
-let detailData = ref(undefined)
-
-const initDetail = () => {
-  api.logApi.selectById(myRoute.query.id).then((res: any) => {
-    if(res.code == 200) {
-      detailData.value = res.data
-    } else {
-      ElMessage({
-        message: res.msg,
-        type: 'warning'
-      })
-    }
-  })
+const router = useRouter();
+const userStore = useUserStore();
+const isShow = ref(false);
+
+const isSort = ref();
+const pageInfo = ref({
+  pageNum: 1,
+  pageSize: 10,
+  sizes: [10, 20, 30, 40, 50],
+  total: 0,
+});
+const listOption = reactive({
+  rowKey: "telemarketingDelId",
+  //查询
+  queryFormFields: [],
+  // 表格列
+  columns: [
+    {
+      prop: "companyName",
+      label: "姓名",
+      width: "100",
+    },
+    {
+      prop: "partnerCompanyName",
+      label: "手机号",
+      width: "120",
+    },
+    {
+      prop: "orderNo",
+      label: "所属机构",
+      width: "300",
+    },
+    {
+      prop: "licenseNo",
+      label: "订单号",
+      width: "120",
+    },
+    {
+      prop: "orderTypeName",
+      label: "订单号",
+      width: "180",
+    },
+    {
+      prop: "riskName",
+      label: "车牌号",
+      width: "180",
+    },
+    {
+      prop: "sumPremium",
+      label: "订单类型",
+      width: "180",
+    },
+    {
+      prop: "createTime",
+      label: "险种",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保费",
+      width: "180",
+      align: "right",
+      sortable: true,
+    },
+    {
+      prop: "recordTime",
+      label: "状态",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "录单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "签单时间",
+      width: "180",
+    },
+    {
+      prop: "recordTime",
+      label: "保险公司",
+      width: "180",
+    },
+     {
+      prop: "recordTime",
+      label: "合作保险公司",
+      width: "300",
+    },
+  ],
+});
+
+const selectedKeys = ref([]);
+const selected = function (val) {
+  selectedKeys.value = val;
+};
+
+//查询数据
+const phone = JSON.parse(localStorage.getItem("userInfo")).username;
+
+//获取默认选择数据
+const queryFormRes = ref();
+const routerKey = ref("telemarketingDataDetail");
+const defaultList = ref();
+const pageHiddenList = ref([]); //页面不显示的数据
+const initDefaultList = async () => {
+  const { data } = await api.manageApi.getSearchDefaultList({
+    routerKey: routerKey.value,
+    userId: phone,
+  });
+  listOption.queryFormFields = data.filter((e) => e.showFlag);
+
+  pageHiddenList.value = data.filter((e) => !e.showFlag);
+  defaultList.value = data.map((e) => e.id);
+  selectedKeys.value = defaultList.value;
+  queryFormRes.value = queryFormRef.value?.initDefaultSaveForm();
+  queryList();
+};
+
+//删除
+const filterDialogRef = ref();
+const delSelect = (id) => {
+  listOption.queryFormFields = listOption.queryFormFields.filter(
+    (item) => item.id != id
+  );
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//打开dialogShow
+const dialogShow = function () {
+  isShow.value = true;
+  filterDialogRef.value.initList(
+    [...listOption.queryFormFields, ...pageHiddenList.value],
+    defaultList.value
+  );
+};
+
+//确定
+const queryFormRef = ref();
+const filterSure = (item, index) => {
+  isShow.value = false;
+  const secondGroupIds = item.list.map((item) => item.id);
+  const oldList = listOption.queryFormFields.filter((item) =>
+    secondGroupIds.includes(item.id)
+  );
+  const firstGroupIds = listOption.queryFormFields.map((item) => item.id);
+  let newList = item.list.filter((item) => !firstGroupIds.includes(item.id));
+
+  //过滤掉默认不显示的数据
+  const hiddenList = new Set(pageHiddenList.value.map((item) => item.id));
+  const filterList = newList.filter((item) => !hiddenList.has(item.id));
+
+  listOption.queryFormFields = [...oldList, ...filterList];
+  queryFormRef.value?.initDefaultSaveForm();
+  selectedKeys.value = item.list.filter((item) => item.id);
+};
+
+const globalSortKey = ref("");
+const globalSortOrder = ref<"asc" | "desc">("asc");
+//  处理子组件传递的排序更新
+const handleSortUpdate = (sortInfo: {
+  key: string;
+  order: string;
+  name: string;
+}) => {
+  globalSortKey.value = sortInfo.key;
+  globalSortOrder.value = sortInfo.order;
+  queryList();
+};
+
+//查询
+const query = (item) => {
+  queryFormRes.value = item;
+  queryList();
+};
+
+//数据查询
+const tableData = ref([]);
+const queryList = async () => {
+  let query = { ...queryFormRes.value };
+  const { data } = await api.manageApi.companyDataManageDetailPageList({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  tableData.value = data.records;
+  pageInfo.value.pageNum = data.current;
+  pageInfo.value.pageSize = data.size;
+  pageInfo.value.total = data.total;
+};
+
+//分页事件
+function getList(item: PageInfo) {
+  pageInfo.value.pageNum = item.pageNum;
+  pageInfo.value.pageSize = item.pageSize;
+  queryList();
 }
 
-onMounted(() => {
-  initDetail()
-})
+//导出
+const downloadFile = async () => {
+  let query = { ...queryFormRes.value };
+  const { data, msg } = await api.manageApi.companyDataManageDetailToTask({
+    pageNo: pageInfo.value.pageNum,
+    pageSize: pageInfo.value.pageSize,
+    routerKey: routerKey.value,
+    userId: phone,
+    orderType: globalSortKey.value
+      ? globalSortKey.value + " " + globalSortOrder.value
+      : "",
+    ...query,
+  });
+  ElMessage({
+    message: msg,
+    type: "success",
+  });
+  userStore.count++;
+};
 
+onMounted(() => {
+  initDefaultList();
+});
 </script>
 
 <style scoped lang="scss">
-.logDetail{
-  padding: 24px;
-  background: #FFFFFF;
+.log {
   width: 100%;
   height: calc(100vh - 120px);
-  .title{
-    display: flex;
-    align-items: center;
-    justify-content: flex-start;
-    .icon{
-      width: 30px;
-      height: 30px;
-      border-radius: 50%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: #1A85FA;
-      color: #FFFFFF;
-      font-size: 20px;
-      margin-right: 10px;
-    }
-  }
-  .content{
-    height: calc(100% - 120px);
-    overflow: hidden;
-    p{
-      text-align: center;
-      background: #F0F0F0;
-      margin: 0;
-      padding: 16px 0;
-    }
-    .list{
-      height: calc(100% - 80px);
-      overflow-y: auto;
-      overflow-x: hidden;
-      .list-item{
-        margin: 14px 0;
-        padding: 0 20px;
-        display: flex;
-      }
-    }
+  background: #ffffff;
+  padding: 24px;
+  overflow-y: auto;
+  .query-btn {
+    margin-left: 20px;
   }
-  :deep(.el-descriptions) {
-    width: 50%;
+  .btn-box {
+    padding-bottom: 15px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #eeeeee;
+    display: flex;
+    justify-content: flex-end;
   }
 }
+:deep(.caret-wrapper) {
+  display: none !important;
+}
 </style>