v23CostProcess.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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="edit" @click="oncreate">成本计算</el-button> -->
  11. <el-button type="primary" class="bt" icon="download" @click="ToExcel" >导出到Excel</el-button>
  12. </el-form-item>
  13. </el-form>
  14. </div>
  15. </layout-header>
  16. <layout>
  17. <!-- 左侧树侧形结构-->
  18. <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;height: 78vh">
  19. <div class="JKWTree-tree" style="height: 200px">
  20. <h3>V23工序成本独立核算</h3>
  21. <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" @node-expand="handleNodeExpand">
  22. </el-tree>
  23. </div>
  24. </layout-sider>
  25. <!-- 右侧区域 -->
  26. <layout-content >
  27. <el-main>
  28. <div class="gva-table-box">
  29. <!-- 表格数据 -->
  30. <el-table ref="multipleTable" style="width: 100%;height: 50vh" tooltip-effect="dark"
  31. :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
  32. :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
  33. :data="hztableData" border row-key="ID"
  34. size="small" id="tab2"
  35. :cell-class-name="gxbgCellClass"
  36. highlight-current-row="true" @row-dblclick="updateCompanyFunc"
  37. @row-click="tableRowClick" :show-overflow-tooltip="true"
  38. @selection-change="handleSelectionChange">
  39. <el-table-column sortable align="center" label="车间名称" prop="车间名称" width="120" />
  40. <el-table-column sortable align="center" label="工单编号" prop="sczl_gdbh" width="120" />
  41. <el-table-column align="center" label="年月" prop="sys_ny" width="100" />
  42. <el-table-column align="center" label="印件号" prop="sczl_yjno" width="90" />
  43. <el-table-column align="center" label="印件名称" prop="印件名称" width="300" />
  44. <el-table-column align="center" label="工序号" prop="sczl_gxh" width="90" />
  45. <el-table-column align="center" label="工序名称" prop="工序名称" width="110" />
  46. <el-table-column align="center" label="设备编号" prop="sczl_jtbh" width="110" />
  47. <el-table-column align="center" label="卷张换算系数" prop="卷张换算系数" width="110" />
  48. <el-table-column align="center" label="占用机时" prop="占用机时" width="110" />
  49. <el-table-column align="center" label="班组车头产量" prop="班组车头产量" width="120" />
  50. <el-table-column align="center" label="墨数" prop="sczl_ms" width="110" />
  51. <el-table-column align="center" label="工序难度系数" prop="工序难度系数" width="200" />
  52. <el-table-column align="center" label="班组换算产量" prop="班组换算产量" width="200" />
  53. <el-table-column align="center" label="千件工价" prop="千件工价" width="110" />
  54. <el-table-column align="center" label="计件产量" prop="计件产量" width="200" />
  55. <el-table-column align="center" label="水电分摊因子" prop="水电分摊因子" width="200" />
  56. <el-table-column align="center" label="材料分摊因子" prop="材料分摊因子" width="200" />
  57. <el-table-column align="center" label="人工分摊因子" prop="人工分摊因子" width="200" />
  58. <el-table-column align="center" label="小时折旧额" prop="A_小时折旧额" width="200" />
  59. <el-table-column align="center" label="车间人工" prop="车间人工" width="110" />
  60. <el-table-column align="center" label="部门人工附加" prop="部门人工附加" width="110" />
  61. <el-table-column align="center" label="直接材料" prop="直接材料" width="200" />
  62. <el-table-column align="center" label="考核直接材料" prop="考核直接材料" width="200" />
  63. <el-table-column align="center" label="分摊材料" prop="分摊材料" width="110" />
  64. <el-table-column align="center" label="直接折旧" prop="直接折旧" width="110" />
  65. <el-table-column align="center" label="分摊折旧" prop="分摊折旧" width="200" />
  66. <el-table-column align="center" label="直接水电" prop="直接水电" width="200" />
  67. <el-table-column align="center" label="分摊水电" prop="分摊水电" width="110" />
  68. <el-table-column align="center" label="场地租金" prop="场地租金" width="110" />
  69. <el-table-column align="center" label="废气处理" prop="废气处理" width="200" />
  70. <el-table-column align="center" label="锅炉" prop="锅炉" width="140" />
  71. <el-table-column align="center" label="热水锅炉" prop="热水锅炉" width="110" />
  72. <el-table-column align="center" label="空压机" prop="空压机" width="110" />
  73. <el-table-column align="center" label="真空鼓风机" prop="真空鼓风机" width="110" />
  74. <el-table-column align="center" label="中央空调" prop="中央空调" width="110" />
  75. <el-table-column align="center" label="分摊其他" prop="分摊其他" width="200" />
  76. <el-table-column align="center" label="成本合计" prop="客户编号" width="200" />
  77. </el-table>
  78. <!-- 分页 -->
  79. <div class="gva-pagination">
  80. <el-pagination
  81. @size-change="handleSizeChange"
  82. @current-change="handleCurrentChange"
  83. :current-page="page"
  84. :page-size="limit"
  85. layout="total, sizes, prev, pager, next, jumper"
  86. :total="total">
  87. </el-pagination>
  88. </div>
  89. <div class="formula-description">
  90. <div class="formula-title">计算公式说明:</div>
  91. <div class="formula-grid">
  92. <div class="formula-item">
  93. <span class="formula-label">水电分摊因子:</span>
  94. <span class="formula-content">工单机台生产工时</span>
  95. </div>
  96. <div class="formula-item">
  97. <span class="formula-label">材料分摊因子:</span>
  98. <span class="formula-content">色度数</span>
  99. </div>
  100. <div class="formula-item">
  101. <span class="formula-label">人工分摊因子:</span>
  102. <span class="formula-content">直接人工成本</span>
  103. </div>
  104. <div class="formula-item">
  105. <span class="formula-label">小时折旧额:</span>
  106. <span class="formula-content">机台小时折旧 × 水电分摊因子</span>
  107. </div>
  108. <div class="formula-item">
  109. <span class="formula-label">车间人工:</span>
  110. <span class="formula-content">车间人工成本 × (工单工序色度数 ÷ 车间总色度数)</span>
  111. </div>
  112. <div class="formula-item">
  113. <span class="formula-label">部门人工附加:</span>
  114. <span class="formula-content">部门人工 × (车间直接人工成本 ÷ 总直接人工成本) × (工单工序色度数 ÷ 车间总色度数)</span>
  115. </div>
  116. <div class="formula-item">
  117. <span class="formula-label">直接材料:</span>
  118. <span class="formula-content">ERP直接材料数量 × 单价</span>
  119. </div>
  120. <div class="formula-item">
  121. <span class="formula-label">分摊材料:</span>
  122. <span class="formula-content">ERP分摊材料数量 × 单价 × (工单工序色度数 ÷ 车间总色度数)</span>
  123. </div>
  124. <div class="formula-item">
  125. <span class="formula-label">直接水电:</span>
  126. <span class="formula-content">上报运行时长 × 电量单价</span>
  127. </div>
  128. <div class="formula-item full-width">
  129. <span class="formula-label">废气处理、锅炉、热水锅炉、空压机、空调、鼓风机:</span>
  130. <span class="formula-content">上报数量 × 单价 × (水电分摊因子 ÷ 总分摊因子)(锅炉和热水锅炉只算卷凹机组)</span>
  131. </div>
  132. </div>
  133. </div>
  134. </div>
  135. <el-dialog
  136. v-model="costlist"
  137. title="成本计算"
  138. width="500px"
  139. :close-on-click-modal="false"
  140. >
  141. <!-- 月份选择器 -->
  142. <div class="date-picker-container">
  143. <div class="date-picker-item">
  144. <span class="label">计算月份:</span>
  145. <el-date-picker
  146. v-model="costMonth"
  147. type="month"
  148. placeholder="选择创建月份"
  149. format="YYYY年MM月"
  150. value-format="YYYYMM"
  151. />
  152. </div>
  153. </div>
  154. <!-- 底部按钮 -->
  155. <template #footer>
  156. <span class="dialog-footer">
  157. <el-button @click="costlist = false">取消</el-button>
  158. <el-button type="primary" @click="costhandleConfirm">确定</el-button>
  159. </span>
  160. </template>
  161. </el-dialog>
  162. </el-main>
  163. </layout-content>
  164. </layout>
  165. </layout>
  166. </div>
  167. </template>
  168. <script setup>
  169. // 全量引入格式化工具 请按需保留
  170. import { Layout, LayoutSider, LayoutContent } from '@arco-design/web-vue';
  171. import {ref, reactive} from 'vue'
  172. import { useUserStore } from '@/pinia/modules/user'
  173. import { exportExcelFile } from '@/utils/excel'
  174. import {ElMessage} from "element-plus";
  175. import * as XLSX from 'xlsx'
  176. import FileSaver from 'file-saver'
  177. import LuckyExcel from 'luckyexcel';
  178. import {getSummaryTab,SummaryCostAccountingList,getProcessTab,ProcessCostAccountingList} from '@/api/jixiaoguanli/caiwubaobiao'
  179. defineOptions({name: 'Company'})
  180. const userStore = useUserStore()
  181. const _username = ref('')
  182. _username.value = userStore.userInfo.userName + '/' + userStore.userInfo.nickName
  183. // =========== 获取左侧树侧形结构 ===========
  184. const treeData = ref([]);
  185. const defaultProps = {
  186. children: 'children',
  187. label: 'label'
  188. };
  189. const getTreeData = async () => {
  190. try {
  191. const res = await getProcessTab();
  192. if (res.code === 0 && res.data) {
  193. treeData.value = Object.entries(res.data).map(([yearMonth, workshops]) => {
  194. const year = yearMonth.substring(0, 4);
  195. const month = parseInt(yearMonth.substring(4), 10);
  196. return {
  197. label: `${year}年${month}月`,
  198. value: yearMonth,
  199. children: workshops.map(workshop => ({
  200. label: workshop,
  201. value: `${yearMonth}-${workshop}`,
  202. type: 'workshop'
  203. }))
  204. };
  205. }).sort((a, b) => b.value.localeCompare(a.value)); // 按年月倒序
  206. console.log('树形数据:', treeData.value);
  207. }
  208. } catch (error) {
  209. console.error('请求出错:', error);
  210. }
  211. };
  212. getTreeData();
  213. const total = ref(0)
  214. const page = ref(1)
  215. const limit = ref(50)
  216. const nodeclick = ref('')
  217. const hztableData = ref([])
  218. const handleNodeClick = async (nodeData) => {
  219. console.log('点击节点:', nodeData);
  220. nodeclick.value = nodeData
  221. // 根据节点类型处理不同逻辑
  222. if (nodeData.value.split('-').length === 1) {
  223. // 点击了年月节点
  224. console.log('选择了年月:', nodeData.label);
  225. } else {
  226. // 点击了车间节点
  227. const [yearMonth, workshop] = nodeData.value.split('-');
  228. console.log(`选择了 ${yearMonth} 的 ${workshop}`);
  229. const res = await ProcessCostAccountingList({month:yearMonth,sist:workshop,page:page.value,limit:limit.value})
  230. console.log(res)
  231. if(res.code === 0){
  232. hztableData.value = res.data.list
  233. total.value = res.data.total
  234. }
  235. }
  236. };
  237. const handleSizeChange = (val) => {
  238. limit.value = val;
  239. handleNodeClick(nodeclick.value);
  240. }
  241. const handleCurrentChange = (val) => {
  242. page.value = val;
  243. handleNodeClick(nodeclick.value);
  244. }
  245. //导出按钮
  246. const ToExcel = async () => {
  247. try {
  248. const el = document.getElementById('tab2');
  249. // 使用table_to_sheet获取工作表对象
  250. const worksheet = XLSX.utils.table_to_sheet(el, { raw: true });
  251. //设置从C列开始为数字格式
  252. const range = XLSX.utils.decode_range(worksheet['!ref']);
  253. for (let col = 3; col <= range.e.c; col++) { // 从C列(索引2)开始
  254. for (let row = range.s.r + 1; row <= range.e.r; row++) { // 跳过表头行
  255. const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
  256. if (worksheet[cellAddress]) {
  257. // 尝试转换为数字
  258. const cellValue = worksheet[cellAddress].v;
  259. const numValue = Number(cellValue);
  260. if (!isNaN(numValue)) {
  261. worksheet[cellAddress].t = 'n'; // 数字类型
  262. worksheet[cellAddress].v = numValue; // 更新值
  263. // worksheet[cellAddress].z = '0.000'; // 数字格式
  264. }
  265. }
  266. }
  267. }
  268. // 创建并导出工作簿
  269. const workbook = XLSX.utils.book_new();
  270. XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
  271. XLSX.writeFile(workbook, '成本汇总.xlsx');
  272. } catch (error) {
  273. console.error('导出失败:', error);
  274. ElMessage.error('导出数据失败,请重试');
  275. }
  276. };
  277. const costlist = ref(false)
  278. const costMonth = ref('')
  279. const oncreate = () => {
  280. costlist.value = true;
  281. }
  282. // const costhandleConfirm = async () => {
  283. // if (!costMonth.value) {
  284. // ElMessage.error('请选择计算月份');
  285. // return;
  286. // }
  287. // try {
  288. // const qtdtAdds = await ({
  289. // month: costMonth.value,
  290. // sys_id: userStore.userInfo.nickName
  291. // });
  292. // if (qtdtAdds.code === 0) {
  293. // costlist.value = false;
  294. // ElMessage({type: 'success',message: '计算成功'})
  295. // } else {
  296. // ElMessage({type: 'error',message: '计算失败'})
  297. // }
  298. // } catch (error) {
  299. // console.error(error);
  300. // }
  301. // }
  302. </script>
  303. <style scoped>
  304. .form-container {
  305. display: flex;
  306. flex-wrap: wrap;
  307. }
  308. .form-column {
  309. /*flex: 1;*/
  310. margin-right: 15px; /* 调整列之间的间距 */
  311. }
  312. /* 左侧输入框宽度调整 */
  313. .form-column .el-form-item .el-input {
  314. width: 150px; /* 调整左侧输入框的宽度 */
  315. }
  316. :deep(.hui-plan-usage-lows div) {
  317. color: #8c939d !important;
  318. }
  319. :deep(.lan-plan-usage-lows div) {
  320. color: blue !important;
  321. font-weight: bold;
  322. }
  323. /* 媒体查询,根据需要调整断点 */
  324. @media screen and (max-width: 768px) {
  325. .form-column {
  326. flex: 1 0 100%; /* 在小屏幕下变成单列布局 */
  327. margin-right: 0;
  328. }
  329. }
  330. /*:deep(.el-table td .cell) {*/
  331. /* line-height: 30px !important;*/
  332. /*}*/
  333. .JKWTree-container {
  334. display: flex;
  335. }
  336. .JKWTree-tree {
  337. /*width: 300px;*/
  338. background-color: #fff;
  339. padding: 10px;
  340. margin-right: 20px;
  341. }
  342. .JKWTree-tree h3 {
  343. font-size: 15px;
  344. font-weight: 700;
  345. margin: 10px 0;
  346. }
  347. .JKWTree-content {
  348. flex: 1;
  349. }
  350. /* 选中某行时的背景色 */
  351. :deep(.el-table__body tr.current-row) > td {
  352. background: #ff80ff !important;
  353. }
  354. </style>
  355. <style scoped>
  356. :deep(.el-table td .cell) {
  357. line-height: 20px !important;
  358. }
  359. :deep(.el-tabs__header){
  360. margin-bottom: 0;
  361. }
  362. .search{
  363. margin-left: 0px !important;
  364. margin-right: 10px !important;
  365. }
  366. .bt{
  367. margin-left: 2px !important;
  368. padding: 3px !important;
  369. font-size: 12px;
  370. }
  371. .el-tabs__header{
  372. margin: 0px !important;
  373. }
  374. .gva-table-box{
  375. padding: 0px !important;
  376. }
  377. .mab{
  378. margin-bottom: 5px;
  379. }
  380. </style>