Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| febbcb3241 | |||
| 94cd3f867d | |||
| 6ee935ccb6 | |||
| 321c3fce49 | 
| @ -5,7 +5,7 @@ VITE_APP_TITLE = 新能源场站智慧运维平台 | ||||
| VITE_APP_ENV = 'development' | ||||
|  | ||||
| # 开发环境 | ||||
| VITE_APP_BASE_API = 'http://192.168.110.210:18899' | ||||
| VITE_APP_BASE_API = 'http://192.168.110.149:18899' | ||||
|  | ||||
| # 应用访问路径 例如使用前缀 /admin/ | ||||
| VITE_APP_CONTEXT_PATH = '/' | ||||
|  | ||||
| @ -61,3 +61,16 @@ export const delBeipinBeijian = (id: string | number | Array<string | number>) = | ||||
|     method: 'delete' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 运维-物资-备件-查询总览 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const chuRuKuTotal = (data:any): AxiosPromise<any> => { | ||||
|   return request({ | ||||
|     url: '/ops/beipinBeijian/getCount', | ||||
|     method: 'get', | ||||
|     params: data | ||||
|   }); | ||||
| }; | ||||
| @ -54,3 +54,45 @@ export const caigouPlanDetail = (id: string | number): AxiosPromise<CaigouPlanVO | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * 更新运维-物资-采购计划单 | ||||
|  * @param data | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const updateCaigouPlan = (data: CaigouPlanForm): AxiosPromise<CaigouPlanVO> => { | ||||
|   return request({ | ||||
|     url: '/ops/caigouPlan', | ||||
|     method: 'put', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| // /** | ||||
| //  * 查询运维-物资-采购计划单年度金额 | ||||
| //  * @param query | ||||
| //  * @returns {*} | ||||
| //  */ | ||||
| // export const getJinE = (query?: CaigouPlanQuery): AxiosPromise<any> => { | ||||
| //   return request({ | ||||
| //     url: '/ops/caigouPlan/getJinE', | ||||
| //     method: 'get', | ||||
| //     params: query | ||||
| //   }); | ||||
| // }; | ||||
|  | ||||
| /** | ||||
|  * 查询运维-物资-采购计划单年度金额 | ||||
|  * @param id | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const getCount = (id: string | number): AxiosPromise<CaigouPlanVO> => { | ||||
|   return request({ | ||||
|     url: '/ops/caigouPlan/getJinE', | ||||
|     method: 'get', | ||||
|     params: { | ||||
|       projectId: id | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| @ -178,6 +178,18 @@ export interface CaigouPlanVO { | ||||
|      * 采购申请计划文件 查询 | ||||
|      */ | ||||
|     opsCaigouPlanFilesVos?: Array<any>; | ||||
|     /** | ||||
|      * 申请原因 | ||||
|      */ | ||||
|     reason?: string; | ||||
|     /** | ||||
|      * 供应商名称 | ||||
|      */ | ||||
|     gonyingshangName?: string; | ||||
|     /** | ||||
|      * 设备类型 | ||||
|      */ | ||||
|     shebeiType?: string; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -360,8 +372,18 @@ export interface CaigouPlanForm extends BaseEntity { | ||||
|      * 出货时间 | ||||
|      */ | ||||
|     chouhuoTime?: string; | ||||
|     | ||||
|  | ||||
|     /** | ||||
|      * 申请原因 | ||||
|      */ | ||||
|     reason?: string; | ||||
|     /** | ||||
|      * 供应商名称 | ||||
|      */ | ||||
|     gonyingshangName?: string; | ||||
|     /** | ||||
|      * 设备类型 | ||||
|      */ | ||||
|     shebeiType?: string; | ||||
| } | ||||
|  | ||||
| export interface CaigouPlanQuery extends PageQuery { | ||||
| @ -545,6 +567,18 @@ export interface CaigouPlanQuery extends PageQuery { | ||||
|      * 出货时间 | ||||
|      */ | ||||
|     chouhuoTime?: string; | ||||
|      /** | ||||
|      * 申请原因 | ||||
|      */ | ||||
|     reason?: string; | ||||
|     /** | ||||
|      * 供应商名称 | ||||
|      */ | ||||
|     gonyingshangName?: string; | ||||
|     /** | ||||
|      * 设备类型 | ||||
|      */ | ||||
|     shebeiType?: string; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -62,15 +62,43 @@ export const delChurukudan = (id: string | number | Array<string | number>) => { | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 运维-物资-出入库单折现图 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const getChuRuKuCountLine = (data:any): AxiosPromise<any> => { | ||||
|   return request({ | ||||
|     url: '/ops/churukudan/getChuRuKuDayCount', | ||||
|     method: 'get', | ||||
|     params: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 运维-物资-出入库单柱状图 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const getChuRuKuCountBar = (data:any): AxiosPromise<any> => { | ||||
| export const getChuRuKuDayCountBar = (data:any): AxiosPromise<any> => { | ||||
|   return request({ | ||||
|     url: '/ops/churukudan/getChuRuKuCount', | ||||
|     method: 'get', | ||||
|     params: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 运维-物资-出入库单-查询产品名称列表 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
| export const getChanpinLists = (data:any): AxiosPromise<any> => { | ||||
|   return request({ | ||||
|     url: '/ops/caigouPlan/getChanpinList', | ||||
|     method: 'get', | ||||
|     params: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -47,6 +47,18 @@ export interface ChurukudanVO { | ||||
|    */ | ||||
|   danjvType: string; | ||||
|  | ||||
|   /** | ||||
|    * 审核状态 | ||||
|    */ | ||||
|   auditStatus?: string; | ||||
|   /** | ||||
|    * 产品名称 | ||||
|    */ | ||||
|   chanpinName?: string; | ||||
|   /** | ||||
|    * 产品id | ||||
|    */ | ||||
|   chanpinId?: string | number; | ||||
| } | ||||
|  | ||||
| export interface ChurukudanForm extends BaseEntity { | ||||
| @ -102,6 +114,14 @@ export interface ChurukudanForm extends BaseEntity { | ||||
|    * 审核状态 | ||||
|    */ | ||||
|   auditStatus?: string; | ||||
|   /** | ||||
|    * 产品名称 | ||||
|    */ | ||||
|   chanpinName?: string; | ||||
|   /** | ||||
|    * 产品id | ||||
|    */ | ||||
|   chanpinId?: string | number; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -139,11 +159,18 @@ export interface ChurukudanQuery extends PageQuery { | ||||
|    * 开始日期 | ||||
|    */ | ||||
|   startDate?: string; | ||||
|    | ||||
|   /** | ||||
|    * 产品名称 | ||||
|    */ | ||||
|   chanpinName?: string; | ||||
|   /** | ||||
|    * 结束日期 | ||||
|    */ | ||||
|   endDate?: string; | ||||
|   /** | ||||
|    * 产品id | ||||
|    */ | ||||
|   chanpinId?: string | number; | ||||
|     /** | ||||
|      * 日期范围参数 | ||||
|      */ | ||||
|  | ||||
| @ -1,5 +1,16 @@ | ||||
| <template> | ||||
|   <div class="upload-file"> | ||||
|      <!-- 文件列表 --> | ||||
|     <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> | ||||
|       <li v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content"> | ||||
|         <el-link :href="`${file.url}`" :underline="false" target="_blank"> | ||||
|           <span class="el-icon-document"> {{ getFileName(file.name) }} </span> | ||||
|         </el-link> | ||||
|         <div class="ele-upload-list__item-content-action"> | ||||
|           <el-button type="danger" v-if="!disabled" link @click="handleDelete(index)">删除</el-button> | ||||
|         </div> | ||||
|       </li> | ||||
|     </transition-group> | ||||
|     <el-upload | ||||
|       ref="fileUploadRef" | ||||
|       multiple | ||||
| @ -37,17 +48,6 @@ | ||||
|       </template> | ||||
|       的文件 | ||||
|     </div> | ||||
|     <!-- 文件列表 --> | ||||
|     <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> | ||||
|       <li v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content"> | ||||
|         <el-link :href="`${file.url}`" :underline="false" target="_blank"> | ||||
|           <span class="el-icon-document"> {{ getFileName(file.name) }} </span> | ||||
|         </el-link> | ||||
|         <div class="ele-upload-list__item-content-action"> | ||||
|           <el-button type="danger" v-if="!disabled" link @click="handleDelete(index)">删除</el-button> | ||||
|         </div> | ||||
|       </li> | ||||
|     </transition-group> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @ -55,7 +55,7 @@ | ||||
| import { propTypes } from '@/utils/propTypes'; | ||||
| import { delOss, listByIds } from '@/api/system/oss'; | ||||
| import { globalHeaders } from '@/utils/request'; | ||||
|  | ||||
| import { ref } from 'vue'; | ||||
| const props = defineProps({ | ||||
|   modelValue: { | ||||
|     type: [String, Object, Array], | ||||
| @ -89,7 +89,6 @@ const showTip = computed(() => props.isShowTip && (props.fileType || props.fileS | ||||
|  | ||||
| const fileUploadRef = ref<ElUploadInstance>(); | ||||
|  | ||||
|  | ||||
| // 监听 fileType 变化,更新 fileAccept | ||||
| const fileAccept = computed(() => props.fileType.map((type) => `.${type}`).join(',')); | ||||
|  | ||||
| @ -200,7 +199,6 @@ const uploadedSuccessfully = () => { | ||||
|     uploadList.value = []; | ||||
|     number.value = 0; | ||||
|     emit('update:modelValue', listToString(fileList.value)); | ||||
|     emit('update:fileList', fileList.value); | ||||
|     proxy?.$modal.closeLoading(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @ -2,9 +2,11 @@ | ||||
|   <section class="app-main"> | ||||
|     <router-view v-slot="{ Component, route }"> | ||||
|       <transition :enter-active-class="animate" mode="out-in"> | ||||
|         <keep-alive :include="tagsViewStore.cachedViews"> | ||||
|         <div> | ||||
|           <keep-alive :include="tagsViewStore.cachedViews"> | ||||
|           <component :is="Component" v-if="!route.meta.link" :key="route.path" /> | ||||
|         </keep-alive> | ||||
|         </div> | ||||
|       </transition> | ||||
|     </router-view> | ||||
|     <iframe-toggle /> | ||||
|  | ||||
| @ -70,11 +70,18 @@ export const useProcurementDraftStore = defineStore('procurementDraft', () => { | ||||
|     return false; | ||||
|   }; | ||||
|  | ||||
|   // 清除所有草稿 | ||||
|   const clearAllDrafts = (): void => { | ||||
|     draftList.value = []; | ||||
|     saveDraftsToStorage(draftList.value); | ||||
|   }; | ||||
|  | ||||
|   return { | ||||
|     draftList, | ||||
|     saveDraft, | ||||
|     getDraftList, | ||||
|     getDraft, | ||||
|     deleteDraft | ||||
|     deleteDraft, | ||||
|     clearAllDrafts | ||||
|   }; | ||||
| }); | ||||
| @ -2,7 +2,7 @@ | ||||
|     <div class="manage-form-container"> | ||||
|         <!-- 搜索和筛选区域 --> | ||||
|         <div class="search-filter-section"> | ||||
|             <el-row gutter="12" align="middle"> | ||||
|             <el-row :gutter="12" align="middle"> | ||||
|                 <el-col :span="2"> | ||||
|                     <el-select v-model="searchForm.deviceType" placeholder="设备类型" clearable> | ||||
|                         <el-option label="全部类型" value="" /> | ||||
|  | ||||
| @ -19,9 +19,29 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup> | ||||
| import { ref, onMounted, onUnmounted } from 'vue'; | ||||
| import { ref, onMounted, onUnmounted, watch, computed } from 'vue'; | ||||
| import * as echarts from 'echarts'; | ||||
|  | ||||
| // 定义props | ||||
| const props = defineProps({ | ||||
|     lineData: { | ||||
|         type: Object, | ||||
|         default: () => ({ | ||||
|             days: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], | ||||
|             rukuCounnts: [5, 40, 20, 75, 60, 80, 40, 55, 30, 65, 5, 80], | ||||
|             chukuCounnts: [30, 40, 30, 30, 30, 15, 55, 50, 40, 60, 25, 90] | ||||
|         }) | ||||
|     }, | ||||
|     barData: { | ||||
|         type: Object, | ||||
|         default: () => ({ | ||||
|             shebeiTypes: ['光伏组件', '逆变器', '汇流箱', '支架', '电缆'], | ||||
|             rukuCount: [5, 40, 20, 75, 60], | ||||
|             chukuCount: [30, 40, 30, 30, 30] | ||||
|         }) | ||||
|     } | ||||
| }); | ||||
|  | ||||
| // 图表容器引用 | ||||
| const lineChartRef = ref(null); | ||||
| const barChartRef = ref(null); | ||||
| @ -30,6 +50,53 @@ const barChartRef = ref(null); | ||||
| let lineChart = null; | ||||
| let barChart = null; | ||||
|  | ||||
| // 计算属性:处理传入的lineData,确保数据有效 | ||||
| const processedLineData = computed(() => { | ||||
|     // 检查传入的数据是否有效 | ||||
|     if (!props.lineData ||  | ||||
|         !props.lineData.days ||  | ||||
|         props.lineData.days.length === 0 || | ||||
|         !Array.isArray(props.lineData.rukuCounnts) || | ||||
|         !Array.isArray(props.lineData.chukuCounnts)) { | ||||
|         return { | ||||
|             days: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], | ||||
|             rukuCounnts: [5, 40, 20, 75, 60, 80, 40, 55, 30, 65, 5, 80], | ||||
|             chukuCounnts: [30, 40, 30, 30, 30, 15, 55, 50, 40, 60, 25, 90] | ||||
|         }; | ||||
|     } | ||||
|      | ||||
|     // 检查rukuCounnts和chukuCounnts是否全为0 | ||||
|     const isRukuAllZero = props.lineData.rukuCounnts.every(item => item === 0); | ||||
|     const isChukuAllZero = props.lineData.chukuCounnts.every(item => item === 0); | ||||
|      | ||||
|     if (isRukuAllZero && isChukuAllZero) { | ||||
|         return { | ||||
|             days: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], | ||||
|             rukuCounnts: [5, 40, 20, 75, 60, 80, 40, 55, 30, 65, 5, 80], | ||||
|             chukuCounnts: [30, 40, 30, 30, 30, 15, 55, 50, 40, 60, 25, 90] | ||||
|         }; | ||||
|     } | ||||
|      | ||||
|     return props.lineData; | ||||
| }); | ||||
|  | ||||
| // 计算属性:处理传入的barData,确保数据有效 | ||||
| const processedBarData = computed(() => { | ||||
|     // 检查传入的数据是否有效 | ||||
|     if (!props.barData ||  | ||||
|         !props.barData.shebeiTypes ||  | ||||
|         props.barData.shebeiTypes.length === 0 || | ||||
|         !Array.isArray(props.barData.rukuCount) || | ||||
|         !Array.isArray(props.barData.chukuCount)) { | ||||
|         return { | ||||
|             shebeiTypes: ['光伏组件', '逆变器', '汇流箱', '支架', '电缆'], | ||||
|             rukuCount: [5, 40, 20, 75, 60], | ||||
|             chukuCount: [30, 40, 30, 30, 30] | ||||
|         }; | ||||
|     } | ||||
|     return props.barData; | ||||
| }); | ||||
|  | ||||
| onMounted(() => { | ||||
|     // 初始化折线图 | ||||
|     initLineChart(); | ||||
| @ -77,7 +144,7 @@ const initLineChart = () => { | ||||
|             }, | ||||
|             xAxis: { | ||||
|                 type: 'category', | ||||
|                 data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] | ||||
|                 data: processedLineData.value.days | ||||
|             }, | ||||
|             yAxis: { | ||||
|                 type: 'value' | ||||
| @ -86,7 +153,7 @@ const initLineChart = () => { | ||||
|                 { | ||||
|                     name: '入库数量', | ||||
|                     type: 'line', | ||||
|                     data: [5, 40, 20, 75, 60, 80, 40, 55, 30, 65, 5, 80], | ||||
|                     data: processedLineData.value.rukuCounnts, | ||||
|                     symbol: 'none', | ||||
|                     smooth: true, | ||||
|                     lineStyle: { | ||||
| @ -105,7 +172,7 @@ const initLineChart = () => { | ||||
|                 { | ||||
|                     name: '出库数量', | ||||
|                     type: 'line', | ||||
|                     data: [30, 40, 30, 30, 30, 15, 55, 50, 40, 60, 25, 90], | ||||
|                     data: processedLineData.value.chukuCounnts, | ||||
|                     symbol: 'none', | ||||
|                     smooth: true, | ||||
|                     lineStyle: { | ||||
| @ -155,7 +222,7 @@ const initBarChart = () => { | ||||
|             }, | ||||
|             xAxis: { | ||||
|                 type: 'category', | ||||
|                 data: ['电器部件', '机械部件', '电子元件', '控制模块', '结构部件', '其他'], | ||||
|                 data: processedBarData.value.shebeiTypes, | ||||
|                 axisLabel: { | ||||
|                     interval: 0, // 强制显示所有标签 | ||||
|                     rotate: 30, // 标签旋转30度 | ||||
| @ -171,7 +238,7 @@ const initBarChart = () => { | ||||
|                 { | ||||
|                     name: '入库数量', | ||||
|                     type: 'bar', | ||||
|                     data: [650, 480, 510, 280, 650, 220], | ||||
|                     data: processedBarData.value.rukuCount, | ||||
|                     itemStyle: { | ||||
|                         color: 'rgba(22, 93, 255, 1)' // 入库数量颜色 | ||||
|                     }, | ||||
| @ -182,7 +249,7 @@ const initBarChart = () => { | ||||
|                 { | ||||
|                     name: '出库数量', | ||||
|                     type: 'bar', | ||||
|                     data: [850, 400, 770, 590, 540, 310], | ||||
|                     data: processedBarData.value.chukuCount, | ||||
|                     itemStyle: { | ||||
|                         color: 'rgba(15, 198, 194, 1)' // 出库数量颜色 | ||||
|                     }, | ||||
| @ -205,6 +272,12 @@ const handleResize = () => { | ||||
|         barChart.resize(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| // 监听数据变化,更新图表 | ||||
| watch([() => props.lineData, () => props.barData], () => { | ||||
|     initLineChart(); | ||||
|     initBarChart(); | ||||
| }, { deep: true }); | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
|  | ||||
| @ -1,84 +1,37 @@ | ||||
| <template> | ||||
|     <div class="approval-form"> | ||||
|         <!-- 基础信息 --> | ||||
|         <el-card class="card" shadow="hover"> | ||||
|             <template #header> | ||||
|                 <h3>基础信息</h3> | ||||
|             </template> | ||||
|             <el-form :model="detailInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="采购单号"> | ||||
|                             <el-input v-model="detailInfo.id" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="创建时间"> | ||||
|                             <el-input v-model="detailInfo.createTime" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="经办人"> | ||||
|                             <el-input v-model="detailInfo.jingbanrenName" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="所属部门"> | ||||
|                             <el-select v-model="detailInfo.caigouDanweiName" placeholder="请选择"> | ||||
|                                 <el-option label="运维部" value="运维部" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="采购类型"> | ||||
|                             <el-select v-model="detailInfo.caigouType" placeholder="请选择"> | ||||
|                                 <el-option label="项目业务" value="项目业务" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|                 <el-form-item label="申请原因"> | ||||
|                     <el-input v-model="basicInfo.applyReason" type="textarea" :rows="2" placeholder="请输入申请原因" /> | ||||
|                 </el-form-item> | ||||
|             </el-form> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <el-descriptions title="基础信息" direction="vertical" :column="3" border size="large" class="infoClass"> | ||||
|                 <el-descriptions-item label="采购单编号">{{ props.detailInfo.id }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="创建时间">{{ props.detailInfo.createTime }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="经办人">{{ props.detailInfo.jingbanrenName }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="所属部门">{{ props.detailInfo.caigouDanweiName }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="采购类型">{{ getTagLabel(wz_purchase_type, props.detailInfo.caigouType) | ||||
|                     }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="申请原因">{{ props.detailInfo.reason }}</el-descriptions-item> | ||||
|             </el-descriptions> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 供应商信息 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>供应商信息</h3> | ||||
|             </template> | ||||
|             <el-form :model="detailInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="供应商单位"> | ||||
|                             <el-select v-model="detailInfo.gonyingshangId" placeholder="请选择"> | ||||
|                                 <el-option label="AAAA精密仪器制造有限公司" value="AAAA精密仪器制造有限公司" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="出货时间"> | ||||
|                             <el-select v-model="detailInfo.chouhuoTime" placeholder="请选择"> | ||||
|                                 <el-option label="2年零4个月" value="2年零4个月" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|             </el-form> | ||||
|             <el-descriptions title="供应商信息" direction="vertical" :column="2" border size="large"> | ||||
|                 <el-descriptions-item label="供应商单位">{{ props.detailInfo.gonyingshangName }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="出货时间">{{ props.detailInfo.chuhuoTime }}</el-descriptions-item> | ||||
|             </el-descriptions> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 产品信息 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>产品信息</h3> | ||||
|             </template> | ||||
|             <el-table :data="detailInfo.opsCaigouPlanChanpinVos" border style="width: 100%"> | ||||
|             <div slot="header" class="infoTitle">产品信息</div> | ||||
|             <el-table :data="props.detailInfo.opsCaigouPlanChanpinVos || []" border style="width: 100%"> | ||||
|                 <el-table-column prop="chanpinName" label="产品名称" /> | ||||
|                 <el-table-column prop="chanpinType" label="产品型号" /> | ||||
|                 <el-table-column prop="chanpinMonovalent" label="产品单价" align="center" :cell-style="{ background: 'pink' }" /> | ||||
|                 <el-table-column prop="shebeiType" label="设备类型"> | ||||
|                     <template #default="scope"> | ||||
|                         {{ getTagLabel(wz_device_type, scope.row.shebeiType) }} | ||||
|                     </template> | ||||
|                 </el-table-column> | ||||
|                 <el-table-column prop="chanpinMonovalent" label="产品单价" align="center" | ||||
|                     :cell-style="{ background: 'pink' }" /> | ||||
|                 <el-table-column prop="goumaiNumber" label="购买数量" align="center" :cell-style="{ background: 'pink' }" /> | ||||
|                 <el-table-column prop="yontu" label="用途" /> | ||||
|                 <el-table-column prop="totalPrice" label="合计" /> | ||||
| @ -87,163 +40,89 @@ | ||||
|  | ||||
|         <!-- 合同条款 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>合同条款</h3> | ||||
|             </template> | ||||
|             <el-form :model="contractInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="付款条件"> | ||||
|                             <el-select v-model="detailInfo.fukuantiaojian" placeholder="请选择"> | ||||
|                                 <el-option label="银行卡" value="银行卡" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="发票开具方式"> | ||||
|                             <el-select v-model="detailInfo.fapiaoKjfs" placeholder="请选择"> | ||||
|                                 <el-option label="请选择" value="请选择" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|             </el-form> | ||||
|             <el-descriptions title="合同条款" direction="vertical" :column="3" border size="large"> | ||||
|                 <el-descriptions-item label="付款条件">{{ getTagLabel(wz_payment_terms, props.detailInfo.fukuantiaojian) | ||||
|                     }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="发票开具方式">{{ getTagLabel(wz_invoicing_way, props.detailInfo.fapiaoKjfs) | ||||
|                     }}</el-descriptions-item> | ||||
|                 <el-descriptions-item label="合同类型">{{ | ||||
|                     getTagLabel(wz_contract_type, props.detailInfo.hetonType) }}</el-descriptions-item> | ||||
|             </el-descriptions> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 附件 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>附件</h3> | ||||
|             </template> | ||||
|             <el-upload class="upload-demo" action="#" :file-list="fileList" :auto-upload="false" | ||||
|                 :on-preview="handlePreview"> | ||||
|                 <el-table :data="fileList" border style="width: 100%"> | ||||
|                     <el-table-column prop="name" label="文件名" width="300" /> | ||||
|                     <el-table-column prop="size" label="大小" width="100" /> | ||||
|                     <el-table-column label="操作" width="100"> | ||||
|                         <template #default="scope"> | ||||
|                             <!-- <el-link type="primary" @click="handlePreview(scope.row)"> --> | ||||
|                             <el-link type="primary"> | ||||
|                                 预览 | ||||
|                             </el-link> | ||||
|                         </template> | ||||
|                     </el-table-column> | ||||
|                 </el-table> | ||||
|             </el-upload> | ||||
|             <div slot="header" class="infoTitle">附件</div> | ||||
|  | ||||
|             <el-table :data="props.detailInfo.opsCaigouPlanFilesVos || []" border> | ||||
|                 <el-table-column prop="fileName" label="文件名" width="300" /> | ||||
|                 <el-table-column label="文件类型" width="200"> | ||||
|                     <template #default="scope"> | ||||
|                         {{ getFileType(scope.row.fileName) }} | ||||
|                     </template> | ||||
|                 </el-table-column> | ||||
|                 <el-table-column label="操作" width="200"> | ||||
|                     <template #default="scope"> | ||||
|                         <el-link type="primary" @click="handlePreview(scope.row)"> | ||||
|                             预览 | ||||
|                         </el-link> | ||||
|                     </template> | ||||
|                 </el-table-column> | ||||
|             </el-table> | ||||
|         </el-card> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted, getCurrentInstance, toRefs } from 'vue'; | ||||
| import { useRoute } from 'vue-router'; | ||||
| import { ref, computed, onMounted, getCurrentInstance, toRefs } from 'vue'; | ||||
| import { defineProps } from 'vue'; | ||||
| import type { ComponentInternalInstance } from 'vue'; | ||||
| const route = useRoute(); | ||||
| import type { CaigouPlanVO } from '@/api/wuziguanli/caigouPlan/types'; | ||||
|  | ||||
| // 定义props | ||||
| const props = defineProps<{ | ||||
|     detailInfo: CaigouPlanVO | ||||
| }>(); | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| const { wz_invoicing_way, wz_payment_terms, wz_purchase_type, wz_contract_type, wz_caigou_examine } = toRefs<any>(proxy?.useDict('wz_invoicing_way', 'wz_payment_terms', 'wz_purchase_type', 'wz_contract_type', 'wz_caigou_examine')); | ||||
| const { wz_invoicing_way, wz_payment_terms, wz_purchase_type, wz_contract_type, wz_device_type } = toRefs<any>(proxy?.useDict('wz_device_type','wz_invoicing_way', 'wz_payment_terms', 'wz_purchase_type', 'wz_contract_type', 'wz_caigou_examine', 'wz_device_type')); | ||||
|  | ||||
| import { caigouPlanDetail } from '@/api/wuziguanli/caigouPlan'; | ||||
| import { CaigouPlanVO, CaigouPlanQuery, CaigouPlanForm } from '@/api/wuziguanli/caigouPlan/types'; | ||||
|  | ||||
| // 存储计划详情数据 | ||||
| const detailInfo = ref<CaigouPlanVO>({} as CaigouPlanVO); | ||||
|  | ||||
| // 存储计划编号 | ||||
| const id = ref(''); | ||||
|  | ||||
| const getDetailInfo = async () => { | ||||
|     const res = await caigouPlanDetail(id.value); | ||||
|     if (res.code === 200) { | ||||
|        detailInfo.value = res.data; | ||||
|        console.log(detailInfo.value); | ||||
|         | ||||
|     } | ||||
| // 根据字典数组和值获取标签文本 | ||||
| const getTagLabel = (dictArray: any[], value: any): string => { | ||||
|     if (!dictArray || !value) return ''; | ||||
|     const item = dictArray.find(item => item.value === value); | ||||
|     return item?.label || value; | ||||
| } | ||||
| onMounted(() => { | ||||
|     // 接收路由参数 | ||||
|     id.value = route.query.id as string; | ||||
|     getDetailInfo(); | ||||
|  | ||||
|  | ||||
|  | ||||
| }); | ||||
| // 基础信息数据 | ||||
| const basicInfo = ref({ | ||||
|     orderNo: '0035455', | ||||
|     createTime: '2023-11-02 16:32', | ||||
|     handler: '李四', | ||||
|     dept: '运维部', | ||||
|     purchaseType: '项目业务', | ||||
|     applyReason: | ||||
|         '随着业务拓展,光伏电站业务负责增加,现有设备已运行5年,部分出现效率下降情况。为保证电站正常运行,计划采购一批新的逆变器替换老旧设备,并补充备件库存。', | ||||
| }); | ||||
|  | ||||
| // 供应商信息数据 | ||||
| const supplierInfo = ref({ | ||||
|     supplierName: 'AAAA精密仪器制造有限公司', | ||||
|     deliveryTime: '2年零4个月', | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 产品信息数据 | ||||
| const productInfo = ref({ | ||||
|     tableData: [ | ||||
|         { | ||||
|             productName: 'AAABBBCCC', | ||||
|             productModel: '15-42', | ||||
|             productPrice: 500, | ||||
|             buyQuantity: 10, | ||||
|             usage: '组件', | ||||
|             total: 5000, | ||||
|         }, | ||||
|     ], | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 合同条款数据 | ||||
| const contractInfo = ref({ | ||||
|     paymentCondition: '银行卡', | ||||
|     invoiceWay: '请选择', | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 附件数据 | ||||
| const fileList = ref([ | ||||
|     { | ||||
|         name: 'MWwwwww.jpg', | ||||
|         size: '30kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '231234124w.zip', | ||||
|         size: '50kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '12451asdas.doc', | ||||
|         size: '80kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '21seasda.xls', | ||||
|         size: '29kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '12kjaklskw.png', | ||||
|         size: '16kb', | ||||
|         url: '', | ||||
|     }, | ||||
| ]); | ||||
| // 获取文件类型(后缀名) | ||||
| const getFileType = (fileName: string): string => { | ||||
|     if (!fileName) return ''; | ||||
|     const lastDotIndex = fileName.lastIndexOf('.'); | ||||
|     if (lastDotIndex === -1) return ''; | ||||
|     return fileName.substring(lastDotIndex + 1).toLowerCase(); | ||||
| }; | ||||
|  | ||||
| // 预览文件 | ||||
| const handlePreview = (file) => { | ||||
|     console.log('预览文件:', file); | ||||
|     // 实际场景可在这里处理文件预览逻辑,如打开新窗口等 | ||||
|     window.open(file.fileUrl, '_blank'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .infoTitle { | ||||
|     font-size: 16px; | ||||
|     font-weight: bold; | ||||
|     margin-bottom: 20px; | ||||
| } | ||||
|  | ||||
| .approval-form { | ||||
|     padding: 20px; | ||||
| } | ||||
| @ -258,7 +137,7 @@ const handlePreview = (file) => { | ||||
|     margin-top: 5px; | ||||
| } | ||||
|  | ||||
| ::v-deep(.el-input__inner) { | ||||
| :v-deep(.el-input__inner) { | ||||
|     color: red; | ||||
| } | ||||
| </style> | ||||
| @ -1,261 +0,0 @@ | ||||
| <template> | ||||
|     <div class="approval-form"> | ||||
|         <!-- 基础信息 --> | ||||
|         <el-card class="card" shadow="hover"> | ||||
|             <template #header> | ||||
|                 <h3>基础信息</h3> | ||||
|             </template> | ||||
|             <el-form :model="basicInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="订单编号"> | ||||
|                             <el-input v-model="basicInfo.orderNo" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="创建时间"> | ||||
|                             <el-input v-model="basicInfo.createTime" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="8"> | ||||
|                         <el-form-item label="经办人"> | ||||
|                             <el-input v-model="basicInfo.handler" disabled /> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="所属部门"> | ||||
|                             <el-select v-model="basicInfo.dept" placeholder="请选择"> | ||||
|                                 <el-option label="运维部" value="运维部" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="采购类型"> | ||||
|                             <el-select v-model="basicInfo.purchaseType" placeholder="请选择"> | ||||
|                                 <el-option label="项目业务" value="项目业务" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|                 <el-form-item label="申请原因"> | ||||
|                     <el-input v-model="basicInfo.applyReason" type="textarea" :rows="2" placeholder="请输入申请原因" /> | ||||
|                 </el-form-item> | ||||
|             </el-form> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 供应商信息 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>供应商信息</h3> | ||||
|             </template> | ||||
|             <el-form :model="supplierInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="供应商单位"> | ||||
|                             <el-select v-model="supplierInfo.supplierName" placeholder="请选择"> | ||||
|                                 <el-option label="AAAA精密仪器制造有限公司" value="AAAA精密仪器制造有限公司" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="出货时间"> | ||||
|                             <el-select v-model="supplierInfo.deliveryTime" placeholder="请选择"> | ||||
|                                 <el-option label="2年零4个月" value="2年零4个月" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|             </el-form> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 产品信息 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>产品信息</h3> | ||||
|             </template> | ||||
|             <el-table :data="productInfo.tableData" border style="width: 100%"> | ||||
|                 <el-table-column prop="productName" label="产品名称" /> | ||||
|                 <el-table-column prop="productModel" label="产品型号" /> | ||||
|                 <el-table-column prop="productPrice" label="产品单价" align="center" :cell-style="{ background: 'pink' }" /> | ||||
|                 <el-table-column prop="buyQuantity" label="购买数量" align="center" :cell-style="{ background: 'pink' }" /> | ||||
|                 <el-table-column prop="usage" label="用途" /> | ||||
|                 <el-table-column prop="total" label="合计" /> | ||||
|             </el-table> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 合同条款 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>合同条款</h3> | ||||
|             </template> | ||||
|             <el-form :model="contractInfo" label-width="120px"> | ||||
|                 <el-row :gutter="20"> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="付款条件"> | ||||
|                             <el-select v-model="contractInfo.paymentCondition" placeholder="请选择"> | ||||
|                                 <el-option label="银行卡" value="银行卡" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                     <el-col :span="12"> | ||||
|                         <el-form-item label="发票开具方式"> | ||||
|                             <el-select v-model="contractInfo.invoiceWay" placeholder="请选择"> | ||||
|                                 <el-option label="请选择" value="请选择" /> | ||||
|                             </el-select> | ||||
|                         </el-form-item> | ||||
|                     </el-col> | ||||
|                 </el-row> | ||||
|             </el-form> | ||||
|         </el-card> | ||||
|  | ||||
|         <!-- 附件 --> | ||||
|         <el-card class="card" shadow="hover" style="margin-top: 20px"> | ||||
|             <template #header> | ||||
|                 <h3>附件</h3> | ||||
|             </template> | ||||
|             <el-upload class="upload-demo" action="#" :file-list="fileList" :auto-upload="false" | ||||
|                 :on-preview="handlePreview"> | ||||
|                 <el-table :data="fileList" border style="width: 100%"> | ||||
|                     <el-table-column prop="name" label="文件名" width="300" /> | ||||
|                     <el-table-column prop="size" label="大小" width="100" /> | ||||
|                     <el-table-column label="操作" width="100"> | ||||
|                         <template #default="scope"> | ||||
|                             <!-- <el-link type="primary" @click="handlePreview(scope.row)"> --> | ||||
|                             <el-link type="primary"> | ||||
|                                 预览 | ||||
|                             </el-link> | ||||
|                         </template> | ||||
|                     </el-table-column> | ||||
|                 </el-table> | ||||
|             </el-upload> | ||||
|         </el-card> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted, getCurrentInstance, toRefs } from 'vue'; | ||||
| import { useRoute } from 'vue-router'; | ||||
| import type { ComponentInternalInstance } from 'vue'; | ||||
| const route = useRoute(); | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| const { wz_invoicing_way, wz_payment_terms, wz_purchase_type, wz_contract_type, wz_caigou_examine } = toRefs<any>(proxy?.useDict('wz_invoicing_way', 'wz_payment_terms', 'wz_purchase_type', 'wz_contract_type', 'wz_caigou_examine')); | ||||
|  | ||||
| import { caigouPlanDetail } from '@/api/wuziguanli/caigouPlan'; | ||||
| import { CaigouPlanVO, CaigouPlanQuery, CaigouPlanForm } from '@/api/wuziguanli/caigouPlan/types'; | ||||
|  | ||||
|  | ||||
| // 存储计划编号 | ||||
| const id = ref(''); | ||||
|  | ||||
| const getDetailInfo = async () => { | ||||
|     const res = await caigouPlanDetail(id.value); | ||||
|     if (res.code === 200) { | ||||
|        console.log(res); | ||||
|         | ||||
|     } | ||||
| } | ||||
| onMounted(() => { | ||||
|     // 接收路由参数 | ||||
|     id.value = route.query.id as string; | ||||
|     getDetailInfo(); | ||||
|  | ||||
|  | ||||
|  | ||||
| }); | ||||
| // 基础信息数据 | ||||
| const basicInfo = ref({ | ||||
|     orderNo: '0035455', | ||||
|     createTime: '2023-11-02 16:32', | ||||
|     handler: '李四', | ||||
|     dept: '运维部', | ||||
|     purchaseType: '项目业务', | ||||
|     applyReason: | ||||
|         '随着业务拓展,光伏电站业务负责增加,现有设备已运行5年,部分出现效率下降情况。为保证电站正常运行,计划采购一批新的逆变器替换老旧设备,并补充备件库存。', | ||||
| }); | ||||
|  | ||||
| // 供应商信息数据 | ||||
| const supplierInfo = ref({ | ||||
|     supplierName: 'AAAA精密仪器制造有限公司', | ||||
|     deliveryTime: '2年零4个月', | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 产品信息数据 | ||||
| const productInfo = ref({ | ||||
|     tableData: [ | ||||
|         { | ||||
|             productName: 'AAABBBCCC', | ||||
|             productModel: '15-42', | ||||
|             productPrice: 500, | ||||
|             buyQuantity: 10, | ||||
|             usage: '组件', | ||||
|             total: 5000, | ||||
|         }, | ||||
|     ], | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 合同条款数据 | ||||
| const contractInfo = ref({ | ||||
|     paymentCondition: '银行卡', | ||||
|     invoiceWay: '请选择', | ||||
|     remark: '', | ||||
| }); | ||||
|  | ||||
| // 附件数据 | ||||
| const fileList = ref([ | ||||
|     { | ||||
|         name: 'MWwwwww.jpg', | ||||
|         size: '30kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '231234124w.zip', | ||||
|         size: '50kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '12451asdas.doc', | ||||
|         size: '80kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '21seasda.xls', | ||||
|         size: '29kb', | ||||
|         url: '', | ||||
|     }, | ||||
|     { | ||||
|         name: '12kjaklskw.png', | ||||
|         size: '16kb', | ||||
|         url: '', | ||||
|     }, | ||||
| ]); | ||||
|  | ||||
| // 预览文件 | ||||
| const handlePreview = (file) => { | ||||
|     console.log('预览文件:', file); | ||||
|     // 实际场景可在这里处理文件预览逻辑,如打开新窗口等 | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .approval-form { | ||||
|     padding: 20px; | ||||
| } | ||||
|  | ||||
| .card { | ||||
|     border-radius: 8px; | ||||
| } | ||||
|  | ||||
| .error-tip { | ||||
|     color: red; | ||||
|     font-size: 12px; | ||||
|     margin-top: 5px; | ||||
| } | ||||
|  | ||||
| ::v-deep(.el-input__inner) { | ||||
|     color: red; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										278
									
								
								src/views/materialManagement/components/upload.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								src/views/materialManagement/components/upload.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,278 @@ | ||||
| <template> | ||||
|   <div class="upload-file"> | ||||
|      <!-- 文件列表 --> | ||||
|     <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> | ||||
|       <li v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content"> | ||||
|         <el-link :href="`${file.url}`" :underline="false" target="_blank"> | ||||
|           <span class="el-icon-document"> {{ getFileName(file.name) }} </span> | ||||
|         </el-link> | ||||
|         <div class="ele-upload-list__item-content-action"> | ||||
|           <el-button type="danger" v-if="!disabled" link @click="handleDelete(index)">删除</el-button> | ||||
|         </div> | ||||
|       </li> | ||||
|     </transition-group> | ||||
|     <el-upload | ||||
|       ref="fileUploadRef" | ||||
|       multiple | ||||
|       :drag="isDrag" | ||||
|       :action="uploadFileUrl" | ||||
|       :before-upload="handleBeforeUpload" | ||||
|       :file-list="fileList" | ||||
|       :limit="limit" | ||||
|       :accept="fileAccept" | ||||
|       :on-error="handleUploadError" | ||||
|       :on-exceed="handleExceed" | ||||
|       :on-success="handleUploadSuccess" | ||||
|       :show-file-list="false" | ||||
|       :headers="headers" | ||||
|       class="upload-file-uploader" | ||||
|       v-if="!disabled" | ||||
|     > | ||||
|       <!-- 上传按钮 --> | ||||
|       <el-button type="primary" v-if="!isDrag">选取文件</el-button> | ||||
|       <div v-else> | ||||
|         <el-icon class="el-icon--upload"><upload-filled /></el-icon> | ||||
|         <div class="el-upload__text"> | ||||
|           拖拽文件到此处,或 <em>点击上传</em> | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-upload> | ||||
|     <!-- 上传提示 --> | ||||
|     <div v-if="showTip && !disabled" class="el-upload__tip"> | ||||
|       请上传 | ||||
|       <template v-if="fileSize"> | ||||
|         大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> | ||||
|       </template> | ||||
|       <template v-if="fileType"> | ||||
|         格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b> | ||||
|       </template> | ||||
|       的文件 | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { propTypes } from '@/utils/propTypes'; | ||||
| import { delOss, listByIds } from '@/api/system/oss'; | ||||
| import { globalHeaders } from '@/utils/request'; | ||||
| import { ref } from 'vue'; | ||||
| const props = defineProps({ | ||||
|   modelValue: { | ||||
|     type: [String, Object, Array], | ||||
|     default: () => [] | ||||
|   }, | ||||
|   // 数量限制 | ||||
|   limit: propTypes.number.def(5), | ||||
|   // 大小限制(MB) | ||||
|   fileSize: propTypes.number.def(5), | ||||
|   // 文件类型, 例如['png', 'jpg', 'jpeg'] | ||||
|   fileType: propTypes.array.def(['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']), | ||||
|   // 是否显示提示 | ||||
|   isShowTip: propTypes.bool.def(true), | ||||
|   // 禁用组件(仅查看文件) | ||||
|   disabled: propTypes.bool.def(false), | ||||
|   // 是否开启拖拽上传 | ||||
|   isDrag: propTypes.bool.def(false) | ||||
| }); | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| const emit = defineEmits(['update:modelValue', 'update:fileList']); | ||||
| const number = ref(0); | ||||
| const uploadList = ref<any[]>([]); | ||||
|  | ||||
| const baseUrl = import.meta.env.VITE_APP_BASE_API; | ||||
| const uploadFileUrl = ref(baseUrl + '/resource/oss/upload'); // 上传文件服务器地址 | ||||
| const headers = ref(globalHeaders()); | ||||
|  | ||||
| const fileList = ref<any[]>([]); | ||||
| const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize)); | ||||
|  | ||||
| const fileUploadRef = ref<ElUploadInstance>(); | ||||
|  | ||||
| // 暴露方法给父组件 | ||||
| defineExpose({ | ||||
|   // 清空所有文件 | ||||
|   clearAllFiles: () => { | ||||
|     fileList.value = []; | ||||
|     emit('update:modelValue', ''); | ||||
|     emit('update:fileList', []); | ||||
|   } | ||||
| }); | ||||
|  | ||||
|  | ||||
| // 监听 fileType 变化,更新 fileAccept | ||||
| const fileAccept = computed(() => props.fileType.map((type) => `.${type}`).join(',')); | ||||
|  | ||||
| watch( | ||||
|   () => props.modelValue, | ||||
|   async (val) => { | ||||
|     if (val) { | ||||
|       let temp = 1; | ||||
|       // 首先将值转为数组 | ||||
|       let list: any[] = []; | ||||
|        | ||||
|       if (Array.isArray(val)) { | ||||
|         // 如果是数组,检查第一个元素的格式 | ||||
|         if (val.length > 0 && val[0].fileName && val[0].fileId && val[0].fileUrl) { | ||||
|           // 处理后端返回的格式 [{fileName,fileId,fileUrl}] | ||||
|           list = val.map(item => ({ | ||||
|             name: item.fileName, | ||||
|             url: item.fileUrl, | ||||
|             ossId: item.fileId | ||||
|           })); | ||||
|         } else { | ||||
|           // 处理组件内部格式 [{name,url,ossId}] | ||||
|           list = val; | ||||
|         } | ||||
|       } else { | ||||
|         // 处理字符串格式(逗号分隔的ossId) | ||||
|         const res = await listByIds(val); | ||||
|         list = res.data.map((oss) => { | ||||
|           return { name: oss.originalName, url: oss.url, ossId: oss.ossId }; | ||||
|         }); | ||||
|       } | ||||
|        | ||||
|       // 然后将数组转为对象数组 | ||||
|       fileList.value = list.map((item) => { | ||||
|         item = { name: item.name, url: item.url, ossId: item.ossId }; | ||||
|         item.uid = item.uid || new Date().getTime() + temp++; | ||||
|         return item; | ||||
|       }); | ||||
|     } else { | ||||
|       fileList.value = []; | ||||
|       return []; | ||||
|     } | ||||
|   }, | ||||
|   { deep: true, immediate: true } | ||||
| ); | ||||
|  | ||||
| // 上传前校检格式和大小 | ||||
| const handleBeforeUpload = (file: any) => { | ||||
|   // 校检文件类型 | ||||
|   if (props.fileType.length) { | ||||
|     const fileName = file.name.split('.'); | ||||
|     const fileExt = fileName[fileName.length - 1]; | ||||
|     const isTypeOk = props.fileType.indexOf(fileExt) >= 0; | ||||
|     if (!isTypeOk) { | ||||
|       proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`); | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|   // 校检文件名是否包含特殊字符 | ||||
|   if (file.name.includes(',')) { | ||||
|     proxy?.$modal.msgError('文件名不正确,不能包含英文逗号!'); | ||||
|     return false; | ||||
|   } | ||||
|   // 校检文件大小 | ||||
|   if (props.fileSize) { | ||||
|     const isLt = file.size / 1024 / 1024 < props.fileSize; | ||||
|     if (!isLt) { | ||||
|       proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`); | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|   proxy?.$modal.loading('正在上传文件,请稍候...'); | ||||
|   number.value++; | ||||
|   return true; | ||||
| }; | ||||
|  | ||||
| // 文件个数超出 | ||||
| const handleExceed = () => { | ||||
|   proxy?.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`); | ||||
| }; | ||||
|  | ||||
| // 上传失败 | ||||
| const handleUploadError = () => { | ||||
|   proxy?.$modal.msgError('上传文件失败'); | ||||
| }; | ||||
|  | ||||
| // 上传成功回调 | ||||
| const handleUploadSuccess = (res: any, file: UploadFile) => { | ||||
|   if (res.code === 200) { | ||||
|     uploadList.value.push({ | ||||
|       name: res.data.fileName, | ||||
|       url: res.data.url, | ||||
|       ossId: res.data.ossId | ||||
|     }); | ||||
|      | ||||
|     uploadedSuccessfully(); | ||||
|   } else { | ||||
|     number.value--; | ||||
|     proxy?.$modal.closeLoading(); | ||||
|     proxy?.$modal.msgError(res.msg); | ||||
|     fileUploadRef.value?.handleRemove(file); | ||||
|     uploadedSuccessfully(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 删除文件 | ||||
| const handleDelete = (index: number) => { | ||||
|   const ossId = fileList.value[index].ossId; | ||||
|   delOss(ossId); | ||||
|   fileList.value.splice(index, 1); | ||||
|    | ||||
|   // 转换为后端需要的格式 [{fileName,fileId,fileUrl}] | ||||
|   const formattedList = fileList.value.map(file => ({ | ||||
|     fileName: file.name, | ||||
|     fileId: file.ossId, | ||||
|     fileUrl: file.url | ||||
|   })); | ||||
|    | ||||
|   emit('update:modelValue', formattedList); | ||||
| }; | ||||
|  | ||||
| // 上传结束处理 | ||||
| const uploadedSuccessfully = () => { | ||||
|   if (number.value > 0 && uploadList.value.length === number.value) { | ||||
|     fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value); | ||||
|     uploadList.value = []; | ||||
|     number.value = 0; | ||||
|      | ||||
|     // 转换为后端需要的格式 [{fileName,fileId,fileUrl}] | ||||
|     const formattedList = fileList.value.map(file => ({ | ||||
|       fileName: file.name, | ||||
|       fileId: file.ossId, | ||||
|       fileUrl: file.url | ||||
|     })); | ||||
|      | ||||
|     emit('update:modelValue', formattedList); | ||||
|     emit('update:fileList', fileList.value); | ||||
|     proxy?.$modal.closeLoading(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 获取文件名称 | ||||
| const getFileName = (name: string) => { | ||||
|   // 如果是url那么取最后的名字 如果不是直接返回 | ||||
|   if (name.lastIndexOf('/') > -1) { | ||||
|     return name.slice(name.lastIndexOf('/') + 1); | ||||
|   } else { | ||||
|     return name; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .upload-file-uploader { | ||||
|   margin-bottom: 5px; | ||||
| } | ||||
|  | ||||
| .upload-file-list .el-upload-list__item { | ||||
|   border: 1px solid #e4e7ed; | ||||
|   line-height: 2; | ||||
|   margin-bottom: 10px; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .upload-file-list .ele-upload-list__item-content { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|   align-items: center; | ||||
|   color: inherit; | ||||
| } | ||||
|  | ||||
| .ele-upload-list__item-content-action .el-link { | ||||
|   margin-right: 10px; | ||||
| } | ||||
| </style> | ||||
| @ -8,8 +8,8 @@ | ||||
|                         <div class="top"> | ||||
|                             <div class="title">单据列表</div> | ||||
|                             <div class="button-actions"> | ||||
|                                 <button :class="{ active: type === 'chuku' }" @click="changeType('chuku')">出库单</button> | ||||
|                                 <button :class="{ active: type === 'ruku' }" @click="changeType('ruku')">入库单</button> | ||||
|                                 <button :class="{ active: type === 'chuku' }" @click="changeType('chuku')">出库单</button> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="content" style="height: 100%;flex: 1;"> | ||||
| @ -23,20 +23,20 @@ | ||||
|                                                 <el-input v-model="queryParams.danjvNumber" placeholder="请输入单据编号" | ||||
|                                                     clearable @keyup.enter="handleQuery" /> | ||||
|                                             </el-form-item> | ||||
|                                             <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                                             <!-- <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                                                 <el-select v-model="queryParams.shebeiType" placeholder="请选择设备类型" | ||||
|                                                     clearable> | ||||
|                                                     <el-option v-for="dict in wz_device_type" :key="dict.value" | ||||
|                                                         :label="dict.label" :value="dict.value" /> | ||||
|                                                 </el-select> | ||||
|                                             </el-form-item> | ||||
|                                             <el-form-item label="审核状态" prop="auditStatus"> | ||||
|                                             </el-form-item> --> | ||||
|                                             <!-- <el-form-item label="审核状态" prop="auditStatus"> | ||||
|                                                 <el-select v-model="queryParams.auditStatus" placeholder="请选择审核状态" | ||||
|                                                     clearable> | ||||
|                                                     <el-option v-for="dict in shenheStatus" :key="dict.value" | ||||
|                                                         :label="dict.label" :value="dict.value" /> | ||||
|                                                 </el-select> | ||||
|                                             </el-form-item> | ||||
|                                             </el-form-item> --> | ||||
|                                             <el-form-item label="开始日期" prop="startDate"> | ||||
|                                                 <el-date-picker v-model="queryParams.startDate" type="date" | ||||
|                                                     placeholder="请选择开始日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" | ||||
| @ -63,21 +63,17 @@ | ||||
|                             <el-table v-loading="loading" border :data="churukudanList" | ||||
|                                 style="width: 100%;margin-top: 15px;"> | ||||
|                                 <el-table-column label="单据编号" align="center" prop="danjvNumber" /> | ||||
|                                 <el-table-column label="设备类型" align="center" prop="shebeiType"> | ||||
|                                     <template #default="scope"> | ||||
|                                         <span>{{ getTagLabel(wz_device_type, scope.row.shebeiType) }}</span> | ||||
|                                     </template> | ||||
|                                 </el-table-column> | ||||
|                                 <el-table-column label="经手人" align="center" prop="jingshourenName" /> | ||||
|                                 <el-table-column label="产品名称" align="center" prop="chanpinName"></el-table-column> | ||||
|                                 <el-table-column label="经手人" align="center" prop="jingshourenName" width="80px" /> | ||||
|                                 <el-table-column label="操作时间" align="center" prop="updateTime" /> | ||||
|                                 <el-table-column label="总数量" align="center" prop="zonNumber" width="80px" /> | ||||
|                                 <el-table-column label="审核状态" align="center" prop="shenheStatus"> | ||||
|                                 <!-- <el-table-column label="审核状态" align="center" prop="shenheStatus"> | ||||
|                                     <template #default="scope"> | ||||
|                                         <el-tag :type="getTagType(shenheStatus, scope.row.shenheStatus)" as="span"> | ||||
|                                             {{ getTagLabel(shenheStatus, scope.row.shenheStatus) }} | ||||
|                                         </el-tag> | ||||
|                                     </template> | ||||
|                                 </el-table-column> | ||||
|                                 </el-table-column> --> | ||||
|                                 <el-table-column label="单据类型" align="center" prop="danjvType"> | ||||
|                                     <template #default="scope"> | ||||
|                                         <el-tag :type="getTagType(danjvType, scope.row.danjvType)"> | ||||
| @ -87,8 +83,8 @@ | ||||
|                                 </el-table-column> | ||||
|                                 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|                                     <template #default="scope"> | ||||
|                                         <el-button link type="primary" @click="handleUpdate(scope.row)" | ||||
|                                             v-hasPermi="['personnel:churukudan:edit']">修改</el-button> | ||||
|                                         <!-- <el-button link type="primary" @click="handleUpdate(scope.row)" | ||||
|                                             v-hasPermi="['personnel:churukudan:edit']">修改</el-button> --> | ||||
|                                         <el-button link type="primary" @click="handleDetail(scope.row)" | ||||
|                                             v-hasPermi="['personnel:churukudan:query']">详情</el-button> | ||||
|                                         <el-button link type="primary" @click="handleDelete(scope.row)" | ||||
| @ -118,7 +114,7 @@ | ||||
|                     <div class="item-box"> | ||||
|                         <div class="title">数据分析</div> | ||||
|                         <div class="content"> | ||||
|                             <DataAnalysis /> | ||||
|                             <DataAnalysis :lineData="lineData" :barData="barData" /> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </el-card> | ||||
| @ -133,14 +129,17 @@ | ||||
|                             :value="dict.value"></el-option> | ||||
|                     </el-select> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="单据编号" prop="danjvNumber"> | ||||
|                     <el-input v-model="form.danjvNumber" placeholder="请输入单据编号" /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                 <!-- <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                     <el-select v-model="form.shebeiType" placeholder="请选择设备类型"> | ||||
|                         <el-option v-for="dict in wz_device_type" :key="dict.value" :label="dict.label" | ||||
|                             :value="dict.value"></el-option> | ||||
|                     </el-select> | ||||
|                 </el-form-item> --> | ||||
|                 <el-form-item label="产品名称" prop="chanpinName"> | ||||
|                     <el-select v-model="form.chanpinName" placeholder="请选择产品名称"> | ||||
|                         <el-option v-for="dict in chanpinSelect" :key="dict.value" :label="dict.label" | ||||
|                             :value="dict.value"></el-option> | ||||
|                     </el-select> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="经手人id" prop="jingshourenId"> | ||||
|                     <el-input v-model="form.jingshourenId" placeholder="请输入经手人id" /> | ||||
| @ -152,7 +151,7 @@ | ||||
|                     <el-input v-model="form.contactNumber" placeholder="请输入联系电话" /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="总数量" prop="zonNumber"> | ||||
|                     <el-input v-model="form.zonNumber" placeholder="请输入总数量" /> | ||||
|                     <el-input v-model="form.zonNumber" placeholder="请输入总数量" type="number" min="0"/> | ||||
|                 </el-form-item> | ||||
|             </el-form> | ||||
|             <template #footer> | ||||
| @ -316,7 +315,7 @@ | ||||
|     padding: 12px 0; | ||||
| } | ||||
|  | ||||
| ::v-deep(.el-card__body) { | ||||
| :v-deep(.el-card__body) { | ||||
|     height: 100%; | ||||
| } | ||||
| </style> | ||||
| @ -325,7 +324,7 @@ import SystemInfo from './components/SystemInfo.vue'; | ||||
| import DataAnalysis from './components/DataAnalysis.vue'; | ||||
| import { ref, computed } from 'vue'; | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| import { listChurukudan, getChurukudan, delChurukudan, addChurukudan, updateChurukudan, getChuRuKuCountBar } from '@/api/wuziguanli/churuku/index'; | ||||
| import { listChurukudan, getChurukudan, delChurukudan, addChurukudan, updateChurukudan, getChuRuKuCountLine, getChuRuKuDayCountBar, getChanpinLists } from '@/api/wuziguanli/churuku/index'; | ||||
| import { ChurukudanVO, ChurukudanQuery, ChurukudanForm } from '@/api/wuziguanli/churuku/types'; | ||||
| const { wz_device_type } = toRefs<any>(proxy?.useDict('wz_device_type')); | ||||
|  | ||||
| @ -342,8 +341,8 @@ const loading = ref(true); | ||||
| const showSearch = ref(true); | ||||
| const ids = ref<Array<string | number>>([]); | ||||
| const total = ref(0); | ||||
| // 单据类型切换变量 - 默认出库单 | ||||
| const type = ref<string>('chuku'); | ||||
| // 单据类型切换变量 - 默认入库单 | ||||
| const type = ref<string>('ruku'); | ||||
|  | ||||
| /** 切换单据类型 */ | ||||
| const changeType = (newType: string) => { | ||||
| @ -427,6 +426,8 @@ const initFormData: ChurukudanForm = { | ||||
|     danjvType: undefined, | ||||
|     updateTime: undefined, | ||||
|     auditStatus: undefined, | ||||
|     chanpinName: undefined, | ||||
|     chanpinId: undefined, | ||||
| } | ||||
| const data = reactive<PageData<ChurukudanForm, ChurukudanQuery>>({ | ||||
|     form: { ...initFormData }, | ||||
| @ -440,13 +441,18 @@ const data = reactive<PageData<ChurukudanForm, ChurukudanQuery>>({ | ||||
|         startDate: undefined, | ||||
|         endDate: undefined, | ||||
|         auditStatus: undefined, | ||||
|         danjvType: '1', // 默认显示出库单 | ||||
|         chanpinName: undefined, | ||||
|         chanpinId: undefined, | ||||
|         danjvType: '2', // 默认显示入库单 | ||||
|         params: { | ||||
|         } | ||||
|     }, | ||||
|     rules: { | ||||
|         shebeiType: [ | ||||
|             { required: true, message: "设备类型不能为空", trigger: "change" } | ||||
|         // shebeiType: [ | ||||
|         //     { required: true, message: "设备类型不能为空", trigger: "change" } | ||||
|         // ], | ||||
|         chanpinName: [ | ||||
|             { required: true, message: "产品名称不能为空", trigger: "change" } | ||||
|         ], | ||||
|         jingshourenId: [ | ||||
|             { required: true, message: "经手人id不能为空", trigger: "blur" } | ||||
| @ -460,10 +466,34 @@ const data = reactive<PageData<ChurukudanForm, ChurukudanQuery>>({ | ||||
|         danjvType: [ | ||||
|             { required: true, message: "单据状态不能为空", trigger: "change" } | ||||
|         ], | ||||
|         // 手机号码格式校验 | ||||
|         contactNumber: [ | ||||
|             { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码格式", trigger: "blur" } | ||||
|         ] | ||||
|     } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
| // 查询产品名称列表 | ||||
| const chanpinList = ref<any[]>([]); | ||||
| const chanpinSelect = ref<any[]>([]); | ||||
| // 查询产品名称列表 | ||||
| const getChanpinList = async () => { | ||||
|     try { | ||||
|         const res = await getChanpinLists({ projectId: userStore.selectedProject.id }); | ||||
|         chanpinList.value = res.data || []; | ||||
|         chanpinSelect.value = chanpinList.value.map(item => ({ | ||||
|             label:item.caigouPlanName +'-'+item.chanpinName, | ||||
|             value: item.id | ||||
|         })); | ||||
|         console.log('chanpinSelect.value', chanpinSelect.value); | ||||
|          | ||||
|     } catch (error) { | ||||
|         console.error('获取产品名称列表失败:', error); | ||||
|         proxy?.$modal.msgError("获取产品名称列表失败,请稍后重试"); | ||||
|         chanpinList.value = []; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** 查询运维-物资-出入库单管理列表 */ | ||||
| const getList = async () => { | ||||
| @ -526,23 +556,23 @@ const handleAdd = () => { | ||||
| } | ||||
|  | ||||
| /** 修改按钮操作 */ | ||||
| const handleUpdate = async (row?: ChurukudanVO) => { | ||||
|     reset(); | ||||
|     const _id = row?.id || ids.value[0]; | ||||
|     if (!_id) { | ||||
|         proxy?.$modal.msgWarning("请选择要修改的数据"); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const res = await getChurukudan(_id); | ||||
|         Object.assign(form.value, res.data); | ||||
|         dialog.visible = true; | ||||
|         dialog.title = "修改运维-物资-出入库单管理"; | ||||
|     } catch (error) { | ||||
|         console.error('获取出入库单详情失败:', error); | ||||
|         proxy?.$modal.msgError("获取数据失败,请稍后重试"); | ||||
|     } | ||||
| } | ||||
| // const handleUpdate = async (row?: ChurukudanVO) => { | ||||
| //     reset(); | ||||
| //     const _id = row?.id || ids.value[0]; | ||||
| //     if (!_id) { | ||||
| //         proxy?.$modal.msgWarning("请选择要修改的数据"); | ||||
| //         return; | ||||
| //     } | ||||
| //     try { | ||||
| //         const res = await getChurukudan(_id); | ||||
| //         Object.assign(form.value, res.data); | ||||
| //         dialog.visible = true; | ||||
| //         dialog.title = "修改运维-物资-出入库单管理"; | ||||
| //     } catch (error) { | ||||
| //         console.error('获取出入库单详情失败:', error); | ||||
| //         proxy?.$modal.msgError("获取数据失败,请稍后重试"); | ||||
| //     } | ||||
| // } | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
| @ -550,6 +580,7 @@ const submitForm = () => { | ||||
|         if (valid) { | ||||
|             buttonLoading.value = true; | ||||
|             try { | ||||
|                 form.value.chanpinId = form.value.chanpinName | ||||
|                 if (form.value.id) { | ||||
|                     await updateChurukudan(form.value); | ||||
|                     proxy?.$modal.msgSuccess("修改成功"); | ||||
| @ -607,7 +638,29 @@ const handleDelete = async (row?: ChurukudanVO) => { | ||||
|     } | ||||
| } | ||||
|  | ||||
| // 折线图数据获取 | ||||
| const lineData = ref<any>(); | ||||
| const fetchChuRuKuCountLineData = async () => { | ||||
|     if (!queryParams.value.projectId) { | ||||
|         return; | ||||
|     } | ||||
|     let data = { | ||||
|         projectId: queryParams.value.projectId, | ||||
|         startDate: currentMonthDates[0].fullDate, | ||||
|         endDate: currentMonthDates[currentMonthDates.length - 1].fullDate, | ||||
|     } | ||||
|     try { | ||||
|         const res = await getChuRuKuCountLine(data); | ||||
|         if (res.code === 200) { | ||||
|             lineData.value = res.data; | ||||
|         } | ||||
|         // 这里可以添加数据处理和图表更新的逻辑 | ||||
|     } catch (error) { | ||||
|         proxy?.$modal.msgError("获取统计数据失败"); | ||||
|     } | ||||
| } | ||||
| // 柱状图数据获取 | ||||
| const barData = ref<any>(); | ||||
| const fetchChuRuKuCountBarData = async () => { | ||||
|     if (!queryParams.value.projectId) { | ||||
|         return; | ||||
| @ -618,16 +671,15 @@ const fetchChuRuKuCountBarData = async () => { | ||||
|         endDate: currentMonthDates[currentMonthDates.length - 1].fullDate, | ||||
|     } | ||||
|     try { | ||||
|         const res = await getChuRuKuCountBar(data); | ||||
|         console.log(res); | ||||
|         const res = await getChuRuKuDayCountBar(data); | ||||
|         if (res.code === 200) { | ||||
|             barData.value = res.data; | ||||
|         } | ||||
|         // 这里可以添加数据处理和图表更新的逻辑 | ||||
|     } catch (error) { | ||||
|         console.error('获取柱状图数据失败:', error); | ||||
|         // 可以选择是否显示错误提示,根据UI需求决定 | ||||
|         // proxy?.$modal.msgError("获取统计数据失败"); | ||||
|         proxy?.$modal.msgError("获取统计数据失败"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // 监听用户选择的项目变化 | ||||
| watch(() => userStore.selectedProject, (newProject) => { | ||||
|     if (newProject && newProject.id) { | ||||
| @ -638,12 +690,16 @@ watch(() => userStore.selectedProject, (newProject) => { | ||||
|         } | ||||
|         // 调用getList刷新数据 | ||||
|         getList(); | ||||
|         fetchChuRuKuCountLineData(); | ||||
|         fetchChuRuKuCountBarData(); | ||||
|     } | ||||
| }, { immediate: true, deep: true }); | ||||
| onMounted(() => { | ||||
|     getList(); | ||||
|     fetchChuRuKuCountLineData(); | ||||
|     fetchChuRuKuCountBarData(); | ||||
|     // 查询产品名称列表 | ||||
|     getChanpinList(); | ||||
| }); | ||||
|  | ||||
| // 组件卸载时清空projectId | ||||
|  | ||||
| @ -9,15 +9,15 @@ | ||||
|                                 <ArrowLeft /> | ||||
|                             </el-icon> | ||||
|                         </span> | ||||
|                         <h2>Q2风电轴承采购计划</h2> | ||||
|                         <h2>{{ Info.jihuaName }}</h2> | ||||
|                     </div> | ||||
|                 </el-card> | ||||
|             </el-col> | ||||
|         </el-row> | ||||
|         <el-row gutter="10"> | ||||
|         <el-row :gutter="10"> | ||||
|             <el-col :span="18"> | ||||
|                 <el-card> | ||||
|                     <detailInfo /> | ||||
|                     <detailInfo :detail-info="Info" /> | ||||
|                 </el-card> | ||||
|             </el-col> | ||||
|             <el-col :span="6" style="flex-grow: 1;"> | ||||
| @ -46,12 +46,66 @@ | ||||
|     cursor: pointer; | ||||
| } | ||||
| </style> | ||||
| <script setup> | ||||
| <script setup lang="ts"> | ||||
|  | ||||
| import detailInfo from './components/detailInfo.vue'; | ||||
| import DetailsProcess from './components/DetailsProcess.vue'; | ||||
| import { ref, onMounted, getCurrentInstance, toRefs, watch } from 'vue'; | ||||
| import { useRoute } from 'vue-router'; | ||||
| import type { ComponentInternalInstance } from 'vue'; | ||||
| const route = useRoute(); | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
|  | ||||
| import { caigouPlanDetail } from '@/api/wuziguanli/caigouPlan'; | ||||
| import { CaigouPlanVO, CaigouPlanQuery, CaigouPlanForm } from '@/api/wuziguanli/caigouPlan/types'; | ||||
|  | ||||
|  | ||||
| // 存储计划详情数据 | ||||
| const Info = ref<CaigouPlanVO>({} as CaigouPlanVO); | ||||
|  | ||||
| // 存储计划编号 | ||||
| const id = ref(''); | ||||
|  | ||||
| // 获取详细信息 | ||||
| const getDetailInfo = async () => { | ||||
|     const res = await caigouPlanDetail(id.value); | ||||
|     if (res.code === 200) { | ||||
|         Info.value = res.data; | ||||
|         console.log(Info.value); | ||||
|  | ||||
|     } | ||||
| } | ||||
| onMounted(() => { | ||||
|     // 接收路由参数 | ||||
|     id.value = route.query.id as string || ''; | ||||
|     console.log('组件挂载时路由参数id:', id.value); | ||||
|     // 确保id不为空时才调用接口 | ||||
|     if (id.value) { | ||||
|         getDetailInfo(); | ||||
|     } else { | ||||
|         proxy.$modal.msgError('未获取到详细信息') | ||||
|         setTimeout(() => { | ||||
|             router.back(); | ||||
|         }, 800); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| // 监听路由参数变化 | ||||
| watch( | ||||
|     () => route.query.id, | ||||
|     (newId) => { | ||||
|         id.value = newId as string || '';  | ||||
|         if (id.value) { | ||||
|             getDetailInfo(); | ||||
|         }  | ||||
|     }, | ||||
|     { immediate: true } | ||||
| ); | ||||
| const router = useRouter(); | ||||
| const handleBack = () => { | ||||
|     router.back(); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| </script> | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -214,7 +214,7 @@ | ||||
|                             <dict-tag :options="wz_inventory_type" :value="scope.row.kucunStatus"></dict-tag> | ||||
|                         </template> | ||||
|                     </el-table-column> | ||||
|                     <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|                     <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|                         <template #default="scope"> | ||||
|                             <el-button type="text" @click="handleUpdate(scope.row)" | ||||
|                                 v-hasPermi="['personnel:beipinBeijian:edit']">编辑</el-button> | ||||
| @ -223,7 +223,7 @@ | ||||
|                             <el-button type="text" @click="handleDelete(scope.row)" | ||||
|                                 v-hasPermi="['personnel:beipinBeijian:remove']">删除</el-button> | ||||
|                         </template> | ||||
|                     </el-table-column> | ||||
|                     </el-table-column> --> | ||||
|                 </el-table> | ||||
|                 <div class="pagination-section"> | ||||
|                     <div class="pagination-info"> | ||||
| @ -252,7 +252,7 @@ | ||||
|                     <el-input v-model="form.guigexinghao" placeholder="请输入规格型号" /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="库存数量" prop="kucunCount"> | ||||
|                     <el-input v-model="form.kucunCount" placeholder="请输入库存数量" /> | ||||
|                     <el-input v-model="form.kucunCount" placeholder="请输入库存数量" type="number" min="0" /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="库存状态" prop="kucunStatus"> | ||||
|                     <el-select v-model="form.kucunStatus" placeholder="请选择库存状态"> | ||||
| @ -260,12 +260,12 @@ | ||||
|                             :value="dict.value"></el-option> | ||||
|                     </el-select> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                 <!-- <el-form-item label="设备类型" prop="shebeiType"> | ||||
|                     <el-select v-model="form.shebeiType" placeholder="请选择设备类型"> | ||||
|                         <el-option v-for="dict in wz_device_type" :key="dict.value" :label="dict.label" | ||||
|                             :value="dict.value"></el-option> | ||||
|                     </el-select> | ||||
|                 </el-form-item> | ||||
|                 </el-form-item> --> | ||||
|             </el-form> | ||||
|             <template #footer> | ||||
|                 <div class="dialog-footer"> | ||||
| @ -408,7 +408,7 @@ const userStore = useUserStore(); | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
|  | ||||
| import { listBeipinBeijian, getBeipinBeijian, delBeipinBeijian, updateBeipinBeijian } from '@/api/wuziguanli/beijian'; | ||||
| import { listBeipinBeijian, getBeipinBeijian, delBeipinBeijian, updateBeipinBeijian,chuRuKuTotal } from '@/api/wuziguanli/beijian'; | ||||
| import { BeipinBeijianVO, BeipinBeijianQuery, BeipinBeijianForm } from '@/api/wuziguanli/beijian/types'; | ||||
|  | ||||
|  | ||||
| @ -502,6 +502,18 @@ const getDictLabel = (dictType, value) => { | ||||
|     return option?.label || value; | ||||
| }; | ||||
|  | ||||
| //查询总览 | ||||
| const getTotalView= async () => { | ||||
|     try { | ||||
|         const res = await chuRuKuTotal({projectId: queryParams.value.projectId}); | ||||
|         console.log(res); | ||||
|          | ||||
|         total.value = res.total; | ||||
|     } catch (error) { | ||||
|         proxy?.$modal.msgError('获取数据失败,请重试'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** 查询运维-物资-备品配件列表 */ | ||||
| const getList = async () => { | ||||
|     loading.value = true; | ||||
| @ -511,7 +523,6 @@ const getList = async () => { | ||||
|         total.value = res.total; | ||||
|     } catch (error) { | ||||
|         proxy?.$modal.msgError('获取数据失败,请重试'); | ||||
|         console.error('获取备品配件列表失败:', error); | ||||
|     } finally { | ||||
|         loading.value = false; | ||||
|     } | ||||
| @ -555,7 +566,6 @@ const handleUpdate = async (row?: BeipinBeijianVO) => { | ||||
|         dialog.visible = true; | ||||
|     } catch (error) { | ||||
|         proxy?.$modal.msgError('获取数据失败,请重试'); | ||||
|         console.error('获取备品配件详情失败:', error); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -572,7 +582,6 @@ const handleDetail = async (row?: BeipinBeijianVO) => { | ||||
|         detailDialogVisible.value = true; | ||||
|     } catch (error) { | ||||
|         proxy?.$modal.msgError('获取数据失败,请重试'); | ||||
|         console.error('获取备品配件详情失败:', error); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -595,7 +604,6 @@ const submitForm = () => { | ||||
|                 await getList(); | ||||
|             } catch (error) { | ||||
|                 proxy?.$modal.msgError('操作失败,请重试'); | ||||
|                 console.error('提交表单失败:', error); | ||||
|             } finally { | ||||
|                 buttonLoading.value = false; | ||||
|             } | ||||
| @ -620,7 +628,6 @@ const handleDelete = async (row?: BeipinBeijianVO) => { | ||||
|         // 如果是用户取消确认,则不显示错误信息 | ||||
|         if (error !== 'cancel') { | ||||
|             proxy?.$modal.msgError('删除失败,请重试'); | ||||
|             console.error('删除数据失败:', error); | ||||
|         } | ||||
|     } finally { | ||||
|         loading.value = false; | ||||
| @ -644,6 +651,8 @@ watch(() => userStore.selectedProject, (newProject) => { | ||||
|  | ||||
| onMounted(() => { | ||||
|     getList(); | ||||
|     // 初始化查询总览 | ||||
|     getTotalView(); | ||||
| }); | ||||
|  | ||||
| // 组件卸载时清空projectId | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| <template> | ||||
|     <el-card style="border-radius: 15px;"> | ||||
|         <el-row gutter="35"> | ||||
|         <el-row :gutter="35"> | ||||
|             <el-col :span="8" class="status-card"> | ||||
|                 <div class="title">设备状态</div> | ||||
|                 <!-- gutter设置为20,创建左右间隙 --> | ||||
|                 <el-row gutter="20" style="width: 100%;"> | ||||
|                 <el-row :gutter="20" style="width: 100%;"> | ||||
|                     <!-- 一行2个,每个占12格(24/2=12) --> | ||||
|                     <el-col :span="12"> | ||||
|                         <div class="item"> | ||||
| @ -120,7 +120,7 @@ | ||||
|     } | ||||
|  | ||||
|     .red { | ||||
|         ::v-deep::before { | ||||
|         :v-deep::before { | ||||
|             position: absolute; | ||||
|             content: ''; | ||||
|             background-color: rgba(227, 39, 39, 1); | ||||
| @ -133,7 +133,7 @@ | ||||
|     } | ||||
|  | ||||
|     .yellow { | ||||
|         ::v-deep::before { | ||||
|         :v-deep::before { | ||||
|             position: absolute; | ||||
|             content: ''; | ||||
|             background-color: rgba(255, 208, 35, 1); | ||||
|  | ||||
| @ -132,7 +132,7 @@ | ||||
|     position: relative; | ||||
|     margin: 10px 0; | ||||
|  | ||||
|     ::v-deep::before { | ||||
|     :v-deep::before { | ||||
|         position: absolute; | ||||
|         width: 5px; | ||||
|         height: 5px; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	