index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. <template>
  2. <div>
  3. <layout>
  4. <layout-header>
  5. <div class="">
  6. <!--按钮部分-->
  7. <el-form
  8. ref="elSearchFormRef"
  9. inline
  10. class="demo-form-inline"
  11. @submit.native.prevent
  12. >
  13. <el-form-item>
  14. <el-input
  15. v-model="searchInfo"
  16. placeholder="搜索产品编号或产品名称"
  17. clearable
  18. style="width: 180px;"
  19. />
  20. <el-button
  21. type="primary"
  22. icon="search"
  23. class="search"
  24. @click="handleSearch"
  25. />
  26. <el-button
  27. type="primary"
  28. icon="edit"
  29. class="bt"
  30. @click="() => {dialogDetail = true}"
  31. ><i class="el-icon-edit" />查改
  32. </el-button>
  33. <!-- <el-button type="primary" disabled icon="edit" @click="" style="margin-left: 10px">工艺方案复制</el-button>-->
  34. <el-button
  35. type="primary"
  36. icon="edit"
  37. class="bt"
  38. @click="()=>{dialogGdcjstj = true}"
  39. >工单超节损统计
  40. </el-button>
  41. <el-button
  42. type="primary"
  43. icon="edit"
  44. class="bt"
  45. @click="()=>{dialogKhsz = true}"
  46. >考核设置
  47. </el-button>
  48. <el-button
  49. type="primary"
  50. icon="edit"
  51. class="bt"
  52. @click="()=>{dialogXzgdtl = true}"
  53. >修正工单投料
  54. </el-button>
  55. <el-button
  56. type="primary"
  57. icon="edit"
  58. class="bt"
  59. @click="()=>{dialogGxclhc = true}"
  60. >工序产量核查
  61. </el-button>
  62. <el-button
  63. type="primary"
  64. icon="edit"
  65. class="bt"
  66. @click="()=>{dialogGdzjfptj = true}"
  67. >工单质检废品统计
  68. </el-button>
  69. <el-button
  70. type="primary"
  71. icon="edit"
  72. class="bt"
  73. @click="()=>{dialogHjfpfb = true}"
  74. >核检废品分布
  75. </el-button>
  76. <el-button
  77. type="primary"
  78. icon="edit"
  79. class="bt"
  80. @click="handleGddy"
  81. >工单打印
  82. </el-button>
  83. <el-button
  84. type="primary"
  85. icon="edit"
  86. class="bt"
  87. @click="()=>{pd_lcdlist = true; pd_lcdProductValue()}"
  88. >流程单查询
  89. </el-button>
  90. <el-button
  91. type="primary"
  92. icon="edit"
  93. class="bt"
  94. @click="testExcel"
  95. >导出测试
  96. </el-button>
  97. </el-form-item>
  98. </el-form>
  99. <!-- 弹窗 -->
  100. <div>
  101. <!-- 查改 -->
  102. <Detail
  103. v-if="dialogDetail"
  104. :is-show="dialogDetail"
  105. :gdbh="gdbh"
  106. @destroy="()=>{dialogDetail = false}"
  107. />
  108. <!-- 工单超节损统计 -->
  109. <el-dialog
  110. v-model="dialogGdcjstj"
  111. title="工单超节损统计"
  112. destroy-on-close
  113. >
  114. <Gdcjstj :gdbh="gdbh" />
  115. </el-dialog>
  116. <!-- 修正工单印件质量考核设置 -->
  117. <Khsz
  118. v-if="dialogKhsz"
  119. v-model="dialogKhsz"
  120. :gdbh="gdbh"
  121. />
  122. <!-- 修正工单投料 -->
  123. <Xzgdtl
  124. v-if="dialogXzgdtl"
  125. v-model="dialogXzgdtl"
  126. :date="date"
  127. />
  128. <!-- 工序产量核查 -->
  129. <Gxclhc
  130. v-if="dialogGxclhc"
  131. v-model="dialogGxclhc"
  132. :gdbh="gdbh"
  133. />
  134. <!-- 工单质检废品统计 -->
  135. <Gongdanzhijianfeipintongji
  136. v-if="dialogGdzjfptj"
  137. v-model="dialogGdzjfptj"
  138. :val="gdbh"
  139. />
  140. <!-- 核检废品分布 -->
  141. <Hjfpfb
  142. v-if="dialogHjfpfb"
  143. v-model="dialogHjfpfb"
  144. :val="gdbh"
  145. />
  146. <!-- 工单打印 -->
  147. <PrintPage ref="printPageRef" />
  148. <!--流程单查询【弹窗】-->
  149. <el-dialog
  150. v-model="pd_lcdlist"
  151. title="工单工序生产进程"
  152. fullscreen
  153. >
  154. <div style="width: 100%;height: 100%;">
  155. <el-button
  156. type=""
  157. @click="()=>{pd_lcdlist = false}"
  158. >退出</el-button>
  159. </div>
  160. <div style="width: 100%; height: 100%; display: flex; align-items: center;">
  161. <el-form-item
  162. label="工单编号"
  163. style="margin-right: 20px; padding: 0;"
  164. >
  165. <el-input
  166. v-model="pd_lcdformData['gdbh']"
  167. @keyup.enter="pd_lcdProductValue"
  168. />
  169. </el-form-item>
  170. <el-form-item
  171. label=""
  172. style="margin-right: 5px; padding: 0;"
  173. >
  174. <el-input
  175. v-model="pd_lcdformData['code']"
  176. disabled
  177. />
  178. </el-form-item>
  179. <el-form-item
  180. label=""
  181. style="margin-right: 5px; padding: 0;"
  182. >
  183. <el-input
  184. v-model="pd_lcdformData['name']"
  185. disabled
  186. style="width: 500px"
  187. />
  188. </el-form-item>
  189. </div>
  190. <div style="width: 100%; height: 70vh; display: flex;">
  191. <layout>
  192. <layout-sider
  193. :resize-directions="['right']"
  194. :width="240"
  195. style="margin-right: 10px;height: 70vh;"
  196. >
  197. <div class="JKWTree-tree">
  198. <el-tree
  199. :data="pd_lcd_treeData"
  200. default-expand-all
  201. @node-click="pd_lcd_handleNodeClick"
  202. />
  203. </div>
  204. </layout-sider>
  205. <layout-main>
  206. <!-- 这里放右侧的内容 -->
  207. <el-space wrap>
  208. <!-- 右侧内容 -->
  209. <template v-for="item in processList.total_process">
  210. <el-button
  211. disabled
  212. :type="! processList.process.includes(item) ? 'danger' : 'info'"
  213. plain
  214. style="width: 50px"
  215. >{{ item }}</el-button>
  216. </template>
  217. </el-space>
  218. </layout-main>
  219. </layout>
  220. </div>
  221. </el-dialog>
  222. </div>
  223. </div>
  224. </layout-header>
  225. <layout>
  226. <!-- 左侧树侧形结构-->
  227. <layout-sider
  228. :resize-directions="['right']"
  229. :width="190"
  230. style="margin-right: 10px;"
  231. >
  232. <div
  233. class="JKWTree-tree"
  234. style="height: 70vh;"
  235. >
  236. <h3> 工单超节损核算</h3>
  237. <el-tree
  238. :data="treeData"
  239. highlight-current
  240. @node-click="handleNodeClick"
  241. />
  242. </div>
  243. </layout-sider>
  244. <!-- 右侧内容区域 -->
  245. <layout-content>
  246. <!-- 上方列表 -->
  247. <div class="gva-table-box">
  248. <el-table
  249. style="width: 100%;height:30vh;"
  250. :data="tableData1"
  251. row-key="ID"
  252. highlight-current-row
  253. border
  254. :row-class-name="rowClassName"
  255. :cell-class-name="cellClassName"
  256. :row-style="{ height: '20px' }"
  257. :cell-style="{ padding: '0px' }"
  258. :header-row-style="{ height: '20px' }"
  259. :header-cell-style="{ padding: '0px' }"
  260. @row-click="showOrderSuperLossGy"
  261. @current-change="(row, oldRow) => { currentRow = row}"
  262. >
  263. <el-table-column
  264. type="selection"
  265. width="55"
  266. />
  267. <!-- 使用 v-for 循环渲染每一列 -->
  268. <el-table-column
  269. v-for="column in tableCols1"
  270. :key="column.prop"
  271. :prop="column.prop"
  272. :label="column.label"
  273. :width="column.width"
  274. show-overflow-tooltip="true"
  275. sortable
  276. />
  277. </el-table>
  278. </div>
  279. <!-- 下方表格 -->
  280. <el-table
  281. style="width: 100%;height: 40vh;"
  282. row-key="ID"
  283. highlight-current-row
  284. border
  285. :data="tableData2"
  286. :row-style="{ height: '20px' }"
  287. :cell-style="{ padding: '0px' }"
  288. :header-row-style="{ height: '20px' }"
  289. :header-cell-style="{ padding: '0px' }"
  290. >
  291. <el-table-column
  292. type="selection"
  293. width="55"
  294. />
  295. <!-- 使用 v-for 循环渲染每一列 -->
  296. <el-table-column
  297. v-for="column in tableCols2"
  298. :key="column.prop"
  299. :prop="column.prop"
  300. :label="column.label"
  301. :width="column.width"
  302. show-overflow-tooltip="true"
  303. sortable
  304. />
  305. </el-table>
  306. </layout-content>
  307. </layout>
  308. </layout>
  309. </div>
  310. </template>
  311. <script>
  312. import service from '@/utils/request'
  313. // 5.1流程单查询-工单工序生产进程菜单栏
  314. export const getOrderProcessLeft = (params) => {
  315. return service({
  316. url: '/mes_server/work_order_verification/getOrderProcessLeft',
  317. method: 'get',
  318. params
  319. })
  320. }
  321. // 5.2流程单查询-获取工单工序生产进程右侧
  322. export const getOrderProcessRight = (params) => {
  323. return service({
  324. url: '/mes_server/work_order_verification/getOrderProcessRight',
  325. method: 'get',
  326. params
  327. })
  328. }
  329. </script>
  330. <script setup>
  331. import { Layout, LayoutContent, LayoutHeader, LayoutSider } from '@arco-design/web-vue'
  332. import { ref, watch } from 'vue'
  333. import { getOrderSuperLossGy, getSide, getTable } from '@/api/mes_api_gty/orderAccounting'
  334. import Gdcjstj from '@/view/performance/12-orderAccounting/componets/gdcjstj.vue'
  335. import Khsz from '@/view/performance/12-orderAccounting/componets/khsz.vue'
  336. import Xzgdtl from '@/view/performance/12-orderAccounting/componets/xzgdtl.vue'
  337. import Gxclhc from '@/view/performance/12-orderAccounting/componets/gxclhc.vue'
  338. import Gongdanzhijianfeipintongji
  339. from '@/view/performance/09-workOrderVerification/componets/gongdanzhijianfeipintongji.vue'
  340. import Detail from '@/view/performance/12-orderAccounting/componets/detail.vue'
  341. import Hjfpfb from './componets/hjfpfb.vue'
  342. import PrintPage from '@/view/yunyin/shengchanguanli/components/print.vue'
  343. import { reactive } from 'vue'
  344. import { exportExcelFile } from '@/utils/excel'
  345. import { useUserStore } from '@/pinia/modules/user'
  346. const userStore = useUserStore()
  347. const sys_id='['+userStore.userInfo.userName+'/'+userStore.userInfo.nickName+']'
  348. // 弹窗
  349. const dialogGdcjstj = ref(false)
  350. const dialogDetail = ref(false)
  351. const dialogKhsz = ref(false)
  352. const dialogXzgdtl = ref(false)
  353. const dialogGxclhc = ref(false)
  354. const dialogGdzjfptj = ref(false)
  355. const dialogHjfpfb = ref(false)
  356. // 侧边栏数据
  357. const treeData = ref([])
  358. const getSideData = async() => {
  359. const res = await getSide()
  360. if (res.code === 0) {
  361. const { data } = res
  362. const transformedData = []
  363. for (const [key, value] of Object.entries(data)) {
  364. const [date, total] = key.split('-') // 提取日期和数量
  365. const transformedItem = {
  366. label: `${date}(工单数:${total})`,
  367. date: date,
  368. children: value.map(item => ({
  369. label: `${item['客户编号']}【${item['客户名称']}】(工单数:${item.total})`,
  370. date: date,
  371. code: item?.['客户编号'],
  372. })),
  373. }
  374. transformedData.push(transformedItem)
  375. }
  376. treeData.value = transformedData
  377. }
  378. }
  379. getSideData()
  380. // 表格数据
  381. const tableCols1 = [
  382. { label: '超损工单', prop: 'csgd', width: '90' },
  383. { label: '工单编号', prop: 'Gd_gdbh', width: '100' },
  384. { label: '印件号', prop: 'jjcp_yjno', width: '100' },
  385. { label: '联数', prop: 'yj_ls', width: '80' },
  386. { label: '产品代号', prop: '成品编码', width: '150' },
  387. { label: '产品名称', prop: '成品名称', width: '250' },
  388. { label: '实际投料', prop: '实际投料', width: '100' },
  389. { label: '计量单位', prop: '计量单位', width: '100' },
  390. { label: '入仓日期', prop: 'warehousing_date', width: '120' },
  391. { label: '入仓数量', prop: 'warehousing_num', width: '100' },
  392. { label: '目标合格率', prop: 'target_rate', width: '100' },
  393. { label: '实际合格率', prop: 'real_rate', width: '100' },
  394. { label: '奖惩系数', prop: 'reward_rate', width: '100' },
  395. { label: '奖罚金额合计', prop: '', width: '120' },
  396. { label: '废品合计', prop: '废品合计', width: '100' },
  397. { label: '工单无形损', prop: '工单无形损', width: '100' },
  398. { label: '材料废', prop: '材料废', width: '100' },
  399. { label: '零头处理', prop: '零头处理', width: '100' },
  400. { label: '处发废', prop: '外发废', width: '100' },
  401. { label: '外摊废', prop: '分摊废', width: '100' },
  402. { label: '工单计划损耗', prop: '工单计划损耗', width: '120' },
  403. { label: '工单制程废', prop: '', width: '100' },
  404. { label: '工单检验废', prop: '工单质检废', width: '100' },
  405. { label: '年月', prop: 'date', width: '100' },
  406. ]
  407. const tableCols2 = [
  408. { label: '工单编号', prop: 'Gy0_gdbh', width: '100' },
  409. { label: '印件及工序', prop: 'Gy0_yjno', width: '100' },
  410. { label: '工序名称', prop: 'Gy0_gxmc', width: '200' },
  411. { label: '联数', prop: 'Gy0_ls', width: '80' },
  412. { label: '基础损耗', prop: 'Gy0_Rate0', width: '100' },
  413. { label: '损耗率', prop: 'Gy0_Rate1', width: '100' },
  414. { label: '损耗系数', prop: '损耗系数', width: '100' },
  415. { label: '计损色数', prop: 'Gy0_ms', width: '100' },
  416. { label: '计划产量', prop: 'Gy0_计划接货数', width: '100' },
  417. { label: '计划损耗', prop: 'Gy0_计划损耗', width: '100' },
  418. { label: '上报产量', prop: 'total_cl', width: '100' },
  419. { label: '制程废', prop: 'total_fp', width: '100' },
  420. ]
  421. const tableData1 = ref([])
  422. const tableData2 = ref([])
  423. const currentRow = ref({})
  424. const gdbh = ref('')
  425. const date = ref('')
  426. const searchInfo = ref('')
  427. watch(currentRow, (value, oldValue, onCleanup) => {
  428. gdbh.value = value?.['Gd_gdbh']
  429. date.value = value?.['date']
  430. pd_lcdformData['gdbh'] = value?.['Gd_gdbh']
  431. })
  432. // 显示上方表格
  433. const handleNodeClick = async(node) => {
  434. console.log(node)
  435. if (!node.children) {
  436. const { date, code } = node
  437. const res = await getTable({ date, code, limit: 9999, page: 1 })
  438. tableData1.value = res.data.data.map(item => ({
  439. ...item,
  440. csgd: parseFloat(item['target_rate']) - parseFloat(item['real_rate']) > 0 ? '√' : '',
  441. date: date,
  442. }))
  443. console.log(res.data)
  444. } else {
  445. // console.log(node.date, node.code)
  446. }
  447. }
  448. // 显示下方表格
  449. const showOrderSuperLossGy = async() => {
  450. const { Gd_gdbh: order } = currentRow.value
  451. const res = await getOrderSuperLossGy({ order })
  452. if (res.code === 0) {
  453. const { data } = res
  454. tableData2.value = data.map(item => ({
  455. ...item,
  456. Gy0_yjno: `${item.Gy0_yjno}-${item.Gy0_gxh}`,
  457. Gy0_gxmc: item.Add_gxmc === '' ? item.Gy0_gxmc : `${item.Gy0_gxmc}〖${item.Add_gxmc}〗`,
  458. }))
  459. }
  460. }
  461. // 定位
  462. const handleSearch = () => {
  463. if (searchInfo.value) {
  464. tableData1.value = tableData1.value.filter(item => {
  465. return item['Gd_gdbh'] === searchInfo.value ?? item
  466. })
  467. }
  468. }
  469. /* const rowClassName = ({ row, rowIndex }) => {
  470. if (row['csgd'] === '√') {
  471. return 'yellow-row'
  472. }
  473. return ''
  474. }*/
  475. const cellClassName = ({ row, column, rowIndex, columnIndex }) => {
  476. if ([7, 11, 13, 21].includes(columnIndex)) {
  477. return 'red-cell'
  478. }
  479. return ''
  480. }
  481. const printPageRef = ref()
  482. function handleGddy() {
  483. printPageRef.value.open(gdbh.value)
  484. }
  485. const pd_lcdlist = ref(false)
  486. const processList = ref([])
  487. const pd_lcdformData = reactive({})
  488. const pd_lcdProductValue = async() => {
  489. _getOrderProcessLeft_list()
  490. }
  491. const pd_lcd_treeData = ref([])
  492. const _getOrderProcessLeft_list = async() => {
  493. const order = pd_lcdformData['gdbh']
  494. console.log(order)
  495. try {
  496. // 5.1流程单查询-工单工序生产进程菜单栏
  497. const getOrderProcessLeft_list = await getOrderProcessLeft({ order: order })
  498. console.log(getOrderProcessLeft_list)
  499. pd_lcdformData['code'] = getOrderProcessLeft_list.data.Gd_info['code']
  500. pd_lcdformData['name'] = getOrderProcessLeft_list.data.Gd_info['name']
  501. pd_lcd_treeData.value = [{
  502. label: order + '-' + getOrderProcessLeft_list.data.Gd_info['name'],
  503. // label: order + '-' + getOrderProcessLeft_list.data.Gd_info['code'] + '-' + getOrderProcessLeft_list.data.Gd_info['name'],
  504. value: undefined,
  505. children: []
  506. }]
  507. const newData = []
  508. for (const key in getOrderProcessLeft_list.data.Gy_info) {
  509. const temp = getOrderProcessLeft_list.data.Gy_info[key]
  510. const concatenatedValue = `${temp.Gy0_yjno}-${temp.Gy0_gxh} ---> ${temp.Gy0_gxmc}`
  511. newData.push({ label: concatenatedValue, value: temp.Gy0_gxh })
  512. }
  513. pd_lcd_treeData.value[0].children = newData
  514. // 5.2流程单查询-获取工单工序生产进程右侧【进入页面默认显示第一个】
  515. const getOrderProcessRight_list = await getOrderProcessRight({ order: order, gxNo: newData[0].value })
  516. processList.value = getOrderProcessRight_list.data
  517. } catch (error) {
  518. console.error(error)
  519. }
  520. }
  521. const pd_lcd_handleNodeClick = async(node) => {
  522. if (node.value === undefined) return
  523. const order = pd_lcdformData['gdbh']
  524. // //5.2流程单查询-获取工单工序生产进程右侧
  525. const getOrderProcessRight_list = await getOrderProcessRight({ order: order, gxNo: node.value })
  526. console.log(getOrderProcessRight_list)
  527. processList.value = getOrderProcessRight_list.data
  528. }
  529. const testExcel = () => {
  530. const data = [
  531. {
  532. '第一列': '111',
  533. '第二列': '222',
  534. '第三列': '333',
  535. '第四列': '444',
  536. },
  537. {
  538. '第一列': '111',
  539. '第二列': '222',
  540. '第三列': '333',
  541. },
  542. {
  543. '第一列': '111',
  544. '第二列': '222',
  545. '第三列': '333',
  546. },
  547. {
  548. '第一列': '111',
  549. '第二列': '222',
  550. '第三列': '333',
  551. },
  552. ]
  553. exportExcelFile(data);
  554. }
  555. </script>
  556. <style scoped>
  557. :deep(.plan-usage-low div) {
  558. color: red !important;
  559. }
  560. .JKWTree-container {
  561. display: flex;
  562. }
  563. .JKWTree-tree {
  564. width: 100%;
  565. background-color: #fff;
  566. /*background-color: rgba(241, 224, 224, 0.99);*/
  567. padding: 10px;
  568. margin-right: 20px;
  569. }
  570. .JKWTree-tree h3 {
  571. font-size: 15px;
  572. font-weight: 700;
  573. margin: 10px 0;
  574. }
  575. .JKWTree-content {
  576. flex: 1;
  577. }
  578. :deep(.el-table .yellow-row) {
  579. background: #FFFF80;
  580. }
  581. :deep(.red-cell div) {
  582. color: #FF0000 !important;
  583. }
  584. /* 选中某行时的背景色 */
  585. :deep(.el-table__body tr.current-row) > td {
  586. background: #ff80ff !important;
  587. }
  588. </style>
  589. <style scoped>
  590. :deep(.el-table td .cell) {
  591. line-height: 20px !important;
  592. }
  593. :deep(.el-tabs__header) {
  594. margin-bottom: 0;
  595. }
  596. .search {
  597. margin-left: 0px !important;
  598. margin-right: 10px !important;
  599. }
  600. .bt {
  601. margin-left: 2px !important;
  602. padding: 3px !important;
  603. font-size: 12px;
  604. }
  605. .el-tabs__header {
  606. margin: 0px !important;
  607. }
  608. .gva-table-box {
  609. padding: 0px !important;
  610. }
  611. .mab {
  612. margin-bottom: 5px;
  613. }
  614. </style>