zhangafei 3 сар өмнө
parent
commit
2c6bff0de1
26 өөрчлөгдсөн 1560 нэмэгдсэн , 1045 устгасан
  1. 1 1
      .env
  2. 2 2
      .env.development
  3. 0 14
      src/App.vue
  4. 15 15
      src/hooks/system/useJvxeMethods.ts
  5. 20 0
      src/views/equipmentLifecycle/components/YOrN.vue
  6. 16 1
      src/views/equipmentLifecycle/device/list/DeviceBaseInfo.data.ts
  7. 3 4
      src/views/equipmentLifecycle/device/list/DeviceBaseInfoList.vue
  8. 12 7
      src/views/equipmentLifecycle/device/list/components/deviceDetail.vue/baseInfo.vue
  9. 14 15
      src/views/equipmentLifecycle/supplier/apply/PurchaseApplication.api.ts
  10. 145 121
      src/views/equipmentLifecycle/supplier/apply/PurchaseApplication.data.ts
  11. 42 36
      src/views/equipmentLifecycle/supplier/apply/components/PurchaseApplicationForm.vue
  12. 121 88
      src/views/equipmentLifecycle/supplier/apply/components/PurchaseApplicationModal.vue
  13. 25 193
      src/views/equipmentLifecycle/supplier/apply/index.vue
  14. 217 0
      src/views/equipmentLifecycle/supplier/apply/list.vue
  15. 19 15
      src/views/equipmentLifecycle/supplier/list/SupplierManage.api.ts
  16. 20 8
      src/views/equipmentLifecycle/supplier/list/SupplierManage.data.ts
  17. 101 0
      src/views/equipmentLifecycle/supplier/list/components/DetailDrawer.vue
  18. 5 2
      src/views/equipmentLifecycle/supplier/list/components/SupplierManageModal.vue
  19. 12 7
      src/views/equipmentLifecycle/supplier/list/index.vue
  20. 24 15
      src/views/equipmentLifecycle/supplier/plan/PurchasePlan.api.ts
  21. 257 220
      src/views/equipmentLifecycle/supplier/plan/PurchasePlan.data.ts
  22. 0 192
      src/views/equipmentLifecycle/supplier/plan/PurchasePlanList.vue
  23. 126 0
      src/views/equipmentLifecycle/supplier/plan/components/DetailDrawer.vue
  24. 128 89
      src/views/equipmentLifecycle/supplier/plan/components/PurchasePlanModal.vue
  25. 34 0
      src/views/equipmentLifecycle/supplier/plan/index.vue
  26. 201 0
      src/views/equipmentLifecycle/supplier/plan/list.vue

+ 1 - 1
.env

@@ -1,5 +1,5 @@
 # port
-VITE_PORT = 3100
+VITE_PORT = 3103
 
 #  网站标题
 VITE_GLOB_APP_TITLE = 中工智通设备生命周期管理平台

+ 2 - 2
.env.development

@@ -6,10 +6,10 @@ VITE_PUBLIC_PATH = /
 
 
 # 跨域代理,您可以配置多个 ,请注意,没有换行符
-VITE_PROXY = [["/jeecgboot","http://192.168.1.32:9999"],["/upload","http://localhost:3300/upload"]]
+VITE_PROXY = [["/jeecgboot","http://192.168.1.6:9999"],["/upload","http://localhost:3300/upload"]]
 
 #后台接口全路径地址(必填)
-VITE_GLOB_DOMAIN_URL=http://192.168.1.32:9999
+VITE_GLOB_DOMAIN_URL=http://192.168.1.6:9999
 
 #后台接口父地址(必填)
 VITE_GLOB_API_URL=/jeecgboot

+ 0 - 14
src/App.vue

@@ -101,21 +101,7 @@
   // update-end--author:liaozhiyang---date:20231218---for:【QQYUN-6366】升级到antd4.x
 </script>
 <style lang="less">
-  // update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
   img {
     display: inline-block;
   }
-  // update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5839】windi会影响到html2canvas绘制的图片样式
-  .zgztel-check-icon {
-    font-size: 24px;
-    font-weight: bolder;
-
-    &.checked {
-      color: #389e0d;
-    }
-
-    &.no-checked {
-      color: #ff4d4f;
-    }
-  }
 </style>

+ 15 - 15
src/hooks/system/useJvxeMethods.ts

@@ -5,12 +5,12 @@ import { VALIDATE_FAILED, validateFormModelAndTables } from '/@/utils/common/vxe
 export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs, activeKey, refKeys, validateSubForm?) {
   const formRef = ref();
   /** 查询某个tab的数据 */
-  function requestSubTableData(url, params, tab, success) {
+  function requestSubTableData(url, params, tab, success?) {
     tab.loading = true;
     defHttp
       .get({ url, params }, { isTransformResponse: false })
       .then((res) => {
-        let { result } = res;
+        const { result } = res;
         if (res.success && result) {
           if (Array.isArray(result)) {
             tab.dataSource = result;
@@ -35,7 +35,7 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
 
   /** 获取所有的editableTable实例*/
   function getAllTable() {
-    let values = Object.values(tableRefs);
+    const values = Object.values(tableRefs);
     return Promise.all(values);
   }
   /** 确定按钮点击事件 */
@@ -43,7 +43,7 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
     /** 触发表单验证 */
     getAllTable()
       .then((tables) => {
-        let values = formRef.value.getFieldsValue();
+        const values = formRef.value.getFieldsValue();
         return validateFormModelAndTables(formRef.value.validate, values, tables, formRef.value.getProps, false);
       })
       .then((allValues) => {
@@ -54,7 +54,7 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
         if (typeof classifyIntoFormData !== 'function') {
           throw throwNotFunction('classifyIntoFormData');
         }
-        let formData = classifyIntoFormData(allValues);
+        const formData = classifyIntoFormData(allValues);
         // 发起请求
         return requestAddOrEdit(formData);
       })
@@ -62,9 +62,9 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
         if (e.error === VALIDATE_FAILED) {
           // 如果有未通过表单验证的子表,就自动跳转到它所在的tab
           //update-begin-author:taoyan date:2022-11-22 for: VUEN-2866【代码生成】Tab风格 一对多子表校验不通过时,点击提交表单空白了,流程附加页面也有此问题
-          if(e.paneKey){
-            activeKey.value = e.paneKey
-          }else{
+          if (e.paneKey) {
+            activeKey.value = e.paneKey;
+          } else {
             //update-begin-author:liusq date:2024-06-12 for: TV360X-478 一对多tab,校验未通过时,tab没有跳转
             activeKey.value = e.subIndex == null ? (e.index == null ? unref(activeKey) : refKeys.value[e.index]) : Object.keys(tableRefs)[e.subIndex];
             //update-end-author:liusq date:2024-06-12  for: TV360X-478 一对多tab,校验未通过时,tab没有跳转
@@ -101,7 +101,7 @@ export function useJvxeMethod(requestAddOrEdit, classifyIntoFormData, tableRefs,
   function throwNotArray(name) {
     return `${name} 未定义或不是一个数组`;
   }
-  return [handleChangeTabs, handleSubmit, requestSubTableData, formRef];
+  return [handleChangeTabs, handleSubmit, requestSubTableData, formRef, throwNotArray];
 }
 
 //update-begin-author:taoyan date:2022-6-16 for: 代码生成-原生表单用
@@ -120,19 +120,19 @@ export function useValidateAntFormAndTable(activeKey, refMap) {
    * 获取所有子表数据
    */
   async function getSubFormAndTableData() {
-    let formData = {};
-    let all = Object.keys(refMap);
+    const formData = {};
+    const all = Object.keys(refMap);
     let key = '';
     for (let i = 0; i < all.length; i++) {
       key = all[i];
-      let instance = refMap[key].value;
+      const instance = refMap[key].value;
       if (instance.isForm) {
-        let subFormData = await validateFormAndGetData(instance, key);
+        const subFormData = await validateFormAndGetData(instance, key);
         if (subFormData) {
           formData[key + 'List'] = [subFormData];
         }
       } else {
-        let arr = await validateTableAndGetData(instance, key);
+        const arr = await validateTableAndGetData(instance, key);
         if (arr && arr.length > 0) {
           formData[key + 'List'] = arr;
         }
@@ -180,7 +180,7 @@ export function useValidateAntFormAndTable(activeKey, refMap) {
    */
   async function validateFormAndGetData(instance, key) {
     try {
-      let data = await instance.getFormData();
+      const data = await instance.getFormData();
       transformData(data);
       return data;
     } catch (e) {

+ 20 - 0
src/views/equipmentLifecycle/components/YOrN.vue

@@ -0,0 +1,20 @@
+<template>
+  <a-tag color="#ff4d4f" v-if="yes">{{ yesText }}</a-tag>
+  <a-tag color="#389e0d" v-else>{{ noText }}</a-tag>
+</template>
+<script setup lang="ts">
+  defineProps({
+    yes: {
+      type: Boolean,
+      default: true,
+    },
+    yesText: {
+      type: String,
+      default: '是',
+    },
+    noText: {
+      type: String,
+      default: '否',
+    },
+  });
+</script>

+ 16 - 1
src/views/equipmentLifecycle/device/list/DeviceBaseInfo.data.ts

@@ -7,6 +7,7 @@ import { getAllDept } from '../../setting/department/CompanyDepartment.api';
 import { getAllCategory } from '../../setting/category/CompanyCategory.api';
 import { getAllPosition } from '../../setting/position/CompanyPosition.api';
 import { checkDeviceCode } from './DeviceBaseInfo.api';
+import { list as supplierList } from '../../supplier/list/SupplierManage.api';
 
 //列表数据
 export const columns: BasicColumn[] = [
@@ -416,7 +417,21 @@ export const formSchema: FormSchema[] = [
   {
     label: '供应商',
     field: 'supplier',
-    component: 'Input',
+    component: 'ApiSelect',
+    componentProps: {
+      api: supplierList,
+      resultField: 'records',
+      labelField: 'supplierName',
+      valueField: 'id',
+      pageConfig: {
+        isPage: true,
+        //如果和默认的分页字段一致,请忽略以下配置
+        pageField: 'pageNo',
+        pageSizeField: 'pageSize',
+        totalField: 'total',
+        listField: 'records',
+      },
+    },
     colProps: { span: 12 },
   },
   {

+ 3 - 4
src/views/equipmentLifecycle/device/list/DeviceBaseInfoList.vue

@@ -61,12 +61,10 @@
       </div>
     </template>
     <template #isMeteringDevice="{ record }">
-      <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="record.isMeteringDevice === true" />
-      <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+      <YOrN :yes="!record.isMeteringDevice" yes-text="否" no-text="是" />
     </template>
     <template #isDepreciation="{ record }">
-      <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="record.isDepreciation === true" />
-      <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+      <YOrN :yes="!record.isDepreciation" yes-text="否" no-text="是" />
     </template>
   </BasicTable>
   <!-- 表单区域 -->
@@ -92,6 +90,7 @@
   import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
   import DeviceBaseInfoDetailDrawer from './components/DeviceBaseInfoDetailDrawer.vue';
   import { useDrawer } from '/@/components/Drawer';
+  import YOrN from '/@/views/equipmentLifecycle/components/YOrN.vue';
 
   const queryParam = reactive<any>({});
 

+ 12 - 7
src/views/equipmentLifecycle/device/list/components/deviceDetail.vue/baseInfo.vue

@@ -32,16 +32,13 @@
           <a-descriptions-item label="所属部门" :span="3">{{ info.departmentName }}</a-descriptions-item>
           <a-descriptions-item label="功能位置" :span="3">{{ info.positionName }}</a-descriptions-item>
           <a-descriptions-item label="特种设备">
-            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isSpecialEquip === true" />
-            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+            <YOrN :yes="!info.isSpecialEquip" yes-text="否" no-text="是" />
           </a-descriptions-item>
           <a-descriptions-item label="是否计量设备">
-            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isMeteringDevice === true" />
-            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+            <YOrN :yes="!info.isMeteringDevice" yes-text="否" no-text="是" />
           </a-descriptions-item>
           <a-descriptions-item label="是否开启折旧">
-            <Icon icon="ant-design:check-outlined" class="zgztel-check-icon checked" v-if="info.isDepreciation === true" />
-            <Icon icon="ant-design:close-outlined" class="zgztel-check-icon no-checked" v-else />
+            <YOrN :yes="!info.isDepreciation" yes-text="否" no-text="是" />
           </a-descriptions-item>
           <a-descriptions-item label="技术参数" :span="3">{{ info.technicalParameters }}</a-descriptions-item>
           <a-descriptions-item label="备注" :span="3">{{ info.remarks }}</a-descriptions-item>
@@ -133,8 +130,9 @@
   import { useListPage } from '/@/hooks/system/useListPage';
   import { dtlColumns, spareColumns } from '../../DeviceBaseInfo.data';
   import { queryDeviceBaseInfoByParentId, materialList } from '../../DeviceBaseInfo.api';
+  import YOrN from '/@/views/equipmentLifecycle/components/YOrN.vue';
   export default defineComponent({
-    components: { AImage, AImagePreviewGroup: AImage.PreviewGroup, BasicTable },
+    components: { AImage, AImagePreviewGroup: AImage.PreviewGroup, BasicTable, YOrN },
     props: {
       info: {
         type: Object,
@@ -152,6 +150,7 @@
           canResize: false,
           showTableSetting: false,
           showActionColumn: false,
+          immediate: false,
           beforeFetch: (params) => {
             return Object.assign(params, { deviceId: props.info.id, queryType: 2 });
           },
@@ -170,6 +169,7 @@
           canResize: false,
           showTableSetting: false,
           showActionColumn: false,
+          immediate: false,
           beforeFetch: (params) => {
             return Object.assign(params, { deviceId: props.info.id, queryType: 1 });
           },
@@ -187,6 +187,7 @@
           canResize: false,
           showTableSetting: false,
           showActionColumn: false,
+          immediate: false,
           beforeFetch: (params) => {
             return Object.assign(params, { deviceId: props.info.id });
           },
@@ -258,6 +259,10 @@
     .right-col {
       .jeecg-basic-table {
         padding: 0;
+
+        :deep(.ant-table-wrapper) {
+          padding: 0;
+        }
       }
     }
   }

+ 14 - 15
src/views/equipmentLifecycle/supplier/apply/PurchaseApplication.api.ts

@@ -1,12 +1,12 @@
-import {defHttp} from '/@/utils/http/axios';
-import { useMessage } from "/@/hooks/web/useMessage";
+import { defHttp } from '/@/utils/http/axios';
+import { useMessage } from '/@/hooks/web/useMessage';
 
 const { createConfirm } = useMessage();
 
 enum Api {
   list = '/purchaseManage/purchaseApplication/list',
-  save='/purchaseManage/purchaseApplication/add',
-  edit='/purchaseManage/purchaseApplication/edit',
+  save = '/purchaseManage/purchaseApplication/add',
+  edit = '/purchaseManage/purchaseApplication/edit',
   deleteOne = '/purchaseManage/purchaseApplication/delete',
   deleteBatch = '/purchaseManage/purchaseApplication/deleteBatch',
   importExcel = '/purchaseManage/purchaseApplication/importExcel',
@@ -38,17 +38,16 @@ export const materialListList = Api.materialListList;
  * 列表接口
  * @param params
  */
-export const list = (params) =>
-  defHttp.get({url: Api.list, params});
+export const list = (params) => defHttp.get({ url: Api.list, params });
 
 /**
  * 删除单个
  */
-export const deleteOne = (params,handleSuccess) => {
-  return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
+export const deleteOne = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
     handleSuccess();
   });
-}
+};
 /**
  * 批量删除
  * @param params
@@ -61,17 +60,17 @@ export const batchDelete = (params, handleSuccess) => {
     okText: '确认',
     cancelText: '取消',
     onOk: () => {
-      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+      return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
         handleSuccess();
       });
-    }
+    },
   });
-}
+};
 /**
  * 保存或者更新
  * @param params
  */
 export const saveOrUpdate = (params, isUpdate) => {
-  let url = isUpdate ? Api.edit : Api.save;
-  return defHttp.post({url: url, params});
-}
+  const url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params });
+};

+ 145 - 121
src/views/equipmentLifecycle/supplier/apply/PurchaseApplication.data.ts

@@ -1,9 +1,11 @@
 import { BasicColumn } from '/@/components/Table';
 import { FormSchema } from '/@/components/Table';
 // import { rules } from '/@/utils/helper/validator';
-// import { render } from '/@/utils/common/renderUtils';
+import { render } from '/@/utils/common/renderUtils';
 import { JVxeTypes, JVxeColumn } from '/@/components/jeecg/JVxeTable/types';
-// import { getWeekMonthQuarterYear } from '/@/utils';
+import { list as planList } from '../plan/PurchasePlan.api';
+import dayjs from 'dayjs';
+
 //列表数据
 export const columns: BasicColumn[] = [
   {
@@ -27,9 +29,12 @@ export const columns: BasicColumn[] = [
     dataIndex: 'applicant',
   },
   {
-    title: '采购类型(1 设备采购  2 备件物料采购)',
+    title: '采购类型',
     align: 'center',
     dataIndex: 'purchaseType',
+    customRender(opt) {
+      return render.renderDictTag(opt.record.purchaseType, 'purchase_type');
+    },
   },
   {
     title: '项目',
@@ -45,118 +50,154 @@ export const columns: BasicColumn[] = [
     title: '审批状态',
     align: 'center',
     dataIndex: 'approvalStatus',
+    customRender(opt) {
+      return render.renderDictTag(opt.record.approvalStatus, 'approval_status');
+    },
   },
   {
     title: '审批结束时间',
     align: 'center',
     dataIndex: 'approvalEndTime',
   },
-  {
-    title: '采购计划',
-    align: 'center',
-    dataIndex: 'purchasePlan',
-  },
-  {
-    title: '购置理由',
-    align: 'center',
-    dataIndex: 'purchaseReason',
-  },
-  {
-    title: '备注',
-    align: 'center',
-    dataIndex: 'remark',
-  },
-  {
-    title: '采购计划id',
-    align: 'center',
-    dataIndex: 'purchasePlanId',
-  },
 ];
 //查询数据
 export const searchFormSchema: FormSchema[] = [];
 //表单数据
-export const formSchema: FormSchema[] = [
-  {
-    label: '申请单号',
-    field: 'requestNo',
-    component: 'Input',
-  },
-  {
-    label: '申请时间',
-    field: 'applicationTime',
-    component: 'DatePicker',
-    componentProps: {
-      showTime: true,
-      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+export const getFormSchema = (props?: any) => {
+  const formSchema: FormSchema[] = [
+    {
+      label: '采购计划',
+      field: 'purchasePlanId',
+      component: 'ApiSelect',
+      componentProps: {
+        api: planList,
+        params: { approvalStatus: 1 },
+        resultField: 'records',
+        labelField: 'title',
+        valueField: 'id',
+        pageConfig: {
+          isPage: true,
+          //如果和默认的分页字段一致,请忽略以下配置
+          pageField: 'pageNo',
+          pageSizeField: 'pageSize',
+          totalField: 'total',
+          listField: 'records',
+        },
+        onSelect: (value, row) => {
+          props && props.onPurchasePlanSelect && props.onPurchasePlanSelect(value, row);
+        },
+      },
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请选择采购计划' }],
     },
-  },
-  {
-    label: '采购标题',
-    field: 'purchaseTitle',
-    component: 'Input',
-  },
-  {
-    label: '申请人',
-    field: 'applicant',
-    component: 'Input',
-  },
-  {
-    label: '采购类型(1 设备采购  2 备件物料采购)',
-    field: 'purchaseType',
-    component: 'Input',
-  },
-  {
-    label: '项目',
-    field: 'project',
-    component: 'Input',
-  },
-  {
-    label: '当前节点',
-    field: 'currentNode',
-    component: 'Input',
-  },
-  {
-    label: '审批状态',
-    field: 'approvalStatus',
-    component: 'InputNumber',
-  },
-  {
-    label: '审批结束时间',
-    field: 'approvalEndTime',
-    component: 'DatePicker',
-    componentProps: {
-      showTime: true,
-      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    {
+      label: '采购计划',
+      field: 'purchasePlan',
+      component: 'Input',
+      colProps: { span: 12 },
+      show: false,
     },
-  },
-  {
-    label: '采购计划',
-    field: 'purchasePlan',
-    component: 'Input',
-  },
-  {
-    label: '购置理由',
-    field: 'purchaseReason',
-    component: 'Input',
-  },
-  {
-    label: '备注',
-    field: 'remark',
-    component: 'Input',
-  },
-  {
-    label: '采购计划id',
-    field: 'purchasePlanId',
-    component: 'Input',
-  },
-  // TODO 主键隐藏字段,目前写死为ID
-  {
-    label: '',
-    field: 'id',
-    component: 'Input',
-    show: false,
-  },
-];
+    {
+      label: '申请单号',
+      field: 'requestNo',
+      component: 'Input',
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请输入申请单号' }],
+    },
+    {
+      label: '申请时间',
+      field: 'applicationTime',
+      component: 'DatePicker',
+      componentProps: {
+        showTime: true,
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      },
+      defaultValue: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请选择申请时间' }],
+    },
+    {
+      label: '采购标题',
+      field: 'purchaseTitle',
+      component: 'Input',
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请输入采购标题' }],
+    },
+    {
+      label: '申请人',
+      field: 'applicant',
+      component: 'JSelectUser',
+      componentProps: {
+        maxSelectCount: 1,
+      },
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请选择申请人' }],
+    },
+    {
+      label: '采购类型',
+      field: 'purchaseType',
+      component: 'JDictSelectTag',
+      componentProps: {
+        dictCode: 'purchase_type',
+      },
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请选择采购类型' }],
+    },
+    {
+      label: '当前节点',
+      field: 'currentNode',
+      component: 'Input',
+      colProps: { span: 12 },
+    },
+    {
+      label: '审批状态',
+      field: 'approvalStatus',
+      component: 'JDictSelectTag',
+      componentProps: {
+        dictCode: 'approval_status',
+      },
+      defaultValue: '1',
+      colProps: { span: 12 },
+      rules: [{ required: true, message: '请选择审批状态' }],
+    },
+    {
+      label: '审批结束时间',
+      field: 'approvalEndTime',
+      component: 'DatePicker',
+      componentProps: {
+        showTime: true,
+        valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      },
+      defaultValue: dayjs().add(1, 'month').format('YYYY-MM-DD HH:mm:ss'),
+      colProps: { span: 12 },
+    },
+    {
+      label: '项目',
+      field: 'project',
+      component: 'Input',
+      colProps: { span: 12 },
+    },
+    {
+      label: '购置理由',
+      field: 'purchaseReason',
+      component: 'InputTextArea',
+    },
+    {
+      label: '备注',
+      field: 'remark',
+      component: 'InputTextArea',
+    },
+    // TODO 主键隐藏字段,目前写死为ID
+    {
+      label: '',
+      field: 'id',
+      component: 'Input',
+      show: false,
+    },
+  ];
+
+  return { formSchema };
+};
 //子表单数据
 //子表表格配置
 export const purchaseApplicationAttachmentColumns: JVxeColumn[] = [
@@ -164,7 +205,6 @@ export const purchaseApplicationAttachmentColumns: JVxeColumn[] = [
     title: '文件名称',
     key: 'fileName',
     type: JVxeTypes.input,
-    width: '200px',
     placeholder: '请输入${title}',
     defaultValue: '',
   },
@@ -174,15 +214,6 @@ export const purchaseApplicationAttachmentColumns: JVxeColumn[] = [
     type: JVxeTypes.image,
     token: true,
     responseName: 'message',
-    width: '200px',
-    placeholder: '请输入${title}',
-    defaultValue: '',
-  },
-  {
-    title: '采购申请id',
-    key: 'purchaseApplicationId',
-    type: JVxeTypes.input,
-    width: '200px',
     placeholder: '请输入${title}',
     defaultValue: '',
   },
@@ -324,14 +355,6 @@ export const materialListColumns: JVxeColumn[] = [
     placeholder: '请输入${title}',
     defaultValue: '',
   },
-  {
-    title: '采购申请id(外键)',
-    key: 'purchaseApplicationId',
-    type: JVxeTypes.input,
-    width: '200px',
-    placeholder: '请输入${title}',
-    defaultValue: '',
-  },
 ];
 
 // 高级查询数据
@@ -391,5 +414,6 @@ export const superQuerySchema = {
  */
 export function getBpmFormSchema(_formData): FormSchema[] {
   // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
+  const { formSchema } = getFormSchema();
   return formSchema;
 }

+ 42 - 36
src/views/equipmentLifecycle/supplier/apply/components/PurchaseApplicationForm.vue

@@ -1,8 +1,8 @@
 <template>
   <div>
-    <BasicForm @register="registerForm" ref="formRef"/>
+    <BasicForm @register="registerForm" ref="formRef" />
     <!-- 子表单区域 -->
-    <a-tabs v-model:activeKey="activeKey" animated  @change="handleChangeTabs">
+    <a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs">
       <a-tab-pane tab="采购申请相关附件" key="purchaseApplicationAttachment" :forceRender="true">
         <JVxeTable
           keep-source
@@ -37,74 +37,80 @@
       </a-tab-pane>
     </a-tabs>
 
-    <div style="width: 100%;text-align: center" v-if="!formDisabled">
+    <div style="width: 100%; text-align: center" v-if="!formDisabled">
       <a-button @click="handleSubmit" pre-icon="ant-design:check" type="primary">提 交</a-button>
     </div>
   </div>
 </template>
 
 <script lang="ts">
-
-  import {BasicForm, useForm} from '/@/components/Form/index';
+  import { BasicForm, useForm } from '/@/components/Form/index';
   import { computed, defineComponent, reactive, ref, unref } from 'vue';
-  import {defHttp} from '/@/utils/http/axios';
+  import { defHttp } from '/@/utils/http/axios';
   import { propTypes } from '/@/utils/propTypes';
   import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
   import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils';
-  import {getBpmFormSchema,purchaseApplicationAttachmentColumns,materialListColumns} from '../PurchaseApplication.data';
-  import {saveOrUpdate,purchaseApplicationAttachmentList,materialListList} from '../PurchaseApplication.api';
+  import { getBpmFormSchema, purchaseApplicationAttachmentColumns, materialListColumns } from '../PurchaseApplication.data';
+  import { saveOrUpdate, purchaseApplicationAttachmentList, materialListList } from '../PurchaseApplication.api';
 
   export default defineComponent({
-    name: "PurchaseApplicationForm",
-    components:{
+    name: 'PurchaseApplicationForm',
+    components: {
       BasicForm,
     },
-    props:{
+    props: {
       formData: propTypes.object.def({}),
       formBpm: propTypes.bool.def(true),
     },
-    setup(props){
+    setup(props) {
       const [registerForm, { setFieldsValue, setProps }] = useForm({
         labelWidth: 150,
         schemas: getBpmFormSchema(props.formData),
         showActionButtonGroup: false,
-        baseColProps: {span: 24}
+        baseColProps: { span: 24 },
       });
 
-      const formDisabled = computed(()=>{
-        if(props.formData.disabled === false){
+      const formDisabled = computed(() => {
+        if (props.formData.disabled === false) {
           return false;
         }
         return true;
       });
 
-      const refKeys = ref(['purchaseApplicationAttachment', 'materialList', ]);
+      const refKeys = ref(['purchaseApplicationAttachment', 'materialList']);
       const activeKey = ref('purchaseApplicationAttachment');
       const purchaseApplicationAttachment = ref();
       const materialList = ref();
-      const tableRefs = {purchaseApplicationAttachment, materialList, };
+      const tableRefs = { purchaseApplicationAttachment, materialList };
       const purchaseApplicationAttachmentTable = reactive({
         loading: false,
         dataSource: [],
-        columns:purchaseApplicationAttachmentColumns,
-        show: false
-      })
+        columns: purchaseApplicationAttachmentColumns,
+        show: false,
+      });
       const materialListTable = reactive({
         loading: false,
         dataSource: [],
-        columns:materialListColumns,
-        show: false
-      })
+        columns: materialListColumns,
+        show: false,
+      });
 
-      const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys,validateSubForm);
+      const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
+        requestAddOrEdit,
+        classifyIntoFormData,
+        tableRefs,
+        activeKey,
+        refKeys,
+        validateSubForm
+      );
 
       function classifyIntoFormData(allValues) {
-        let main = Object.assign({}, allValues.formValue)
+        let main = Object.assign({}, allValues.formValue);
         return {
           ...main, // 展开
           purchaseApplicationAttachmentList: allValues.tablesValue[0].tableData,
           materialListList: allValues.tablesValue[1].tableData,
-        }
+        };
       }
 
       //表单提交事件
@@ -113,19 +119,19 @@
       }
 
       const queryByIdUrl = '/purchaseManage/purchaseApplication/queryById';
-      async function initFormData(){
-        let params = {id: props.formData.dataId};
-        const data = await defHttp.get({url: queryByIdUrl, params});
+      async function initFormData() {
+        let params = { id: props.formData.dataId };
+        const data = await defHttp.get({ url: queryByIdUrl, params });
         //设置表单的值
-        await setFieldsValue({...data});
-        requestSubTableData(purchaseApplicationAttachmentList, {id: data.id}, purchaseApplicationAttachmentTable, ()=>{
+        await setFieldsValue({ ...data });
+        requestSubTableData(purchaseApplicationAttachmentList, { id: data.id }, purchaseApplicationAttachmentTable, () => {
           purchaseApplicationAttachmentTable.show = true;
         });
-        requestSubTableData(materialListList, {id: data.id}, materialListTable, ()=>{
+        requestSubTableData(materialListList, { id: data.id }, materialListTable, () => {
           materialListTable.show = true;
         });
         //默认是禁用
-        await setProps({disabled: formDisabled.value})
+        await setProps({ disabled: formDisabled.value });
       }
 
       initFormData();
@@ -141,7 +147,7 @@
         materialList,
         purchaseApplicationAttachmentTable,
         materialListTable,
-      }
-    }
+      };
+    },
   });
-</script>
+</script>

+ 121 - 88
src/views/equipmentLifecycle/supplier/apply/components/PurchaseApplicationModal.vue

@@ -1,6 +1,14 @@
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
-    <BasicForm @register="registerForm" ref="formRef" name="PurchaseApplicationForm"/>
+  <BasicModal
+    v-bind="$attrs"
+    @register="registerModal"
+    destroyOnClose
+    :title="title"
+    :body-style="{ padding: '20px 20px 0' }"
+    :width="1200"
+    @ok="handleSubmit"
+  >
+    <BasicForm @register="registerForm" ref="formRef" name="PurchaseApplicationForm" />
     <!-- 子表单区域 -->
     <a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs">
       <a-tab-pane tab="采购申请相关附件" key="purchaseApplicationAttachment" :forceRender="true">
@@ -16,7 +24,7 @@
           :rowSelection="true"
           :disabled="formDisabled"
           :toolbar="true"
-          />
+        />
       </a-tab-pane>
       <a-tab-pane tab="采购物料清单" key="materialList" :forceRender="true">
         <JVxeTable
@@ -31,103 +39,128 @@
           :rowSelection="true"
           :disabled="formDisabled"
           :toolbar="true"
-          />
+        />
       </a-tab-pane>
     </a-tabs>
   </BasicModal>
 </template>
 
 <script lang="ts" setup>
-    import {ref, computed, unref,reactive} from 'vue';
-    import {BasicModal, useModalInner} from '/@/components/Modal';
-    import {BasicForm, useForm} from '/@/components/Form/index';
-    import { JVxeTable } from '/@/components/jeecg/JVxeTable'
-    import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
-    import {formSchema,purchaseApplicationAttachmentColumns,materialListColumns} from '../PurchaseApplication.data';
-    import {saveOrUpdate,purchaseApplicationAttachmentList,materialListList} from '../PurchaseApplication.api';
-    import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
-    // Emits声明
-    const emit = defineEmits(['register','success']);
-    const isUpdate = ref(true);
-    const formDisabled = ref(false);
-    const refKeys = ref(['purchaseApplicationAttachment', 'materialList', ]);
-    const activeKey = ref('purchaseApplicationAttachment');
-    const purchaseApplicationAttachment = ref();
-    const materialList = ref();
-    const tableRefs = {purchaseApplicationAttachment, materialList, };
-    const purchaseApplicationAttachmentTable = reactive({
-          loading: false,
-          dataSource: [],
-          columns:purchaseApplicationAttachmentColumns
-    })
-    const materialListTable = reactive({
-          loading: false,
-          dataSource: [],
-          columns:materialListColumns
-    })
-    //表单配置
-    const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
-        labelWidth: 150,
-        schemas: formSchema,
-        showActionButtonGroup: false,
-        baseColProps: {span: 24}
-    });
-     //表单赋值
-    const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
-        //重置表单
-        await reset();
-        setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
-        isUpdate.value = !!data?.isUpdate;
-        formDisabled.value = !data?.showFooter;
-        if (unref(isUpdate)) {
-            //表单赋值
-            await setFieldsValue({
-                ...data.record,
-            });
-             requestSubTableData(purchaseApplicationAttachmentList, {id:data?.record?.id}, purchaseApplicationAttachmentTable)
-             requestSubTableData(materialListList, {id:data?.record?.id}, materialListTable)
-        }
-        // 隐藏底部时禁用整个表单
-       setProps({ disabled: !data?.showFooter })
-    });
-    //方法配置
-    const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys);
+  import { ref, computed, unref, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { JVxeTable } from '/@/components/jeecg/JVxeTable';
+  import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
+  import { getFormSchema, purchaseApplicationAttachmentColumns, materialListColumns } from '../PurchaseApplication.data';
+  import { saveOrUpdate, purchaseApplicationAttachmentList, materialListList } from '../PurchaseApplication.api';
 
-    //设置标题
-    const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情'));
+  // Emits声明
+  const emit = defineEmits(['register', 'success']);
+  const isUpdate = ref(true);
+  const formDisabled = ref(false);
+  const refKeys = ref(['purchaseApplicationAttachment', 'materialList']);
+  const activeKey = ref('purchaseApplicationAttachment');
+  const purchaseApplicationAttachment = ref();
+  const materialList = ref();
+  const tableRefs = { purchaseApplicationAttachment, materialList };
+  const purchaseApplicationAttachmentTable = reactive({
+    loading: false,
+    dataSource: [],
+    columns: purchaseApplicationAttachmentColumns,
+  });
+  const materialListTable = reactive({
+    loading: false,
+    dataSource: [],
+    columns: materialListColumns,
+  });
 
-    async function reset(){
-      await resetFields();
-      activeKey.value = 'purchaseApplicationAttachment';
-      purchaseApplicationAttachmentTable.dataSource = [];
-      materialListTable.dataSource = [];
+  const { formSchema } = getFormSchema({
+    onPurchasePlanSelect: (val, record) => {
+      const { purchaseType, applicant, currentNode, approvalStatus, approvalEndTime, label } = record;
+      setFieldsValue({
+        purchasePlanId: val,
+        purchaseTitle: label,
+        purchasePlan: label,
+        applicant,
+        purchaseType: String(purchaseType),
+        currentNode,
+        approvalStatus: String(approvalStatus),
+        approvalEndTime,
+      });
+    },
+  });
+
+  //表单配置
+  const [registerForm, { setProps, resetFields, setFieldsValue }] = useForm({
+    labelWidth: 100,
+    schemas: formSchema,
+    showActionButtonGroup: false,
+    baseColProps: { span: 24 },
+  });
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    //重置表单
+    await reset();
+    setModalProps({ confirmLoading: false, showCancelBtn: data?.showFooter, showOkBtn: data?.showFooter });
+    isUpdate.value = !!data?.isUpdate;
+    formDisabled.value = !data?.showFooter;
+    if (unref(isUpdate)) {
+      //表单赋值
+      await setFieldsValue({
+        ...data.record,
+      });
+      if (typeof requestSubTableData === 'function') {
+        requestSubTableData(purchaseApplicationAttachmentList, { id: data?.record?.id }, purchaseApplicationAttachmentTable);
+        requestSubTableData(materialListList, { id: data?.record?.id }, materialListTable);
+      }
     }
-    function classifyIntoFormData(allValues) {
-         let main = Object.assign({}, allValues.formValue)
-         return {
-           ...main, // 展开
-           purchaseApplicationAttachmentList: allValues.tablesValue[0].tableData,
-           materialListList: allValues.tablesValue[1].tableData,
-         }
-       }
-    //表单提交事件
-    async function requestAddOrEdit(values) {
-        try {
-            setModalProps({confirmLoading: true});
-            //提交表单
-            await saveOrUpdate(values, isUpdate.value);
-            //关闭弹窗
-            closeModal();
-            //刷新列表
-            emit('success');
-        } finally {
-            setModalProps({confirmLoading: false});
-        }
+    // 隐藏底部时禁用整个表单
+    setProps({ disabled: !data?.showFooter });
+  });
+  //方法配置
+  const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
+    requestAddOrEdit,
+    classifyIntoFormData,
+    tableRefs,
+    activeKey,
+    refKeys
+  );
+
+  //设置标题
+  const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情'));
+
+  async function reset() {
+    await resetFields();
+    activeKey.value = 'purchaseApplicationAttachment';
+    purchaseApplicationAttachmentTable.dataSource = [];
+    materialListTable.dataSource = [];
+  }
+  function classifyIntoFormData(allValues) {
+    let main = Object.assign({}, allValues.formValue);
+    return {
+      ...main, // 展开
+      purchaseApplicationAttachmentList: allValues.tablesValue[0].tableData,
+      materialListList: allValues.tablesValue[1].tableData,
+    };
+  }
+  //表单提交事件
+  async function requestAddOrEdit(values) {
+    try {
+      setModalProps({ confirmLoading: true });
+      //提交表单
+      await saveOrUpdate(values, isUpdate.value);
+      //关闭弹窗
+      closeModal();
+      //刷新列表
+      emit('success');
+    } finally {
+      setModalProps({ confirmLoading: false });
     }
+  }
 </script>
 
 <style lang="less" scoped>
-	/** 时间和数字输入框样式 */
+  /** 时间和数字输入框样式 */
   :deep(.ant-input-number) {
     width: 100%;
   }
@@ -135,4 +168,4 @@
   :deep(.ant-calendar-picker) {
     width: 100%;
   }
-</style>
+</style>

+ 25 - 193
src/views/equipmentLifecycle/supplier/apply/index.vue

@@ -1,203 +1,35 @@
 <template>
-  <div>
-    <!--引用表格-->
-    <BasicTable @register="registerTable" :rowSelection="rowSelection">
-      <!--插槽:table标题-->
-      <template #tableTitle>
-        <a-button type="primary" v-auth="'purchaseManage:sbsmzq_purchase_application:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">
-          新增
-        </a-button>
-        <a-button
-          type="primary"
-          v-auth="'purchaseManage:sbsmzq_purchase_application:exportXls'"
-          preIcon="ant-design:export-outlined"
-          @click="onExportXls"
-        >
-          导出
-        </a-button>
-        <j-upload-button
-          type="primary"
-          v-auth="'purchaseManage:sbsmzq_purchase_application:importExcel'"
-          preIcon="ant-design:import-outlined"
-          @click="onImportXls"
-        >
-          导入
-        </j-upload-button>
-        <a-dropdown v-if="selectedRowKeys.length > 0">
-          <template #overlay>
-            <a-menu>
-              <a-menu-item key="1" @click="batchHandleDelete">
-                <Icon icon="ant-design:delete-outlined" />
-                删除
-              </a-menu-item>
-            </a-menu>
-          </template>
-          <a-button v-auth="'purchaseManage:sbsmzq_purchase_application:deleteBatch'">
-            批量操作
-            <Icon icon="mdi:chevron-down" />
-          </a-button>
-        </a-dropdown>
-        <!-- 高级查询 -->
-        <super-query :config="superQueryConfig" @search="handleSuperQuery" />
-      </template>
-      <!--操作栏-->
-      <template #action="{ record }">
-        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
-      </template>
-      <!--字段回显插槽-->
-      <!-- <template v-slot:bodyCell="{ column, record, index, text }"> </template> -->
-    </BasicTable>
-    <!-- 表单区域 -->
-    <PurchaseApplicationModal @register="registerModal" @success="handleSuccess" />
-  </div>
+  <a-tabs v-model:activeKey="activeKey" size="small" type="card">
+    <a-tab-pane key="1" tab="采购申请">
+      <list />
+    </a-tab-pane>
+    <a-tab-pane key="2" tab="与我相关"> 与我相关 </a-tab-pane>
+    <a-tab-pane key="3" tab="采购明细"> 与我相关 </a-tab-pane>
+  </a-tabs>
 </template>
 
-<script lang="ts" name="purchaseManage-purchaseApplication" setup>
-  import { reactive } from 'vue';
-  import { BasicTable, TableAction } from '/@/components/Table';
-  import { useListPage } from '/@/hooks/system/useListPage';
-  import { useModal } from '/@/components/Modal';
-  import PurchaseApplicationModal from './components/PurchaseApplicationModal.vue';
-  import { columns, searchFormSchema, superQuerySchema } from './PurchaseApplication.data';
-  import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './PurchaseApplication.api';
+<script lang="ts" name="purchaseManage-purchasePlan" setup>
+  import { ref } from 'vue';
+  import list from './list.vue';
 
-  const queryParam = reactive<any>({});
-  //注册model
-  const [registerModal, { openModal }] = useModal();
-  //注册table数据
-  const { tableContext, onExportXls, onImportXls } = useListPage({
-    tableProps: {
-      title: '采购申请',
-      api: list,
-      columns,
-      canResize: false,
-      formConfig: {
-        //labelWidth: 120,
-        schemas: searchFormSchema,
-        autoSubmitOnEnter: true,
-        showAdvancedButton: true,
-        fieldMapToNumber: [],
-        fieldMapToTime: [],
-      },
-      actionColumn: {
-        width: 120,
-        fixed: 'right',
-      },
-      beforeFetch: (params) => {
-        return Object.assign(params, queryParam);
-      },
-    },
-    exportConfig: {
-      name: '采购申请',
-      url: getExportUrl,
-      params: queryParam,
-    },
-    importConfig: {
-      url: getImportUrl,
-      success: handleSuccess,
-    },
-  });
+  const activeKey = ref('1');
+</script>
 
-  const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
+<style lang="less" scoped>
+  .ant-tabs {
+    height: 100%;
+    padding: 10px;
 
-  // 高级查询配置
-  const superQueryConfig = reactive(superQuerySchema);
+    :deep(.ant-tabs-nav) {
+      margin-bottom: 0;
+    }
 
-  /**
-   * 高级查询事件
-   */
-  function handleSuperQuery(params) {
-    Object.keys(params).map((k) => {
-      queryParam[k] = params[k];
-    });
-    reload();
-  }
+    :deep(.ant-tabs-content) {
+      height: 100%;
+    }
 
-  /**
-   * 新增事件
-   */
-  function handleAdd() {
-    openModal(true, {
-      isUpdate: false,
-      showFooter: true,
-    });
-  }
-  /**
-   * 编辑事件
-   */
-  function handleEdit(record: Recordable) {
-    openModal(true, {
-      record,
-      isUpdate: true,
-      showFooter: true,
-    });
-  }
-  /**
-   * 详情
-   */
-  function handleDetail(record: Recordable) {
-    openModal(true, {
-      record,
-      isUpdate: true,
-      showFooter: false,
-    });
-  }
-  /**
-   * 删除事件
-   */
-  async function handleDelete(record) {
-    await deleteOne({ id: record.id }, handleSuccess);
-  }
-  /**
-   * 批量删除事件
-   */
-  async function batchHandleDelete() {
-    await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
-  }
-  /**
-   * 成功回调
-   */
-  function handleSuccess() {
-    (selectedRowKeys.value = []) && reload();
-  }
-  /**
-   * 操作栏
-   */
-  function getTableAction(record) {
-    return [
-      {
-        label: '编辑',
-        onClick: handleEdit.bind(null, record),
-        auth: 'purchaseManage:sbsmzq_purchase_application:edit',
-      },
-    ];
-  }
-
-  /**
-   * 下拉操作栏
-   */
-  function getDropDownAction(record) {
-    return [
-      {
-        label: '详情',
-        onClick: handleDetail.bind(null, record),
-      },
-      {
-        label: '删除',
-        popConfirm: {
-          title: '是否确认删除',
-          confirm: handleDelete.bind(null, record),
-          placement: 'topLeft',
-        },
-        auth: 'purchaseManage:sbsmzq_purchase_application:delete',
-      },
-    ];
-  }
-</script>
-
-<style lang="less" scoped>
-  :deep(.ant-picker),
-  :deep(.ant-input-number) {
-    width: 100%;
+    :deep(.jeecg-basic-table) {
+      padding: 10px 0 0;
+    }
   }
 </style>

+ 217 - 0
src/views/equipmentLifecycle/supplier/apply/list.vue

@@ -0,0 +1,217 @@
+<template>
+  <div>
+    <!--引用表格-->
+    <BasicTable @register="registerTable" :rowSelection="!noOperate ? rowSelection : null">
+      <!--插槽:table标题-->
+      <template #tableTitle v-if="!noOperate">
+        <a-button type="primary" v-auth="'purchaseManage:sbsmzq_purchase_application:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">
+          新增
+        </a-button>
+        <a-button
+          type="primary"
+          v-auth="'purchaseManage:sbsmzq_purchase_application:exportXls'"
+          preIcon="ant-design:export-outlined"
+          @click="onExportXls"
+        >
+          导出
+        </a-button>
+        <j-upload-button
+          type="primary"
+          v-auth="'purchaseManage:sbsmzq_purchase_application:importExcel'"
+          preIcon="ant-design:import-outlined"
+          @click="onImportXls"
+        >
+          导入
+        </j-upload-button>
+        <a-dropdown v-if="selectedRowKeys.length > 0">
+          <template #overlay>
+            <a-menu>
+              <a-menu-item key="1" @click="batchHandleDelete">
+                <Icon icon="ant-design:delete-outlined" />
+                删除
+              </a-menu-item>
+            </a-menu>
+          </template>
+          <a-button v-auth="'purchaseManage:sbsmzq_purchase_application:deleteBatch'">
+            批量操作
+            <Icon icon="mdi:chevron-down" />
+          </a-button>
+        </a-dropdown>
+        <!-- 高级查询 -->
+        <super-query :config="superQueryConfig" @search="handleSuperQuery" />
+      </template>
+      <!--操作栏-->
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+      </template>
+      <!--字段回显插槽-->
+      <!-- <template v-slot:bodyCell="{ column, record, index, text }"> </template> -->
+    </BasicTable>
+    <!-- 表单区域 -->
+    <PurchaseApplicationModal @register="registerModal" @success="handleSuccess" />
+  </div>
+</template>
+
+<script lang="ts" name="purchaseApplication" setup>
+  import { reactive } from 'vue';
+  import { BasicTable, TableAction } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { useModal } from '/@/components/Modal';
+  import PurchaseApplicationModal from './components/PurchaseApplicationModal.vue';
+  import { columns, searchFormSchema, superQuerySchema } from './PurchaseApplication.data';
+  import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './PurchaseApplication.api';
+
+  const props = defineProps<{
+    noOperate?: boolean;
+    purchasePlanId?: string;
+  }>();
+
+  const queryParam = reactive<any>({});
+  //注册model
+  const [registerModal, { openModal }] = useModal();
+  //注册table数据
+  const { tableContext, onExportXls, onImportXls } = useListPage({
+    tableProps: {
+      title: !props.noOperate ? '采购申请' : '',
+      api: list,
+      columns,
+      canResize: false,
+      showIndexColumn: true,
+      showActionColumn: !props.noOperate,
+      immediate: props.noOperate !== true,
+      showTableSetting: !props.noOperate,
+      size: !props.noOperate ? 'middle' : 'small',
+      formConfig: {
+        //labelWidth: 120,
+        schemas: searchFormSchema,
+        autoSubmitOnEnter: true,
+        showAdvancedButton: true,
+        fieldMapToNumber: [],
+        fieldMapToTime: [],
+      },
+      actionColumn: {
+        width: 120,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return props.purchasePlanId ? Object.assign(params, queryParam, { purchasePlanId: props.purchasePlanId }) : Object.assign(params, queryParam);
+      },
+    },
+    exportConfig: {
+      name: '采购申请',
+      url: getExportUrl,
+      params: queryParam,
+    },
+    importConfig: {
+      url: getImportUrl,
+      success: handleSuccess,
+    },
+  });
+
+  const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
+
+  // 高级查询配置
+  const superQueryConfig = reactive(superQuerySchema);
+
+  /**
+   * 高级查询事件
+   */
+  function handleSuperQuery(params) {
+    Object.keys(params).map((k) => {
+      queryParam[k] = params[k];
+    });
+    reload();
+  }
+
+  /**
+   * 新增事件
+   */
+  function handleAdd() {
+    openModal(true, {
+      isUpdate: false,
+      showFooter: true,
+    });
+  }
+  /**
+   * 编辑事件
+   */
+  function handleEdit(record: Recordable) {
+    openModal(true, {
+      record,
+      isUpdate: true,
+      showFooter: true,
+    });
+  }
+  /**
+   * 详情
+   */
+  function handleDetail(record: Recordable) {
+    openModal(true, {
+      record,
+      isUpdate: true,
+      showFooter: false,
+    });
+  }
+  /**
+   * 删除事件
+   */
+  async function handleDelete(record) {
+    await deleteOne({ id: record.id }, handleSuccess);
+  }
+  /**
+   * 批量删除事件
+   */
+  async function batchHandleDelete() {
+    await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
+  }
+  /**
+   * 成功回调
+   */
+  function handleSuccess() {
+    (selectedRowKeys.value = []) && reload();
+  }
+  /**
+   * 操作栏
+   */
+  function getTableAction(record) {
+    return [
+      {
+        label: '编辑',
+        onClick: handleEdit.bind(null, record),
+        auth: 'purchaseManage:sbsmzq_purchase_application:edit',
+      },
+    ];
+  }
+
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [
+      {
+        label: '详情',
+        onClick: handleDetail.bind(null, record),
+      },
+      {
+        label: '删除',
+        popConfirm: {
+          title: '是否确认删除',
+          confirm: handleDelete.bind(null, record),
+          placement: 'topLeft',
+        },
+        auth: 'purchaseManage:sbsmzq_purchase_application:delete',
+      },
+    ];
+  }
+
+  defineExpose({
+    reload,
+  });
+</script>
+
+<style lang="less" scoped>
+  :deep(.ant-picker),
+  :deep(.ant-input-number) {
+    width: 100%;
+  }
+</style>

+ 19 - 15
src/views/equipmentLifecycle/supplier/list/SupplierManage.api.ts

@@ -1,12 +1,12 @@
-import {defHttp} from '/@/utils/http/axios';
-import { useMessage } from "/@/hooks/web/useMessage";
+import { defHttp } from '/@/utils/http/axios';
+import { useMessage } from '/@/hooks/web/useMessage';
 
 const { createConfirm } = useMessage();
 
 enum Api {
   list = '/purchaseManage/supplierManage/list',
-  save='/purchaseManage/supplierManage/add',
-  edit='/purchaseManage/supplierManage/edit',
+  save = '/purchaseManage/supplierManage/add',
+  edit = '/purchaseManage/supplierManage/edit',
   deleteOne = '/purchaseManage/supplierManage/delete',
   deleteBatch = '/purchaseManage/supplierManage/deleteBatch',
   importExcel = '/purchaseManage/supplierManage/importExcel',
@@ -32,17 +32,16 @@ export const supplyContactsList = Api.supplyContactsList;
  * 列表接口
  * @param params
  */
-export const list = (params) =>
-  defHttp.get({url: Api.list, params});
+export const list = (params) => defHttp.get({ url: Api.list, params });
 
 /**
  * 删除单个
  */
-export const deleteOne = (params,handleSuccess) => {
-  return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
+export const deleteOne = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
     handleSuccess();
   });
-}
+};
 /**
  * 批量删除
  * @param params
@@ -55,17 +54,22 @@ export const batchDelete = (params, handleSuccess) => {
     okText: '确认',
     cancelText: '取消',
     onOk: () => {
-      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+      return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
         handleSuccess();
       });
-    }
+    },
   });
-}
+};
 /**
  * 保存或者更新
  * @param params
  */
 export const saveOrUpdate = (params, isUpdate) => {
-  let url = isUpdate ? Api.edit : Api.save;
-  return defHttp.post({url: url, params});
-}
+  const url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params });
+};
+
+// 查询子表
+export const querySupplyContactsByMainId = (params) => {
+  return defHttp.get({ url: Api.supplyContactsList, params });
+};

+ 20 - 8
src/views/equipmentLifecycle/supplier/list/SupplierManage.data.ts

@@ -10,6 +10,7 @@ export const columns: BasicColumn[] = [
     title: '供应商编号',
     align: 'center',
     dataIndex: 'supplierNumber',
+    slots: { customRender: 'supplierNumber' },
   },
   {
     title: '供应商名称',
@@ -99,7 +100,8 @@ export const formSchema: FormSchema[] = [
     field: 'disable',
     component: 'JSwitch',
     componentProps: {
-      options: ['0', '1'],
+      options: [0, 1],
+      labelOptions: ['禁用', '启用'],
     },
     colProps: { span: 12 },
   },
@@ -130,6 +132,7 @@ export const supplyContactsColumns: JVxeColumn[] = [
     type: JVxeTypes.input,
     placeholder: '请输入${title}',
     defaultValue: '',
+    dataIndex: 'name',
   },
   {
     title: '联系电话',
@@ -137,21 +140,30 @@ export const supplyContactsColumns: JVxeColumn[] = [
     type: JVxeTypes.input,
     placeholder: '请输入${title}',
     defaultValue: '',
+    dataIndex: 'telephone',
+    validateRules: [
+      {
+        // 匹配电话或者手机号
+        pattern: /^(1[3-9]\d{9}|0\d{2,3}-?\d{7,8})$/,
+        message: '请输入正确的联系方式',
+      },
+    ],
   },
   {
     title: '职务',
     key: 'job',
+    dataIndex: 'job',
     type: JVxeTypes.input,
     placeholder: '请输入${title}',
     defaultValue: '',
   },
-  {
-    title: '供应商管理id(外键)',
-    key: 'supplierManageId',
-    type: JVxeTypes.input,
-    placeholder: '请输入${title}',
-    defaultValue: '',
-  },
+  // {
+  //   title: '供应商管理id(外键)',
+  //   key: 'supplierManageId',
+  //   type: JVxeTypes.input,
+  //   placeholder: '请输入${title}',
+  //   defaultValue: '',
+  // },
 ];
 
 // 高级查询数据

+ 101 - 0
src/views/equipmentLifecycle/supplier/list/components/DetailDrawer.vue

@@ -0,0 +1,101 @@
+<template>
+  <BasicDrawer v-bind="$attrs" rootClassName="supplier-dtl-drawer-wrapper" @register="register" title="供应商详情" width="90%">
+    <div class="supplier-wrapper">
+      <div class="dtl-wrapper">
+        <div class="title">基本信息</div>
+        <a-descriptions bordered size="small" :column="2" :labelStyle="{ width: '110px' }">
+          <a-descriptions-item label="供应商编号">{{ info.supplierNumber }}</a-descriptions-item>
+          <a-descriptions-item label="供应商名称">{{ info.supplierName }}</a-descriptions-item>
+
+          <a-descriptions-item label="适用公司">{{ info.applicableCompany }}</a-descriptions-item>
+          <a-descriptions-item label="评级">
+            <a-rate :value="Number(info.grade)" :allowHalf="true" :disabled="true" /> {{ info.grade }}
+          </a-descriptions-item>
+
+          <a-descriptions-item label="官方网站">{{ info.officialWebsite }}</a-descriptions-item>
+          <a-descriptions-item label="是否禁用">
+            <YOrN :yes="Number(info.disable) === 0" />
+          </a-descriptions-item>
+
+          <a-descriptions-item label="地址" :span="2">{{ info.address }}</a-descriptions-item>
+          <a-descriptions-item label="备注" :span="2">{{ info.remark }}</a-descriptions-item>
+        </a-descriptions>
+      </div>
+
+      <div class="dtl-wrapper">
+        <div class="title">联系人信息</div>
+        <BasicTable @register="registerTable" />
+      </div>
+    </div>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import YOrN from '/@/views/equipmentLifecycle/components/YOrN.vue';
+  import { BasicTable, BasicColumn } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { querySupplyContactsByMainId } from '../SupplierManage.api';
+  import { supplyContactsColumns } from '../SupplierManage.data';
+
+  export default defineComponent({
+    components: { BasicDrawer, YOrN, BasicTable },
+    setup() {
+      const info = ref<Recordable>({});
+
+      // 抽屉注册及关闭方法,用于openDrawer方法中
+      // 注册抽屉,用于openDrawer调用
+      const [register, { closeDrawer }] = useDrawerInner((data) => {
+        info.value = data;
+
+        reload();
+      });
+
+      // 注册联系人table数据
+      const { tableContext: tableSubContext } = useListPage({
+        tableProps: {
+          title: '',
+          api: querySupplyContactsByMainId,
+          columns: supplyContactsColumns as BasicColumn[],
+          size: 'small',
+          canResize: false,
+          showIndexColumn: true,
+          showTableSetting: false,
+          showActionColumn: false,
+          immediate: false,
+          beforeFetch: (params) => {
+            return Object.assign(params, { id: info.value.id, queryType: 2 });
+          },
+        },
+      });
+
+      const [registerTable, { reload }] = tableSubContext;
+
+      return { register, closeDrawer, info, registerTable, reload };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .supplier-wrapper {
+    max-width: 1000px;
+
+    .dtl-wrapper {
+      margin-bottom: 10px;
+
+      .title {
+        font-size: 14px;
+        font-weight: bold;
+        margin-bottom: 10px;
+        color: var(--vxe-primary-color);
+      }
+    }
+
+    .jeecg-basic-table {
+      padding: 0;
+
+      :deep(.ant-table-wrapper) {
+        padding: 0;
+      }
+    }
+  }
+</style>

+ 5 - 2
src/views/equipmentLifecycle/supplier/list/components/SupplierManageModal.vue

@@ -35,7 +35,7 @@
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
   import { JVxeTable } from '/@/components/jeecg/JVxeTable';
-  import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts';
+  import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
   import { formSchema, supplyContactsColumns } from '../SupplierManage.data';
   import { saveOrUpdate, supplyContactsList } from '../SupplierManage.api';
   // import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils';
@@ -72,7 +72,10 @@
         ...data.record,
         grade: data.record.grade ? Number(data.record.grade) : 0,
       });
-      requestSubTableData(supplyContactsList, { id: data?.record?.id }, supplyContactsTable);
+      console.log(supplyContacts.value);
+      if (typeof requestSubTableData === 'function') {
+        requestSubTableData(supplyContactsList, { id: data?.record?.id }, supplyContactsTable);
+      }
     }
     // 隐藏底部时禁用整个表单
     setProps({ disabled: !data?.showFooter });

+ 12 - 7
src/views/equipmentLifecycle/supplier/list/index.vue

@@ -41,9 +41,11 @@
       </template>
       <!--字段回显插槽-->
       <!-- <template v-slot:bodyCell="{ column, record, index, text }"> </template> -->
+      <template #supplierNumber="{ record }">
+        <a-button type="link" @click="handleDetail(record)">{{ record.supplierNumber }}</a-button>
+      </template>
       <template #disable="{ record }">
-        <Icon icon="ant-design:check-outlined" class="zgztel-check-icon no-checked" v-if="record.isMeteringDevice === true" />
-        <Icon icon="ant-design:close-outlined" class="zgztel-check-icon checked" v-else />
+        <YOrN :yes="Number(record.disable) === 0" />
       </template>
       <template #grade="{ record }">
         <a-rate :value="Number(record.grade)" :allowHalf="true" :disabled="true" />
@@ -51,6 +53,8 @@
     </BasicTable>
     <!-- 表单区域 -->
     <SupplierManageModal @register="registerModal" @success="handleSuccess" />
+    <!-- 详情 -->
+    <DetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
   </div>
 </template>
 
@@ -62,10 +66,15 @@
   import SupplierManageModal from './components/SupplierManageModal.vue';
   import { columns, searchFormSchema, superQuerySchema } from './SupplierManage.data';
   import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './SupplierManage.api';
+  import DetailDrawer from './components/DetailDrawer.vue';
+  import { useDrawer } from '/@/components/Drawer';
+  import YOrN from '/@/views/equipmentLifecycle/components/YOrN.vue';
 
   const queryParam = reactive<any>({});
   //注册model
   const [registerModal, { openModal }] = useModal();
+  // 注册详情抽屉
+  const [registerDetailDrawer, detailDrawer] = useDrawer();
   //注册table数据
   const { tableContext, onExportXls, onImportXls } = useListPage({
     tableProps: {
@@ -138,11 +147,7 @@
    * 详情
    */
   function handleDetail(record: Recordable) {
-    openModal(true, {
-      record,
-      isUpdate: true,
-      showFooter: false,
-    });
+    detailDrawer.openDrawer(true, record);
   }
   /**
    * 删除事件

+ 24 - 15
src/views/equipmentLifecycle/supplier/plan/PurchasePlan.api.ts

@@ -1,12 +1,12 @@
-import {defHttp} from '/@/utils/http/axios';
-import { useMessage } from "/@/hooks/web/useMessage";
+import { defHttp } from '/@/utils/http/axios';
+import { useMessage } from '/@/hooks/web/useMessage';
 
 const { createConfirm } = useMessage();
 
 enum Api {
   list = '/purchaseManage/purchasePlan/list',
-  save='/purchaseManage/purchasePlan/add',
-  edit='/purchaseManage/purchasePlan/edit',
+  save = '/purchaseManage/purchasePlan/add',
+  edit = '/purchaseManage/purchasePlan/edit',
   deleteOne = '/purchaseManage/purchasePlan/delete',
   deleteBatch = '/purchaseManage/purchasePlan/deleteBatch',
   importExcel = '/purchaseManage/purchasePlan/importExcel',
@@ -38,17 +38,16 @@ export const purchasePlanInfoList = Api.purchasePlanInfoList;
  * 列表接口
  * @param params
  */
-export const list = (params) =>
-  defHttp.get({url: Api.list, params});
+export const list = (params) => defHttp.get({ url: Api.list, params });
 
 /**
  * 删除单个
  */
-export const deleteOne = (params,handleSuccess) => {
-  return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
+export const deleteOne = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
     handleSuccess();
   });
-}
+};
 /**
  * 批量删除
  * @param params
@@ -61,17 +60,27 @@ export const batchDelete = (params, handleSuccess) => {
     okText: '确认',
     cancelText: '取消',
     onOk: () => {
-      return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
+      return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
         handleSuccess();
       });
-    }
+    },
   });
-}
+};
 /**
  * 保存或者更新
  * @param params
  */
 export const saveOrUpdate = (params, isUpdate) => {
-  let url = isUpdate ? Api.edit : Api.save;
-  return defHttp.post({url: url, params});
-}
+  const url = isUpdate ? Api.edit : Api.save;
+  return defHttp.post({ url: url, params });
+};
+
+// 获取附件
+export const getAttachment = (params) => {
+  return defHttp.get({ url: Api.purchaseAttachmentsList, params });
+};
+
+// 获取采购计划信息
+export const getPurchasePlanInfo = (params) => {
+  return defHttp.get({ url: Api.purchasePlanInfoList, params });
+};

+ 257 - 220
src/views/equipmentLifecycle/supplier/plan/PurchasePlan.data.ts

@@ -1,317 +1,354 @@
-import {BasicColumn} from '/@/components/Table';
-import {FormSchema} from '/@/components/Table';
-import { rules} from '/@/utils/helper/validator';
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+// import { rules } from '/@/utils/helper/validator';
 import { render } from '/@/utils/common/renderUtils';
-import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types'
-import { getWeekMonthQuarterYear } from '/@/utils';
+import { JVxeTypes, JVxeColumn } from '/@/components/jeecg/JVxeTable/types';
+import dayjs from 'dayjs';
+
 //列表数据
 export const columns: BasicColumn[] = [
-   {
+  {
     title: '计划编号',
-    align:"center",
-    dataIndex: 'planNumber'
-   },
-   {
+    align: 'center',
+    dataIndex: 'planNumber',
+    slots: { customRender: 'planNumber' },
+  },
+  {
     title: '标题',
-    align:"center",
-    dataIndex: 'title'
-   },
-   {
-    title: '采购类型(1 设备采购  2 备件物料采购)',
-    align:"center",
-    dataIndex: 'purchaseType'
-   },
-   {
+    align: 'center',
+    dataIndex: 'title',
+  },
+  {
+    title: '采购类型',
+    align: 'center',
+    dataIndex: 'purchaseType',
+    customRender: ({ text }) => {
+      return render.renderDictTag(text, 'purchase_type');
+    },
+  },
+  {
     title: '计划采购数量',
-    align:"center",
-    dataIndex: 'planPurchaseNum'
-   },
-   {
+    align: 'center',
+    dataIndex: 'planPurchaseNum',
+  },
+  {
     title: '计划金额',
-    align:"center",
-    dataIndex: 'planAmount'
-   },
-   {
+    align: 'center',
+    dataIndex: 'planAmount',
+  },
+  {
     title: '申请时间',
-    align:"center",
+    align: 'center',
     dataIndex: 'applicationTime',
-    customRender:({text}) =>{
-      text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text);
+    customRender: ({ text }) => {
+      text = !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
       return text;
     },
-   },
-   {
+  },
+  {
     title: '申请人',
-    align:"center",
-    dataIndex: 'applicant'
-   },
-   {
+    align: 'center',
+    dataIndex: 'applicant',
+  },
+  {
     title: '备注',
-    align:"center",
-    dataIndex: 'remark'
-   },
-   {
+    align: 'center',
+    dataIndex: 'remark',
+  },
+  {
     title: '当前节点',
-    align:"center",
-    dataIndex: 'currentNode'
-   },
-   {
+    align: 'center',
+    dataIndex: 'currentNode',
+  },
+  {
     title: '审批状态',
-    align:"center",
-    dataIndex: 'approvalStatus'
-   },
-   {
+    align: 'center',
+    dataIndex: 'approvalStatus',
+    customRender: ({ text }) => {
+      return render.renderDictTag(text, 'approval_status');
+    },
+  },
+  {
     title: '审批结束时间',
-    align:"center",
-    dataIndex: 'approvalEndTime'
-   },
-   {
+    align: 'center',
+    dataIndex: 'approvalEndTime',
+  },
+  {
     title: '采购周期',
-    align:"center",
-    dataIndex: 'purchaseCycle'
-   },
+    align: 'center',
+    dataIndex: 'purchaseCycle',
+  },
 ];
 //查询数据
-export const searchFormSchema: FormSchema[] = [
-];
+export const searchFormSchema: FormSchema[] = [];
 //表单数据
 export const formSchema: FormSchema[] = [
   {
     label: '计划编号',
     field: 'planNumber',
     component: 'Input',
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请输入计划编号' }],
   },
   {
     label: '标题',
     field: 'title',
     component: 'Input',
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请输入计划标题' }],
   },
   {
-    label: '采购类型(1 设备采购  2 备件物料采购)',
+    label: '采购类型',
     field: 'purchaseType',
-    component: 'InputNumber',
+    component: 'JDictSelectTag',
+    componentProps: {
+      dictCode: 'purchase_type',
+    },
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请选择采购类型' }],
   },
   {
     label: '计划采购数量',
     field: 'planPurchaseNum',
     component: 'InputNumber',
+    componentProps: {
+      min: 1,
+    },
+    defaultValue: 1,
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请输入计划采购数量' }],
   },
   {
     label: '计划金额',
     field: 'planAmount',
     component: 'InputNumber',
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请输入计划金额' }],
   },
   {
     label: '申请时间',
     field: 'applicationTime',
     component: 'DatePicker',
-    componentProps:{
-      valueFormat: 'YYYY-MM-DD'
-    },    
+    componentProps: {
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    },
+    defaultValue: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请选择申请时间' }],
   },
   {
     label: '申请人',
     field: 'applicant',
-    component: 'Input',
+    component: 'JSelectUser',
+    componentProps: {
+      maxSelectCount: 1,
+    },
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请选择申请人' }],
   },
   {
-    label: '备注',
-    field: 'remark',
+    label: '采购周期',
+    field: 'purchaseCycle',
     component: 'Input',
+    colProps: { span: 12 },
+    rules: [{ required: true, message: '请输入采购周期' }],
   },
   {
     label: '当前节点',
     field: 'currentNode',
     component: 'Input',
+    colProps: { span: 12 },
   },
   {
     label: '审批状态',
     field: 'approvalStatus',
-    component: 'InputNumber',
+    component: 'JDictSelectTag',
+    componentProps: {
+      dictCode: 'approval_status',
+    },
+    defaultValue: '1',
+    colProps: { span: 12 },
   },
   {
     label: '审批结束时间',
     field: 'approvalEndTime',
     component: 'DatePicker',
     componentProps: {
-       showTime:true,
-       valueFormat: 'YYYY-MM-DD HH:mm:ss'
-     },
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+    },
+    defaultValue: dayjs().add(1, 'month').format('YYYY-MM-DD HH:mm:ss'),
+    colProps: { span: 12 },
   },
   {
-    label: '采购周期',
-    field: 'purchaseCycle',
+    label: '备注',
+    field: 'remark',
+    component: 'InputTextArea',
+  },
+  // TODO 主键隐藏字段,目前写死为ID
+  {
+    label: '',
+    field: 'id',
     component: 'Input',
+    show: false,
   },
-	// TODO 主键隐藏字段,目前写死为ID
-	{
-	  label: '',
-	  field: 'id',
-	  component: 'Input',
-	  show: false
-	},
 ];
 //子表单数据
 //子表表格配置
 export const purchaseAttachmentsColumns: JVxeColumn[] = [
-    {
-      title: '文件地址',
-      key: 'fileAddress',
-      type: JVxeTypes.image,
-      token:true,
-      responseName:"message",
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '采购计划id(外键)',
-      key: 'purchasePlanId',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '文件名称',
-      key: 'fileName',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-  ]
+  {
+    title: '文件地址',
+    key: 'fileAddress',
+    type: JVxeTypes.upload,
+    token: true,
+    action: '/jeecgboot/sys/common/upload',
+    responseName: 'message',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '文件名称',
+    key: 'fileName',
+    type: JVxeTypes.input,
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+];
 export const purchasePlanInfoColumns: JVxeColumn[] = [
-    {
-      title: '编号',
-      key: 'number',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '名称',
-      key: 'name',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '规格型号',
-      key: 'specification',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '数量',
-      key: 'amount',
-      type: JVxeTypes.inputNumber,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '预计单价',
-      key: 'expectedPrice',
-      type: JVxeTypes.inputNumber,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '单位',
-      key: 'unit',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '供应商',
-      key: 'supplier',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '备注',
-      key: 'remark',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '小计',
-      key: 'total',
-      type: JVxeTypes.inputNumber,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-    {
-      title: '采购计划id(外键)',
-      key: 'purchasePlanId',
-      type: JVxeTypes.input,
-      width:"200px",
-      placeholder: '请输入${title}',
-      defaultValue:'',
-    },
-  ]
-
+  {
+    title: '编号',
+    key: 'number',
+    dataIndex: 'number',
+    type: JVxeTypes.input,
+    width: '100px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '名称',
+    key: 'name',
+    dataIndex: 'name',
+    type: JVxeTypes.input,
+    width: '100px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '规格型号',
+    key: 'specification',
+    dataIndex: 'specification',
+    type: JVxeTypes.input,
+    width: '100px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '数量',
+    key: 'amount',
+    dataIndex: 'amount',
+    type: JVxeTypes.inputNumber,
+    width: '60px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '预计单价',
+    key: 'expectedPrice',
+    dataIndex: 'expectedPrice',
+    type: JVxeTypes.inputNumber,
+    width: '100px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '单位',
+    key: 'unit',
+    dataIndex: 'unit',
+    type: JVxeTypes.select,
+    width: '70px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+    allowSearch: true,
+    dictCode: 'unit_type',
+  },
+  {
+    title: '供应商',
+    key: 'supplier',
+    dataIndex: 'supplier',
+    type: JVxeTypes.slot,
+    width: '240px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+    slotName: 'supplier',
+  },
+  {
+    title: '备注',
+    key: 'remark',
+    dataIndex: 'remark',
+    type: JVxeTypes.textarea,
+    width: '200px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+  {
+    title: '小计',
+    key: 'total',
+    dataIndex: 'total',
+    type: JVxeTypes.inputNumber,
+    width: '120px',
+    placeholder: '请输入${title}',
+    defaultValue: '',
+  },
+];
 
 // 高级查询数据
 export const superQuerySchema = {
-  planNumber: {title: '计划编号',order: 0,view: 'text', type: 'string',},
-  title: {title: '标题',order: 1,view: 'text', type: 'string',},
-  purchaseType: {title: '采购类型(1 设备采购  2 备件物料采购)',order: 2,view: 'number', type: 'number',},
-  planPurchaseNum: {title: '计划采购数量',order: 3,view: 'number', type: 'number',},
-  planAmount: {title: '计划金额',order: 4,view: 'number', type: 'number',},
-  applicationTime: {title: '申请时间',order: 5,view: 'date', type: 'string',},
-  applicant: {title: '申请人',order: 6,view: 'text', type: 'string',},
-  remark: {title: '备注',order: 7,view: 'text', type: 'string',},
-  currentNode: {title: '当前节点',order: 8,view: 'text', type: 'string',},
-  approvalStatus: {title: '审批状态',order: 9,view: 'number', type: 'number',},
-  approvalEndTime: {title: '审批结束时间',order: 10,view: 'datetime', type: 'string',},
-  purchaseCycle: {title: '采购周期',order: 11,view: 'text', type: 'string',},
+  planNumber: { title: '计划编号', order: 0, view: 'text', type: 'string' },
+  title: { title: '标题', order: 1, view: 'text', type: 'string' },
+  purchaseType: { title: '采购类型(1 设备采购  2 备件物料采购)', order: 2, view: 'number', type: 'number' },
+  planPurchaseNum: { title: '计划采购数量', order: 3, view: 'number', type: 'number' },
+  planAmount: { title: '计划金额', order: 4, view: 'number', type: 'number' },
+  applicationTime: { title: '申请时间', order: 5, view: 'date', type: 'string' },
+  applicant: { title: '申请人', order: 6, view: 'text', type: 'string' },
+  remark: { title: '备注', order: 7, view: 'text', type: 'string' },
+  currentNode: { title: '当前节点', order: 8, view: 'text', type: 'string' },
+  approvalStatus: { title: '审批状态', order: 9, view: 'number', type: 'number' },
+  approvalEndTime: { title: '审批结束时间', order: 10, view: 'datetime', type: 'string' },
+  purchaseCycle: { title: '采购周期', order: 11, view: 'text', type: 'string' },
   //子表高级查询
   purchaseAttachments: {
     title: '采购计划相关附件',
     view: 'table',
     fields: {
-        fileAddress: {title: '文件地址',order: 0,view: 'image', type: 'string',},
-        purchasePlanId: {title: '采购计划id(外键)',order: 1,view: 'text', type: 'string',},
-        fileName: {title: '文件名称',order: 2,view: 'text', type: 'string',},
-    }
+      fileAddress: { title: '文件地址', order: 0, view: 'image', type: 'string' },
+      purchasePlanId: { title: '采购计划id(外键)', order: 1, view: 'text', type: 'string' },
+      fileName: { title: '文件名称', order: 2, view: 'text', type: 'string' },
+    },
   },
   purchasePlanInfo: {
     title: '采购计划信息',
     view: 'table',
     fields: {
-        number: {title: '编号',order: 0,view: 'text', type: 'string',},
-        name: {title: '名称',order: 1,view: 'text', type: 'string',},
-        specification: {title: '规格型号',order: 2,view: 'text', type: 'string',},
-        amount: {title: '数量',order: 3,view: 'number', type: 'number',},
-        expectedPrice: {title: '预计单价',order: 4,view: 'number', type: 'number',},
-        unit: {title: '单位',order: 5,view: 'text', type: 'string',},
-        supplier: {title: '供应商',order: 6,view: 'text', type: 'string',},
-        remark: {title: '备注',order: 7,view: 'text', type: 'string',},
-        total: {title: '小计',order: 8,view: 'number', type: 'number',},
-        purchasePlanId: {title: '采购计划id(外键)',order: 9,view: 'text', type: 'string',},
-    }
+      number: { title: '编号', order: 0, view: 'text', type: 'string' },
+      name: { title: '名称', order: 1, view: 'text', type: 'string' },
+      specification: { title: '规格型号', order: 2, view: 'text', type: 'string' },
+      amount: { title: '数量', order: 3, view: 'number', type: 'number' },
+      expectedPrice: { title: '预计单价', order: 4, view: 'number', type: 'number' },
+      unit: { title: '单位', order: 5, view: 'text', type: 'string' },
+      supplier: { title: '供应商', order: 6, view: 'text', type: 'string' },
+      remark: { title: '备注', order: 7, view: 'text', type: 'string' },
+      total: { title: '小计', order: 8, view: 'number', type: 'number' },
+      purchasePlanId: { title: '采购计划id(外键)', order: 9, view: 'text', type: 'string' },
+    },
   },
 };
 
 /**
-* 流程表单调用这个方法获取formSchema
-* @param param
-*/
-export function getBpmFormSchema(_formData): FormSchema[]{
-// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
+ * 流程表单调用这个方法获取formSchema
+ * @param param
+ */
+export function getBpmFormSchema(_formData): FormSchema[] {
+  // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
   return formSchema;
-}
+}

+ 0 - 192
src/views/equipmentLifecycle/supplier/plan/PurchasePlanList.vue

@@ -1,192 +0,0 @@
-<template>
-  <div>
-    <!--引用表格-->
-   <BasicTable @register="registerTable" :rowSelection="rowSelection">
-     <!--插槽:table标题-->
-      <template #tableTitle>
-          <a-button type="primary" v-auth="'purchaseManage:sbsmzq_purchase_plan:add'"  @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
-          <a-button  type="primary" v-auth="'purchaseManage:sbsmzq_purchase_plan:exportXls'"  preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
-          <j-upload-button  type="primary" v-auth="'purchaseManage:sbsmzq_purchase_plan:importExcel'"  preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
-          <a-dropdown v-if="selectedRowKeys.length > 0">
-              <template #overlay>
-                <a-menu>
-                  <a-menu-item key="1" @click="batchHandleDelete">
-                    <Icon icon="ant-design:delete-outlined"></Icon>
-                    删除
-                  </a-menu-item>
-                </a-menu>
-              </template>
-              <a-button v-auth="'purchaseManage:sbsmzq_purchase_plan:deleteBatch'">批量操作
-                <Icon icon="mdi:chevron-down"></Icon>
-              </a-button>
-        </a-dropdown>
-        <!-- 高级查询 -->
-        <super-query :config="superQueryConfig" @search="handleSuperQuery" />
-      </template>
-       <!--操作栏-->
-      <template #action="{ record }">
-        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
-      </template>
-      <!--字段回显插槽-->
-      <template v-slot:bodyCell="{ column, record, index, text }">
-      </template>
-    </BasicTable>
-    <!-- 表单区域 -->
-    <PurchasePlanModal @register="registerModal" @success="handleSuccess"></PurchasePlanModal>
-  </div>
-</template>
-
-<script lang="ts" name="purchaseManage-purchasePlan" setup>
-  import {ref, reactive, computed, unref} from 'vue';
-  import {BasicTable, useTable, TableAction} from '/@/components/Table';
-  import { useListPage } from '/@/hooks/system/useListPage'
-  import {useModal} from '/@/components/Modal';
-  import PurchasePlanModal from './components/PurchasePlanModal.vue'
-  import {columns, searchFormSchema, superQuerySchema} from './PurchasePlan.data';
-  import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './PurchasePlan.api';
-  import {downloadFile} from '/@/utils/common/renderUtils';
-  import { useUserStore } from '/@/store/modules/user';
-  const queryParam = reactive<any>({});
-  const checkedKeys = ref<Array<string | number>>([]);
-  const userStore = useUserStore();
-  //注册model
-  const [registerModal, {openModal}] = useModal();
-   //注册table数据
-  const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
-      tableProps:{
-           title: '采购计划',
-           api: list,
-           columns,
-           canResize:false,
-           formConfig: {
-                //labelWidth: 120,
-                schemas: searchFormSchema,
-                autoSubmitOnEnter:true,
-                showAdvancedButton:true,
-                fieldMapToNumber: [
-                ],
-                fieldMapToTime: [
-                ],
-            },
-           actionColumn: {
-               width: 120,
-               fixed:'right'
-           },
-           beforeFetch: (params) => {
-             return Object.assign(params, queryParam);
-           },
-        },
-        exportConfig: {
-            name:"采购计划",
-            url: getExportUrl,
-            params: queryParam,
-        },
-        importConfig: {
-            url: getImportUrl,
-            success: handleSuccess
-        },
-    })
-
-  const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext
-
-  // 高级查询配置
-  const superQueryConfig = reactive(superQuerySchema);
-
-  /**
-   * 高级查询事件
-   */
-  function handleSuperQuery(params) {
-    Object.keys(params).map((k) => {
-      queryParam[k] = params[k];
-    });
-    reload();
-  }
-
-   /**
-    * 新增事件
-    */
-  function handleAdd() {
-     openModal(true, {
-       isUpdate: false,
-       showFooter: true,
-     });
-  }
-   /**
-    * 编辑事件
-    */
-  function handleEdit(record: Recordable) {
-     openModal(true, {
-       record,
-       isUpdate: true,
-       showFooter: true,
-     });
-   }
-   /**
-    * 详情
-   */
-  function handleDetail(record: Recordable) {
-     openModal(true, {
-       record,
-       isUpdate: true,
-       showFooter: false,
-     });
-   }
-   /**
-    * 删除事件
-    */
-  async function handleDelete(record) {
-     await deleteOne({id: record.id}, handleSuccess);
-   }
-   /**
-    * 批量删除事件
-    */
-  async function batchHandleDelete() {
-     await batchDelete({ids: selectedRowKeys.value},handleSuccess);
-   }
-   /**
-    * 成功回调
-    */
-  function handleSuccess() {
-      (selectedRowKeys.value = []) && reload();
-   }
-   /**
-      * 操作栏
-      */
-  function getTableAction(record){
-       return [
-         {
-           label: '编辑',
-           onClick: handleEdit.bind(null, record),
-           auth: 'purchaseManage:sbsmzq_purchase_plan:edit'
-         }
-       ]
-   }
-
-
-  /**
-   * 下拉操作栏
-   */
-  function getDropDownAction(record){
-    return [
-      {
-        label: '详情',
-        onClick: handleDetail.bind(null, record),
-      }, {
-        label: '删除',
-        popConfirm: {
-          title: '是否确认删除',
-          confirm: handleDelete.bind(null, record),
-          placement: 'topLeft'
-        },
-        auth: 'purchaseManage:sbsmzq_purchase_plan:delete'
-      }
-    ]
-  }
-
-</script>
-
-<style lang="less" scoped>
-  :deep(.ant-picker),:deep(.ant-input-number){
-    width: 100%;
-  }
-</style>

+ 126 - 0
src/views/equipmentLifecycle/supplier/plan/components/DetailDrawer.vue

@@ -0,0 +1,126 @@
+<template>
+  <BasicDrawer v-bind="$attrs" rootClassName="supplier-dtl-drawer-wrapper" @register="register" title="采购计划详情" width="90%">
+    <div class="plan-wrapper">
+      <div class="dtl-wrapper" style="max-width: 1000px">
+        <div class="title">申请信息</div>
+        <a-descriptions bordered size="small" :column="2" :labelStyle="{ width: '110px' }">
+          <a-descriptions-item label="计划编号" :span="2">{{ info.planNumber }}</a-descriptions-item>
+          <a-descriptions-item label="申请人">{{ info.applicant }}</a-descriptions-item>
+          <a-descriptions-item label="申请时间">{{ info.applicationTime }}</a-descriptions-item>
+          <a-descriptions-item label="标题" :span="2">{{ info.title }}</a-descriptions-item>
+          <a-descriptions-item label="采购类型">
+            <component :is="render.renderDict(info.purchaseType, 'purchase_type')" />
+          </a-descriptions-item>
+          <a-descriptions-item label="采购周期">{{ info.purchaseCycle }}</a-descriptions-item>
+          <a-descriptions-item label="备注" :span="2">{{ info.remark }}</a-descriptions-item>
+        </a-descriptions>
+      </div>
+
+      <div class="dtl-wrapper">
+        <div class="title">相关附件</div>
+        <!-- <BasicTable @register="registerTable" /> -->
+      </div>
+
+      <div class="dtl-wrapper">
+        <div class="title">计划信息</div>
+        <BasicTable @register="registerTable" />
+      </div>
+
+      <div class="dtl-wrapper">
+        <div class="title">采购申请单</div>
+        <ApplyTableList ref="applyTableContext" :purchasePlanId="info.id" noOperate />
+      </div>
+    </div>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import { BasicTable, BasicColumn } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { getPurchasePlanInfo } from '../PurchasePlan.api';
+  import { purchasePlanInfoColumns } from '../PurchasePlan.data';
+  import ApplyTableList from '../../apply/list.vue';
+  import { render } from '/@/utils/common/renderUtils';
+  import { mapTableTotalSummary } from '/@/utils/common/compUtils';
+
+  export default defineComponent({
+    components: { BasicDrawer, BasicTable, ApplyTableList },
+    setup() {
+      const info = ref<Recordable>({});
+      const applyTableContext = ref();
+
+      // 抽屉注册及关闭方法,用于openDrawer方法中
+      // 注册抽屉,用于openDrawer调用
+      const [register, { closeDrawer }] = useDrawerInner((data) => {
+        info.value = data;
+
+        reload();
+        applyTableContext.value && applyTableContext.value.reload();
+      });
+
+      // 注册联系人table数据
+      const { tableContext: tableSubContext } = useListPage({
+        tableProps: {
+          title: '',
+          api: getPurchasePlanInfo,
+          columns: purchasePlanInfoColumns as BasicColumn[],
+          size: 'small',
+          canResize: false,
+          showIndexColumn: true,
+          showTableSetting: false,
+          showActionColumn: false,
+          immediate: false,
+          beforeFetch: (params) => {
+            return Object.assign(params, { id: info.value.id });
+          },
+          // 显示底部合计
+          showSummary: true,
+          // 底部合计计算方法
+          summaryFunc: (tableData: Recordable[]) => {
+            // 可用工具方法自动计算合计
+            const totals = mapTableTotalSummary(tableData, ['amount', 'total']);
+            return [totals];
+          },
+        },
+      });
+
+      const [registerTable, { reload }] = tableSubContext;
+
+      return { register, closeDrawer, info, registerTable, reload, applyTableContext, render };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .plan-wrapper {
+    max-width: 1450px;
+
+    .dtl-wrapper {
+      margin-bottom: 10px;
+
+      .title {
+        font-size: 14px;
+        font-weight: bold;
+        margin-bottom: 10px;
+        color: var(--vxe-primary-color);
+      }
+
+      :deep(.jeecg-basic-table) {
+        padding: 0;
+
+        .ant-table-wrapper,
+        .ant-table-footer {
+          padding: 0;
+        }
+      }
+    }
+
+    .jeecg-basic-table {
+      padding: 0;
+
+      :deep(.ant-table-wrapper) {
+        padding: 0;
+      }
+    }
+  }
+</style>

+ 128 - 89
src/views/equipmentLifecycle/supplier/plan/components/PurchasePlanModal.vue

@@ -1,6 +1,14 @@
 <template>
-  <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
-    <BasicForm @register="registerForm" ref="formRef" name="PurchasePlanForm"/>
+  <BasicModal
+    v-bind="$attrs"
+    @register="registerModal"
+    destroyOnClose
+    :title="title"
+    :body-style="{ padding: '20px 20px 0' }"
+    :width="1200"
+    @ok="handleSubmit"
+  >
+    <BasicForm @register="registerForm" ref="formRef" name="PurchasePlanForm" />
     <!-- 子表单区域 -->
     <a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs">
       <a-tab-pane tab="采购计划相关附件" key="purchaseAttachments" :forceRender="true">
@@ -16,7 +24,7 @@
           :rowSelection="true"
           :disabled="formDisabled"
           :toolbar="true"
-          />
+        />
       </a-tab-pane>
       <a-tab-pane tab="采购计划信息" key="purchasePlanInfo" :forceRender="true">
         <JVxeTable
@@ -31,103 +39,134 @@
           :rowSelection="true"
           :disabled="formDisabled"
           :toolbar="true"
-          />
+        >
+          <template #supplier="props">
+            <ApiSelect
+              v-model:value="props.row.supplier"
+              :api="supplierList"
+              resultField="records"
+              labelField="supplierName"
+              valueField="id"
+              :showSearch="true"
+              :pageConfig="{
+                isPage: true,
+                //如果和默认的分页字段一致,请忽略以下配置
+                pageField: 'pageNo',
+                pageSizeField: 'pageSize',
+                totalField: 'total',
+                listField: 'records',
+              }"
+              placeholder="请选择供应商"
+            />
+          </template>
+        </JVxeTable>
       </a-tab-pane>
     </a-tabs>
   </BasicModal>
 </template>
 
 <script lang="ts" setup>
-    import {ref, computed, unref,reactive} from 'vue';
-    import {BasicModal, useModalInner} from '/@/components/Modal';
-    import {BasicForm, useForm} from '/@/components/Form/index';
-    import { JVxeTable } from '/@/components/jeecg/JVxeTable'
-    import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
-    import {formSchema,purchaseAttachmentsColumns,purchasePlanInfoColumns} from '../PurchasePlan.data';
-    import {saveOrUpdate,purchaseAttachmentsList,purchasePlanInfoList} from '../PurchasePlan.api';
-    import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
-    // Emits声明
-    const emit = defineEmits(['register','success']);
-    const isUpdate = ref(true);
-    const formDisabled = ref(false);
-    const refKeys = ref(['purchaseAttachments', 'purchasePlanInfo', ]);
-    const activeKey = ref('purchaseAttachments');
-    const purchaseAttachments = ref();
-    const purchasePlanInfo = ref();
-    const tableRefs = {purchaseAttachments, purchasePlanInfo, };
-    const purchaseAttachmentsTable = reactive({
-          loading: false,
-          dataSource: [],
-          columns:purchaseAttachmentsColumns
-    })
-    const purchasePlanInfoTable = reactive({
-          loading: false,
-          dataSource: [],
-          columns:purchasePlanInfoColumns
-    })
-    //表单配置
-    const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
-        labelWidth: 150,
-        schemas: formSchema,
-        showActionButtonGroup: false,
-        baseColProps: {span: 24}
-    });
-     //表单赋值
-    const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
-        //重置表单
-        await reset();
-        setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter});
-        isUpdate.value = !!data?.isUpdate;
-        formDisabled.value = !data?.showFooter;
-        if (unref(isUpdate)) {
-            //表单赋值
-            await setFieldsValue({
-                ...data.record,
-            });
-             requestSubTableData(purchaseAttachmentsList, {id:data?.record?.id}, purchaseAttachmentsTable)
-             requestSubTableData(purchasePlanInfoList, {id:data?.record?.id}, purchasePlanInfoTable)
-        }
-        // 隐藏底部时禁用整个表单
-       setProps({ disabled: !data?.showFooter })
-    });
-    //方法配置
-    const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys);
+  import { ref, computed, unref, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { JVxeTable } from '/@/components/jeecg/JVxeTable';
+  import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
+  import { formSchema, purchaseAttachmentsColumns, purchasePlanInfoColumns } from '../PurchasePlan.data';
+  import { saveOrUpdate, purchaseAttachmentsList, purchasePlanInfoList } from '../PurchasePlan.api';
+  import ApiSelect from '/@/components/Form/src/components/ApiSelect.vue';
+  import { list as supplierList } from '/@/views/equipmentLifecycle/supplier/list/SupplierManage.api';
 
-    //设置标题
-    const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情'));
-
-    async function reset(){
-      await resetFields();
-      activeKey.value = 'purchaseAttachments';
-      purchaseAttachmentsTable.dataSource = [];
-      purchasePlanInfoTable.dataSource = [];
+  // import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils';
+  // Emits声明
+  const emit = defineEmits(['register', 'success']);
+  const isUpdate = ref(true);
+  const formDisabled = ref(false);
+  const refKeys = ref(['purchaseAttachments', 'purchasePlanInfo']);
+  const activeKey = ref('purchaseAttachments');
+  const purchaseAttachments = ref();
+  const purchasePlanInfo = ref();
+  const tableRefs = { purchaseAttachments, purchasePlanInfo };
+  const purchaseAttachmentsTable = reactive({
+    loading: false,
+    dataSource: [],
+    columns: purchaseAttachmentsColumns,
+  });
+  const purchasePlanInfoTable = reactive({
+    loading: false,
+    dataSource: [],
+    columns: purchasePlanInfoColumns,
+  });
+  //表单配置
+  const [registerForm, { setProps, resetFields, setFieldsValue }] = useForm({
+    labelWidth: 110,
+    schemas: formSchema,
+    showActionButtonGroup: false,
+    baseColProps: { span: 24 },
+  });
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    //重置表单
+    await reset();
+    setModalProps({ confirmLoading: false, showCancelBtn: data?.showFooter, showOkBtn: data?.showFooter });
+    isUpdate.value = !!data?.isUpdate;
+    formDisabled.value = !data?.showFooter;
+    if (unref(isUpdate)) {
+      //表单赋值
+      await setFieldsValue({
+        ...data.record,
+      });
+      if (typeof requestSubTableData === 'function') {
+        requestSubTableData(purchaseAttachmentsList, { id: data?.record?.id }, purchaseAttachmentsTable);
+        requestSubTableData(purchasePlanInfoList, { id: data?.record?.id }, purchasePlanInfoTable);
+      }
     }
-    function classifyIntoFormData(allValues) {
-         let main = Object.assign({}, allValues.formValue)
-         return {
-           ...main, // 展开
-           purchaseAttachmentsList: allValues.tablesValue[0].tableData,
-           purchasePlanInfoList: allValues.tablesValue[1].tableData,
-         }
-       }
-    //表单提交事件
-    async function requestAddOrEdit(values) {
-        try {
-            setModalProps({confirmLoading: true});
-            //提交表单
-            await saveOrUpdate(values, isUpdate.value);
-            //关闭弹窗
-            closeModal();
-            //刷新列表
-            emit('success');
-        } finally {
-            setModalProps({confirmLoading: false});
-        }
+    // 隐藏底部时禁用整个表单
+    setProps({ disabled: !data?.showFooter });
+  });
+  //方法配置
+  const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
+    requestAddOrEdit,
+    classifyIntoFormData,
+    tableRefs,
+    activeKey,
+    refKeys
+  );
+
+  //设置标题
+  const title = computed(() => (!unref(isUpdate) ? '新增' : !unref(formDisabled) ? '编辑' : '详情'));
+
+  async function reset() {
+    await resetFields();
+    activeKey.value = 'purchaseAttachments';
+    purchaseAttachmentsTable.dataSource = [];
+    purchasePlanInfoTable.dataSource = [];
+  }
+  function classifyIntoFormData(allValues) {
+    let main = Object.assign({}, allValues.formValue);
+    return {
+      ...main, // 展开
+      purchaseAttachmentsList: allValues.tablesValue[0].tableData,
+      purchasePlanInfoList: allValues.tablesValue[1].tableData,
+    };
+  }
+  //表单提交事件
+  async function requestAddOrEdit(values) {
+    try {
+      setModalProps({ confirmLoading: true });
+      //提交表单
+      await saveOrUpdate(values, isUpdate.value);
+      //关闭弹窗
+      closeModal();
+      //刷新列表
+      emit('success');
+    } finally {
+      setModalProps({ confirmLoading: false });
     }
+  }
 </script>
 
 <style lang="less" scoped>
-	/** 时间和数字输入框样式 */
+  /** 时间和数字输入框样式 */
   :deep(.ant-input-number) {
     width: 100%;
   }
@@ -135,4 +174,4 @@
   :deep(.ant-calendar-picker) {
     width: 100%;
   }
-</style>
+</style>

+ 34 - 0
src/views/equipmentLifecycle/supplier/plan/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <a-tabs v-model:activeKey="activeKey" size="small" type="card">
+    <a-tab-pane key="1" tab="采购计划">
+      <list />
+    </a-tab-pane>
+    <a-tab-pane key="2" tab="与我相关"> 与我相关 </a-tab-pane>
+  </a-tabs>
+</template>
+
+<script lang="ts" name="purchaseManage-purchasePlan" setup>
+  import { ref } from 'vue';
+  import list from './list.vue';
+
+  const activeKey = ref('1');
+</script>
+
+<style lang="less" scoped>
+  .ant-tabs {
+    height: 100%;
+    padding: 10px;
+
+    :deep(.ant-tabs-nav) {
+      margin-bottom: 0;
+    }
+
+    :deep(.ant-tabs-content) {
+      height: 100%;
+    }
+
+    :deep(.jeecg-basic-table) {
+      padding: 10px 0 0;
+    }
+  }
+</style>

+ 201 - 0
src/views/equipmentLifecycle/supplier/plan/list.vue

@@ -0,0 +1,201 @@
+<template>
+  <!--引用表格-->
+  <BasicTable @register="registerTable" :rowSelection="rowSelection">
+    <!--插槽:table标题-->
+    <template #tableTitle>
+      <a-button type="primary" v-auth="'purchaseManage:sbsmzq_purchase_plan:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">
+        新增
+      </a-button>
+      <a-button type="primary" v-auth="'purchaseManage:sbsmzq_purchase_plan:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls">
+        导出
+      </a-button>
+      <j-upload-button
+        type="primary"
+        v-auth="'purchaseManage:sbsmzq_purchase_plan:importExcel'"
+        preIcon="ant-design:import-outlined"
+        @click="onImportXls"
+      >
+        导入
+      </j-upload-button>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <template #overlay>
+          <a-menu>
+            <a-menu-item key="1" @click="batchHandleDelete">
+              <Icon icon="ant-design:delete-outlined" />
+              删除
+            </a-menu-item>
+          </a-menu>
+        </template>
+        <a-button v-auth="'purchaseManage:sbsmzq_purchase_plan:deleteBatch'">
+          批量操作
+          <Icon icon="mdi:chevron-down" />
+        </a-button>
+      </a-dropdown>
+      <!-- 高级查询 -->
+      <super-query :config="superQueryConfig" @search="handleSuperQuery" />
+    </template>
+    <!--操作栏-->
+    <template #action="{ record }">
+      <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+    </template>
+    <!--字段回显插槽-->
+    <!-- <template v-slot:bodyCell="{ column, record, index, text }"> </template> -->
+    <template #planNumber="{ record }">
+      <a-button type="link" @click="handleDetail(record)">{{ record.planNumber }}</a-button>
+    </template>
+  </BasicTable>
+  <!-- 表单区域 -->
+  <PurchasePlanModal @register="registerModal" @success="handleSuccess" />
+  <!-- 详情 -->
+  <DetailDrawer @register="registerDetailDrawer" @success="handleSuccess" />
+</template>
+
+<script lang="ts" name="purchaseManage-purchasePlan" setup>
+  import { reactive } from 'vue';
+  import { BasicTable, TableAction } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { useModal } from '/@/components/Modal';
+  import PurchasePlanModal from './components/PurchasePlanModal.vue';
+  import { columns, searchFormSchema, superQuerySchema } from './PurchasePlan.data';
+  import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './PurchasePlan.api';
+  import DetailDrawer from './components/DetailDrawer.vue';
+  import { useDrawer } from '/@/components/Drawer';
+
+  const queryParam = reactive<any>({});
+  //注册model
+  const [registerModal, { openModal }] = useModal();
+  // 注册详情抽屉
+  const [registerDetailDrawer, detailDrawer] = useDrawer();
+  //注册table数据
+  const { tableContext, onExportXls, onImportXls } = useListPage({
+    tableProps: {
+      title: '采购计划',
+      api: list,
+      columns,
+      canResize: false,
+      formConfig: {
+        //labelWidth: 120,
+        schemas: searchFormSchema,
+        autoSubmitOnEnter: true,
+        showAdvancedButton: true,
+        fieldMapToNumber: [],
+        fieldMapToTime: [],
+      },
+      actionColumn: {
+        width: 120,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return Object.assign(params, queryParam);
+      },
+    },
+    exportConfig: {
+      name: '采购计划',
+      url: getExportUrl,
+      params: queryParam,
+    },
+    importConfig: {
+      url: getImportUrl,
+      success: handleSuccess,
+    },
+  });
+
+  const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
+
+  // 高级查询配置
+  const superQueryConfig = reactive(superQuerySchema);
+
+  /**
+   * 高级查询事件
+   */
+  function handleSuperQuery(params) {
+    Object.keys(params).map((k) => {
+      queryParam[k] = params[k];
+    });
+    reload();
+  }
+
+  /**
+   * 新增事件
+   */
+  function handleAdd() {
+    openModal(true, {
+      isUpdate: false,
+      showFooter: true,
+    });
+  }
+  /**
+   * 编辑事件
+   */
+  function handleEdit(record: Recordable) {
+    openModal(true, {
+      record,
+      isUpdate: true,
+      showFooter: true,
+    });
+  }
+  /**
+   * 详情
+   */
+  function handleDetail(record: Recordable) {
+    detailDrawer.openDrawer(true, record);
+  }
+  /**
+   * 删除事件
+   */
+  async function handleDelete(record) {
+    await deleteOne({ id: record.id }, handleSuccess);
+  }
+  /**
+   * 批量删除事件
+   */
+  async function batchHandleDelete() {
+    await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
+  }
+  /**
+   * 成功回调
+   */
+  function handleSuccess() {
+    (selectedRowKeys.value = []) && reload();
+  }
+  /**
+   * 操作栏
+   */
+  function getTableAction(record) {
+    return [
+      {
+        label: '编辑',
+        onClick: handleEdit.bind(null, record),
+        auth: 'purchaseManage:sbsmzq_purchase_plan:edit',
+      },
+    ];
+  }
+
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [
+      {
+        label: '详情',
+        onClick: handleDetail.bind(null, record),
+      },
+      {
+        label: '删除',
+        popConfirm: {
+          title: '是否确认删除',
+          confirm: handleDelete.bind(null, record),
+          placement: 'topLeft',
+        },
+        auth: 'purchaseManage:sbsmzq_purchase_plan:delete',
+      },
+    ];
+  }
+</script>
+
+<style lang="less" scoped>
+  :deep(.ant-picker),
+  :deep(.ant-input-number) {
+    width: 100%;
+  }
+</style>