ProductionAchievementRate.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. <template>
  2. <div>
  3. <layout>
  4. <layout-header>
  5. <div class="">
  6. <!-- 按钮部分-->
  7. <el-form ref="elSearchFormRef" class="demo-form-inline" :rules="searchRule" >
  8. <el-form-item>
  9. <el-input v-model="searchInfo" placeholder="搜索工单编号" clearable style="width: 200px;margin: 5px"></el-input>
  10. <el-button type="primary" class="bt" icon="download" @click="hzToExcel" >导出到Excel(汇总)</el-button>
  11. <el-button type="primary" class="bt" icon="download" @click="mxToExcel" >导出到Excel(明细)</el-button>
  12. <el-button type="primary" class="bt" icon="download" @click="rqToExcel" >按时段导出明细</el-button>
  13. </el-form-item>
  14. </el-form>
  15. </div>
  16. </layout-header>
  17. <layout>
  18. <!-- 左侧树侧形结构-->
  19. <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;">
  20. <div class="JKWTree-tree" style="height: 200px">
  21. <h3>设备生产效率达成统计</h3>
  22. <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" @node-expand="handleNodeExpand">
  23. </el-tree>
  24. </div>
  25. </layout-sider>
  26. <!-- 右侧区域 -->
  27. <layout-content >
  28. <el-main>
  29. <div class="gva-table-box">
  30. <!-- 表格数据 -->
  31. <el-table ref="multipleTable"
  32. v-if="! ismachine"
  33. :show-overflow-tooltip="true"
  34. @selection-change="selectionChange($event)"
  35. :row-style="{ height: '20px' }" :selectable="checkboxT"
  36. :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
  37. :header-cell-style="{ padding: '0px' }" @row-click="pchzRowClick"
  38. :row-class-name="pchzrowClassStyle"
  39. highlight-current-row="true" @row-dblclick="gytableDatadoubleClick" id="pchztable"
  40. style="width: 100%;height: 30vh" border tooltip-effect="dark" :data="pchztableData" row-key="ID" >
  41. <el-table-column fixed align="left" label="机台编号" prop="机台编号" width="110"/>
  42. <el-table-column fixed align="left" label="机台名称" prop="机台名称" width="170"/>
  43. <el-table-column fixed align="left" label="班组" prop="班组" width="60"/>
  44. <el-table-column align="left" label="近7天综合达成率" prop="近7天综合达成率" width="135"/>
  45. <!-- 近七天列表 -->
  46. <template v-for="item in datelist">
  47. <el-table-column align="left" :label="item.display" :prop="item.prop" width="80"/>
  48. </template>
  49. <el-table-column align="left" label="实际总产量" prop="实际总产量" width="100"/>
  50. <el-table-column align="left" label="排产总产量" prop="排产总产量" width="100"/>
  51. <el-table-column align="left" label="实际产量1" prop="实际产量1" width="100"/>
  52. <el-table-column align="left" label="排产产量1" prop="排产产量1" width="100"/>
  53. <el-table-column align="left" label="实际产量2" prop="实际产量2" width="100"/>
  54. <el-table-column align="left" label="排产产量2" prop="排产产量2" width="100"/>
  55. <el-table-column align="left" label="实际产量3" prop="实际产量3" width="100"/>
  56. <el-table-column align="left" label="排产产量3" prop="排产产量3" width="100"/>
  57. <el-table-column align="left" label="实际产量4" prop="实际产量4" width="100"/>
  58. <el-table-column align="left" label="排产产量4" prop="排产产量4" width="100"/>
  59. <el-table-column align="left" label="实际产量5" prop="实际产量5" width="100"/>
  60. <el-table-column align="left" label="排产产量5" prop="排产产量5" width="100"/>
  61. <el-table-column align="left" label="实际产量6" prop="实际产量6" width="100"/>
  62. <el-table-column align="left" label="排产产量6" prop="排产产量6" width="100"/>
  63. <el-table-column align="left" label="实际产量7" prop="实际产量7" width="100"/>
  64. <el-table-column align="left" label="排产产量7" prop="排产产量7" width="100"/>
  65. </el-table>
  66. <el-table ref="JPmultipleTable"
  67. v-if="! ismachine"
  68. :show-overflow-tooltip="true"
  69. @selection-change="selectionChange($event)"
  70. :row-style="{ height: '20px' }" :row-class-name="totalClassName" :cell-class-name="tableDataCellClass"
  71. :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
  72. :header-cell-style="{ padding: '0px' }" @row-click="getUid"
  73. highlight-current-row="true" @row-dblclick="JPgytableDatadoubleClick" id="pcmxtable"
  74. style="width: 100%;height: 45vh" border tooltip-effect="dark" :data="pcmxtableData" row-key="ID" >
  75. <el-table-column align="left" fixed label="日期" prop="日期" width="110"/>
  76. <el-table-column align="left" fixed label="机台编号" prop="机台编号" width="90"/>
  77. <el-table-column align="left" fixed label="班组" prop="班组" width="70"/>
  78. <el-table-column align="left" label="工单编号" prop="工单编号" width="90"/>
  79. <el-table-column align="left" label="印件号" prop="印件号" width="70"/>
  80. <el-table-column align="left" label="印件名称" prop="印件名称" width="120"/>
  81. <el-table-column align="left" label="工序号" prop="工序号" width="70"/>
  82. <el-table-column align="left" label="工序名称" prop="工序名称" width="120"/>
  83. <el-table-column align="left" label="实际产量" prop="实际产量" width="90"/>
  84. <el-table-column align="left" label="排产标准产能" prop="排产标准产能" width="110"/>
  85. <el-table-column align="left" label="排产产量" prop="排产产量" width="90"/>
  86. <el-table-column align="left" label="上报运行工时" prop="上报运行工时" width="110"/>
  87. <el-table-column align="left" label="运行工时" prop="运行工时" width="110"/>
  88. <el-table-column align="left" label="工序计划辅助工时" prop="工序计划辅助工时" width="140"/>
  89. <el-table-column align="left" label="装版实际工时" prop="装版实际工时" width="110"/>
  90. <el-table-column align="left" label="保养工时" prop="保养工时" width="110"/>
  91. <el-table-column align="left" label="打样工时" prop="打样工时" width="110"/>
  92. <el-table-column align="left" label="版距" prop="版距" width="110"/>
  93. <el-table-column align="left" label="机台名称" prop="机台名称" width="130"/>
  94. </el-table>
  95. <el-table ref="multipleTable"
  96. v-if="ismachine"
  97. :show-overflow-tooltip="true"
  98. @selection-change="selectionChange($event)"
  99. :row-style="{ height: '20px' }" :selectable="checkboxT"
  100. :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
  101. :header-cell-style="{ padding: '0px' }" @row-click="sbhzRowClick"
  102. highlight-current-row="true" @row-dblclick="gytableDatadoubleClick" id="sbhztable"
  103. style="width: 100%;height: 30vh" border tooltip-effect="dark" :data="sbhztableData" row-key="ID" >
  104. <el-table-column fixed align="left" label="机台编号" prop="机台编号" width="90"/>
  105. <el-table-column fixed align="left" label="班组" prop="班组" width="70"/>
  106. <el-table-column align="left" label="实际产量" prop="实际产量" width="85"/>
  107. <el-table-column align="left" label="目标产量" prop="目标产量" width="85"/>
  108. <el-table-column align="left" label="负荷产量" prop="负荷产量" width="85"/>
  109. <el-table-column align="left" label="目标达成" prop="目标达成" width="85"/>
  110. <el-table-column align="left" label="综合利用率" prop="综合利用率" width="95"/>
  111. <el-table-column align="left" label="装版实际工时" prop="装版实际工时" width="110"/>
  112. <el-table-column align="left" label="装版补产工时" prop="装版补产工时" width="110"/>
  113. <el-table-column align="left" label="保养工时" prop="保养工时" width="110"/>
  114. <el-table-column align="left" label="打样总工时" prop="打样总工时" width="110"/>
  115. <el-table-column align="left" label="打样补产工时" prop="打样补产工时" width="110"/>
  116. <el-table-column align="left" label="异常总工时" prop="异常总工时" width="110"/>
  117. <el-table-column align="left" label="异常补时" prop="异常补时" width="110"/>
  118. <el-table-column align="left" label="运行工时" prop="运行工时" width="110"/>
  119. </el-table>
  120. <el-table ref="JPmultipleTable"
  121. v-if="ismachine"
  122. :show-overflow-tooltip="true"
  123. @selection-change="selectionChange($event)"
  124. :row-style="{ height: '20px' }" :cell-class-name="tableDataCellClass"
  125. :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
  126. :header-cell-style="{ padding: '0px' }" @row-click="sbmxRowClick"
  127. :row-class-name="sbmxrowClassStyle"
  128. highlight-current-row="true" @row-dblclick="JPgytableDatadoubleClick" id="sbmxtable"
  129. style="width: 100%;height: 45vh" border tooltip-effect="dark" :data="sbmxtableData" row-key="ID" >
  130. <el-table-column align="left" fixed label="机台编号" prop="机台编号" width="90"/>
  131. <el-table-column align="left" fixed label="日期" prop="日期" width="110"/>
  132. <el-table-column align="left" fixed label="班组" prop="班组" width="70"/>
  133. <el-table-column align="left" label="工单编号" prop="工单编号" width="90"/>
  134. <el-table-column align="left" label="印件名称" prop="印件名称" width="110"/>
  135. <el-table-column align="left" label="印件工序" prop="工序名称" width="110"/>
  136. <el-table-column align="left" label="实际产量" prop="实际产量" width="100"/>
  137. <el-table-column align="left" label="目标产量" prop="目标产量" width="90"/>
  138. <el-table-column align="left" label="负荷产量" prop="负荷产量" width="90"/>
  139. <el-table-column align="left" label="目标达成" prop="目标达成" width="90"/>
  140. <el-table-column align="left" label="综合利用率" prop="综合利用率" width="100"/>
  141. <el-table-column align="left" label="装版实际工时" prop="装版实际工时" width="110"/>
  142. <el-table-column align="left" label="装版补产工时" prop="装版补产工时" width="110"/>
  143. <el-table-column align="left" label="保养工时" prop="保养工时" width="100"/>
  144. <el-table-column align="left" label="打样总工时" prop="打样总工时" width="100"/>
  145. <el-table-column align="left" label="打样补产工时" prop="打样补产工时" width="110"/>
  146. <el-table-column align="left" label="异常总工时" prop="异常总工时" width="100"/>
  147. <el-table-column align="left" label="异常补时" prop="异常补时" width="100"/>
  148. <el-table-column align="left" label="运行工时" prop="运行工时" width="100"/>
  149. <el-table-column align="left" label="小时产能" prop="小时产能" width="100"/>
  150. <el-table-column align="left" label="最高限速" prop="最高限速" width="100"/>
  151. <el-table-column align="left" label="理论生产效率" prop="理论生产效率" width="110"/>
  152. <el-table-column align="left" label="难度系数" prop="难度系数" width="100"/>
  153. <el-table-column align="left" label="版距" prop="版距" width="100"/>
  154. </el-table>
  155. </div>
  156. <!-- 按时段导出弹窗 -->
  157. <el-dialog v-model="onrqexcel" title="达成率明细导出" destroy-on-close style="height: 30%;width: 20%;">
  158. <el-form-item label="部门" label-width="100px">
  159. <el-select v-model="excelbm" placeholder="选择部门">
  160. <el-option
  161. v-for="item in bmoptions"
  162. :key="item.value"
  163. :label="item.label"
  164. :value="item.value">
  165. </el-option>
  166. </el-select>
  167. </el-form-item>
  168. <el-form-item label="选择年月" label-width="100px">
  169. <el-date-picker
  170. v-model="excelrq"
  171. type="daterange"
  172. range-separator="至"
  173. start-placeholder="开始日期"
  174. end-placeholder="结束日期"
  175. :default-value="new Date()"
  176. @change="onchange_data"
  177. style="width: 200px;"
  178. />
  179. </el-form-item>
  180. <template #footer>
  181. <div class="dialog-footer" style="text-align: right;">
  182. <el-button @click="rqexcelcloseDialog">取消</el-button>
  183. <el-button type="primary" @click="rqexcelonDialog">确定</el-button>
  184. </div>
  185. </template>
  186. </el-dialog>
  187. </el-main>
  188. </layout-content>
  189. </layout>
  190. </layout>
  191. </div>
  192. </template>
  193. <script setup>
  194. // 全量引入格式化工具 请按需保留
  195. import { Layout, LayoutSider, LayoutContent } from '@arco-design/web-vue';
  196. import {PARLeftmenu,PARlist,PARDetail,PARlistpro,PARDetailpro,PARDateExcel} from "@/api/mes/job.js"
  197. import {ref, reactive} from 'vue'
  198. import * as XLSX from 'xlsx'
  199. import { exportExcelFile } from '@/utils/excel'
  200. import {ElMessage} from "element-plus";
  201. import { start } from 'nprogress';
  202. defineOptions({name: 'Company'})
  203. const treeData = ref([]);
  204. const defaultProps = {
  205. label: 'label',
  206. children: 'children'
  207. };
  208. const getTreeData = async () => {
  209. try {
  210. const response = await PARLeftmenu();
  211. console.log('接口原始数据:', response);
  212. if (!response) {
  213. throw new Error('接口返回数据为空');
  214. }
  215. const rawData = response.data;
  216. const newTreeData = [];
  217. // 1. 处理排产计划达成率统计
  218. if (rawData['排产计划达成率统计']) {
  219. const planCompletionNode = {
  220. label: '排产计划达成率统计',
  221. children: rawData['排产计划达成率统计']
  222. .map(item => ({
  223. label: item['使用部门'].trim() || '未知部门',
  224. }))
  225. };
  226. newTreeData.push(planCompletionNode);
  227. }
  228. // 2. 处理设备工时达成率统计
  229. if (rawData['设备工时达成率统计']) {
  230. const equipmentHoursNode = {
  231. label: '设备工时达成率统计',
  232. children: []
  233. };
  234. // 获取所有年份并按降序排序
  235. const sortedYears = Object.keys(rawData['设备工时达成率统计'])
  236. .sort((a, b) => parseInt(b) - parseInt(a));
  237. for (const year of sortedYears) {
  238. const yearData = rawData['设备工时达成率统计'][year];
  239. if (!yearData) continue;
  240. const yearNode = {
  241. label: year,
  242. children: []
  243. };
  244. // 获取该年所有月份并按降序排序
  245. const sortedMonths = Object.keys(yearData)
  246. .sort((a, b) => {
  247. // 处理格式为YYYYMM的月份键
  248. const monthA = a.length === 6 ? parseInt(a.substring(4)) : parseInt(a);
  249. const monthB = b.length === 6 ? parseInt(b.substring(4)) : parseInt(b);
  250. return monthB - monthA;
  251. });
  252. for (const monthKey of sortedMonths) {
  253. const monthData = yearData[monthKey];
  254. if (!monthData) continue;
  255. const monthName = monthKey.length === 6
  256. ? `${monthKey.substring(4)}月`
  257. : monthKey;
  258. const monthNode = {
  259. label: `${year}年${monthName}`,
  260. children: monthData
  261. .filter(dept => dept) // 过滤空部门
  262. .map(dept => ({
  263. label: dept.trim() || '未知部门',
  264. rq: monthKey, // 添加月份键值
  265. }))
  266. };
  267. yearNode.children.push(monthNode);
  268. }
  269. equipmentHoursNode.children.push(yearNode);
  270. }
  271. newTreeData.push(equipmentHoursNode);
  272. }
  273. console.log('最终树数据:', newTreeData);
  274. treeData.value = newTreeData;
  275. } catch (error) {
  276. console.error('加载树数据失败:', error);
  277. treeData.value = [];
  278. }
  279. };
  280. // 初始化加载数据
  281. getTreeData();
  282. const ismachine = ref(false)
  283. const datelist = ref([]);
  284. const pchztableData = ref([]);
  285. const pcmxtableData = ref([]);
  286. const sbhztableData = ref([]);
  287. const sbmxtableData = ref([]);
  288. // 节点点击事件处理
  289. const handleNodeClick = async (nodeData) => {
  290. console.log('节点点击:', nodeData)
  291. if(!nodeData.children){
  292. console.log('点击了车间')
  293. //根据是否有rq判断点击的是排产还是设备
  294. if(!nodeData.rq){
  295. ismachine.value = false;
  296. const response = await PARlist({Machine:nodeData.label});
  297. // 创建日期映射表
  298. const dateMap = response.data.list.map(fullDate => {
  299. const [year, month, day] = fullDate.split('-');
  300. const shortKey = `${month.padStart(2, '0')}-${day.padStart(2, '0')}`; // 显示用 05-08
  301. const longKey = `${month.padStart(2, '0')}月${day.padStart(2, '0')}日`; // 数据键 05月08日
  302. return {
  303. display: shortKey, // 表头显示
  304. prop: longKey // 对应数据字段
  305. };
  306. });
  307. datelist.value = dateMap; // 存储映射关系
  308. pchztableData.value = response.data.data;
  309. }else{
  310. ismachine.value = true;
  311. const response = await PARlistpro({Machine:nodeData.label,rq:nodeData.rq});
  312. sbhztableData.value = response.data;
  313. }
  314. }
  315. }
  316. // 节点展开事件处理
  317. const handleNodeExpand = (nodeData, node) => {
  318. console.log('节点展开:', nodeData)
  319. }
  320. const currentjtbh = ref('')//储存设备汇总表格当前选中的机台编号
  321. const currentrq = ref('')//储存设备明细表格当前选中的日期
  322. // 排产表格行点击事件处理
  323. const pchzRowClick = async (row) => {
  324. console.log('行点击:', row)
  325. currentjtbh.value = row.机台编号;
  326. const response = await PARDetail({jtbh:row.机台编号,bz:row.班组})
  327. if (response?.code === 0 && Array.isArray(response.data)) {
  328. pcmxtableData.value = response.data;
  329. console.log('表格数据更新成功:', response.data);
  330. }
  331. }
  332. // 设备汇总表格行点击事件处理
  333. const sbhzRowClick = async (row) => {
  334. console.log('行点击:', row)
  335. const response = await PARDetailpro({jtbh:row.机台编号,bz:row.班组,rq:row.sczl_rq})
  336. if (response?.code === 0 && Array.isArray(response.data)) {
  337. sbmxtableData.value = response.data;
  338. console.log('表格数据更新成功:', response.data);
  339. }
  340. }
  341. //设备明细表格行点击事件处理
  342. const sbmxRowClick = async (row) => {
  343. currentrq.value = row.日期;
  344. }
  345. //导出按钮(汇总)
  346. const hzToExcel = async () => {
  347. try {
  348. // 获取数据
  349. const el = document.getElementById(ismachine.value ? 'sbhztable' : 'pchztable');
  350. const filename = '生产效率统计汇总导出.xlsx';
  351. const worksheet = XLSX.utils.table_to_sheet(el, { raw: true });
  352. //从某列开始转化成数字
  353. //设置从C列开始为数字格式
  354. const range = XLSX.utils.decode_range(worksheet['!ref']);
  355. for (let col = 2; col <= range.e.c; col++) { // 从C列(索引2)开始
  356. for (let row = range.s.r + 1; row <= range.e.r; row++) { // 跳过表头行
  357. const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
  358. if (worksheet[cellAddress]) {
  359. // 尝试转换为数字
  360. const cellValue = worksheet[cellAddress].v;
  361. const numValue = Number(cellValue);
  362. if (!isNaN(numValue)) {
  363. worksheet[cellAddress].t = 'n'; // 数字类型
  364. worksheet[cellAddress].v = numValue; // 更新值
  365. worksheet[cellAddress].z = '0'; // 数字格式
  366. }
  367. }
  368. }
  369. }
  370. // 创建并导出工作簿
  371. const wb = XLSX.utils.book_new();
  372. XLSX.utils.book_append_sheet(wb, worksheet, 'Sheet1');
  373. XLSX.writeFile(wb, filename);
  374. } catch (error) {
  375. console.error('导出失败:', error);
  376. ElMessage.error('导出数据失败,请重试');
  377. }
  378. };
  379. //导出按钮(汇总)
  380. const mxToExcel = async () => {
  381. try {
  382. // 获取数据
  383. const el = document.getElementById(ismachine.value ? 'sbmxtable' : 'pcmxtable');
  384. const filename = '生产效率统计明细导出.xlsx';
  385. const worksheet = XLSX.utils.table_to_sheet(el, { raw: true });
  386. //从某列开始转化成数字
  387. const range = XLSX.utils.decode_range(worksheet['!ref']);
  388. for (let col = 4; col <= range.e.c; col++) { // 从C列(索引2)开始
  389. for (let row = range.s.r + 1; row <= range.e.r; row++) { // 跳过表头行
  390. const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
  391. if (worksheet[cellAddress]) {
  392. // 尝试转换为数字
  393. const cellValue = worksheet[cellAddress].v;
  394. const numValue = Number(cellValue);
  395. if (!isNaN(numValue)) {
  396. worksheet[cellAddress].t = 'n'; // 数字类型
  397. worksheet[cellAddress].v = numValue; // 更新值
  398. worksheet[cellAddress].z = '0'; // 数字格式
  399. }
  400. }
  401. }
  402. }
  403. // 创建并导出工作簿
  404. const wb = XLSX.utils.book_new();
  405. XLSX.utils.book_append_sheet(wb, worksheet, 'Sheet1');
  406. XLSX.writeFile(wb, filename);
  407. } catch (error) {
  408. console.error('导出失败:', error);
  409. ElMessage.error('导出数据失败,请重试');
  410. }
  411. };
  412. const onrqexcel = ref(false);
  413. const excelbm = ref(''); // 部门
  414. const excelrq = ref([]); // 初始化为数组,用于存储日期范围
  415. const bmoptions = ref([]); // 部门下拉选项
  416. // 打开导出弹窗时
  417. const rqToExcel = async () => {
  418. //动态加载部门数据
  419. if (treeData.value[0]?.children) {
  420. bmoptions.value = treeData.value[0].children.map(item => ({
  421. label: item.label,
  422. value: item.label,
  423. }));
  424. }
  425. onrqexcel.value = true;
  426. };
  427. const onchange_data = (val) => {
  428. if (val && val.length === 2) {
  429. // 格式化单个日期为 "YYYY-MM-DD"
  430. const formatDate = (date) => {
  431. const year = date.getFullYear();
  432. const month = String(date.getMonth() + 1).padStart(2, '0');
  433. const day = String(date.getDate()).padStart(2, '0'); // 获取日,并补零
  434. return `${year}-${month}-${day}`;
  435. };
  436. // 分别格式化开始日期和结束日期
  437. excelrq.value = [formatDate(val[0]), formatDate(val[1])];
  438. } else {
  439. excelrq.value = []; // 清空选择
  440. }
  441. };
  442. // 确定导出
  443. const rqexcelonDialog = async () => {
  444. if (excelrq.value.length !== 2) {
  445. ElMessage.warning('请选择完整的日期范围');
  446. return;
  447. }
  448. try {
  449. // 获取数据
  450. const response = await PARDateExcel({
  451. start_rq: excelrq.value[0],
  452. end_rq: excelrq.value[1],
  453. bm: excelbm.value
  454. });
  455. const data = response.data; // 假设返回的是数组格式的数据
  456. // 1. 准备表头
  457. const headers = Object.keys(data[0] || {});
  458. // 2. 准备工作表数据(包含表头和数据行)
  459. const wsData = [
  460. headers, // 表头行
  461. ...data.map(row => headers.map(key => row[key])) // 数据行
  462. ];
  463. // 3. 创建工作表
  464. const worksheet = XLSX.utils.aoa_to_sheet(wsData);
  465. // 4. 数字类型转换(从第5列开始,索引4)
  466. const range = XLSX.utils.decode_range(worksheet['!ref']);
  467. for (let col = 4; col <= range.e.c; col++) {
  468. for (let row = range.s.r + 1; row <= range.e.r; row++) {
  469. const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
  470. if (worksheet[cellAddress]) {
  471. const cellValue = worksheet[cellAddress].v;
  472. const numValue = Number(cellValue);
  473. if (!isNaN(numValue)) {
  474. worksheet[cellAddress].t = 'n';
  475. worksheet[cellAddress].v = numValue;
  476. worksheet[cellAddress].z = '0';
  477. }
  478. }
  479. }
  480. }
  481. // 5. 创建并导出工作簿
  482. const wb = XLSX.utils.book_new();
  483. XLSX.utils.book_append_sheet(wb, worksheet, 'Sheet1');
  484. XLSX.writeFile(wb, '生产效率统计按时段明细导出.xlsx');
  485. } catch (error) {
  486. console.error('导出失败:', error);
  487. ElMessage.error('导出数据失败,请重试');
  488. }
  489. };
  490. // 关闭弹窗
  491. const rqexcelcloseDialog = () => {
  492. onrqexcel.value = false;
  493. };
  494. //===============颜色==================================
  495. //排产汇总表格样式
  496. const pchzrowClassStyle = ({row,rowIndex}) =>{
  497. if(row['机台编号']== currentjtbh.value){
  498. return "warning-row"
  499. }
  500. }
  501. //设备明细表格样式
  502. const sbmxrowClassStyle = ({row,rowIndex}) =>{
  503. if(row['日期']== currentrq.value){
  504. return "warning-row"
  505. }
  506. }
  507. </script>
  508. <style scoped>
  509. .form-container {
  510. display: flex;
  511. flex-wrap: wrap;
  512. }
  513. .form-column {
  514. /*flex: 1;*/
  515. margin-right: 15px; /* 调整列之间的间距 */
  516. }
  517. /* 左侧输入框宽度调整 */
  518. .form-column .el-form-item .el-input {
  519. width: 150px; /* 调整左侧输入框的宽度 */
  520. }
  521. :deep(.hui-plan-usage-lows div) {
  522. color: #8c939d !important;
  523. }
  524. :deep(.lan-plan-usage-lows div) {
  525. color: blue !important;
  526. font-weight: bold;
  527. }
  528. /* 媒体查询,根据需要调整断点 */
  529. @media screen and (max-width: 768px) {
  530. .form-column {
  531. flex: 1 0 100%; /* 在小屏幕下变成单列布局 */
  532. margin-right: 0;
  533. }
  534. }
  535. /*:deep(.el-table td .cell) {*/
  536. /* line-height: 30px !important;*/
  537. /*}*/
  538. .JKWTree-container {
  539. display: flex;
  540. }
  541. .JKWTree-tree {
  542. /*width: 300px;*/
  543. background-color: #fff;
  544. padding: 10px;
  545. margin-right: 20px;
  546. }
  547. .JKWTree-tree h3 {
  548. font-size: 15px;
  549. font-weight: 700;
  550. margin: 10px 0;
  551. }
  552. .JKWTree-content {
  553. flex: 1;
  554. }
  555. :deep(.el-table__body .warning-row) {
  556. background: #FFFF80 !important;
  557. }
  558. /* 选中某行时的背景色 */
  559. :deep(.el-table__body tr.current-row) > td {
  560. background: #ff80ff !important;
  561. }
  562. </style>
  563. <style scoped>
  564. :deep(.el-table td .cell) {
  565. line-height: 20px !important;
  566. }
  567. :deep(.el-tabs__header){
  568. margin-bottom: 0;
  569. }
  570. .search{
  571. margin-left: 0px !important;
  572. margin-right: 10px !important;
  573. }
  574. .bt{
  575. margin-left: 2px !important;
  576. padding: 3px !important;
  577. font-size: 12px;
  578. }
  579. .el-tabs__header{
  580. margin: 0px !important;
  581. }
  582. .gva-table-box{
  583. padding: 0px !important;
  584. }
  585. .mab{
  586. margin-bottom: 5px;
  587. }
  588. </style>