tab-cost.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <template>
  2. <HcCard>
  3. <div class="hc-page-layout-box system-parameter">
  4. <HcCardItem ui="hac-card-item w-60 mr-5">
  5. <template #header>
  6. <span class="mr-2">成本测算分类:</span>
  7. <el-button _icon hc-btn size="small" type="primary" @click="openpriceEdit(1)">
  8. <HcIcon name="add" />
  9. </el-button>
  10. </template>
  11. <div> <span class="mt-2">测算一级科目:</span></div>
  12. <div class="hc-layout-left-box menu mt-3">
  13. <div class="hc-menu-contents-box">
  14. <el-scrollbar>
  15. <HcMenuSimple
  16. :datas="menuOptions" :keys="menuKey" :props="menusProps"
  17. :menus="contextMenu" @menu-tap="contextMenuClick"
  18. @change="menuChange"
  19. />
  20. </el-scrollbar>
  21. </div>
  22. <!-- 预算分类新增编辑弹窗 -->
  23. <HcDialog bg-color="#ffffff" widths="22rem" is-to-body :show="priceModal" :title="priceTitle" @close="priceModalClose" @save="saveparentClick">
  24. <el-form :model="priceform" label-position="top" label-width="auto" size="large">
  25. <el-form-item label="测算一级科目名称:">
  26. <el-input v-model="priceform.dictName" />
  27. </el-form-item>
  28. <el-form-item label="测算一级科目值:">
  29. <el-input v-model="priceform.dictValue" />
  30. </el-form-item>
  31. <el-form-item label="序号:" prop="sort">
  32. <el-input v-model="priceform.sort" oninput="value=value.replace(/[^\d]/g,'')" />
  33. </el-form-item>
  34. </el-form>
  35. </HcDialog>
  36. </div>
  37. </HcCardItem>
  38. <div class="hc-page-content-box">
  39. <HcCardItem ui="hac-card-item" action-size="lg">
  40. <template #header>
  41. <span class="mr-2">测算二级科目:</span>
  42. <el-button _icon hc-btn size="small" type="primary" @click="openEdit(1)">
  43. <HcIcon name="add" />
  44. </el-button>
  45. </template>
  46. <HcTable :column="tableColumn" :datas="tableData" :is-index="false" :loading="tableLoaing">
  47. <template #action="{ row }">
  48. <el-button size="small" type="primary" @click="openEdit(2, row)">
  49. 编辑
  50. </el-button>
  51. <el-button size="small" type="primary" @click="delTask(row)">
  52. 删除
  53. </el-button>
  54. </template>
  55. </HcTable>
  56. <!-- 任务明细弹窗 -->
  57. <HcDialog bg-color="#ffffff" widths="24rem" is-to-body :show="editTaskModal" :title="taskTitle" @close="testModalClose" @save="savechilidClick">
  58. <el-form label-position="top" label-width="auto" :model="formLabelAlign" size="large">
  59. <el-form-item label="测算二级科目名称:">
  60. <el-input v-model="formLabelAlign.dictName" />
  61. </el-form-item>
  62. <el-form-item label="测算一级科目值:">
  63. <el-input v-model="formLabelAlign.dictValue" />
  64. </el-form-item>
  65. <el-form-item label="序号:" prop="sort">
  66. <el-input v-model="formLabelAlign.sort" oninput="value=value.replace(/[^\d]/g,'')" />
  67. </el-form-item>
  68. </el-form>
  69. </HcDialog>
  70. </HcCardItem>
  71. </div>
  72. </div>
  73. </HcCard>
  74. </template>
  75. <script setup>
  76. import { onMounted, ref, watch } from 'vue'
  77. import { getChildList, getParentList, removeDictionary, submitDictionary } from '~api/system/parameter.js'
  78. import { getArrValue } from 'js-fast-way'
  79. const props = defineProps({
  80. cur: {
  81. type: [String, Number],
  82. default: '',
  83. },
  84. type:{
  85. type: [String, Number],
  86. default: '',
  87. },
  88. })
  89. const tabsKey = ref(props.cur)
  90. const tabsType = ref(props.type)
  91. //监听
  92. watch(() => [
  93. props.cur,
  94. props.type,
  95. ], ([key, type]) => {
  96. tabsKey.value = key
  97. tabsType.value = type
  98. })
  99. onMounted(() => {
  100. setContextMenu()
  101. getParentListData()
  102. })
  103. //左侧菜单
  104. const menuKey = ref('')
  105. const menuOptions = ref([])
  106. const menuItem = ref({})
  107. const menuChange = (item) => {
  108. console.log(item)
  109. menuKey.value = item?.id
  110. menuItem.value = item
  111. getChildListData()
  112. }
  113. const menusProps = ref({
  114. key: 'id',
  115. label: 'dictName',
  116. })
  117. //菜单的右键菜单
  118. const contextMenu = ref([])
  119. const setContextMenu = () => {
  120. let newArr = []
  121. newArr.push({ icon: 'draft', label: '编辑分类', key: 'edit' })
  122. newArr.push({ icon: 'delete-bin', label: '删除分类', key: 'del' })
  123. contextMenu.value = newArr
  124. }
  125. //菜单的右键菜单被点击
  126. const contextMenuClick = ({ key, item }) => {
  127. console.log(item, 'item')
  128. menuKey.value = item?.id
  129. if (key === 'edit') {
  130. openpriceEdit(2)
  131. menuKey.value = item?.id
  132. priceform.value.dictName = item.dictName
  133. } else if (key === 'del') {
  134. window?.$messageBox?.alert('您确定要删除该预算分类信息吗? 一旦注销数据将彻底清除,请谨慎操作?', '删除提醒', {
  135. showCancelButton: true,
  136. confirmButtonText: '确认注销',
  137. cancelButtonText: '取消',
  138. type: 'warning',
  139. callback: async (action) => {
  140. if (action === 'confirm') {
  141. const { error, code, msg } = await removeDictionary({
  142. ids: item?.id,
  143. })
  144. if (!error && code === 200) {
  145. window?.$message?.success('删除成功')
  146. getParentListData()
  147. } else {
  148. window?.$message?.warning(msg)
  149. }
  150. }
  151. },
  152. })
  153. }
  154. }
  155. const priceTitle = ref('')
  156. const priceModal = ref(false)
  157. const openpriceEdit = (type) => {
  158. if (type === 1) {
  159. priceTitle.value = '新增分类'
  160. priceform.value = {}
  161. menuKey.value = ''
  162. } else {
  163. priceTitle.value = '编辑分类'
  164. }
  165. priceModal.value = true
  166. }
  167. const priceform = ref({})
  168. const priceModalClose = () => {
  169. priceModal.value = false
  170. }
  171. const taskTitle = ref('')
  172. const openEdit = (type, row) => {
  173. if (type === 1) {
  174. formLabelAlign.value.dictName = ''
  175. formLabelAlign.value.id = ''
  176. taskTitle.value = '新增'
  177. } else {
  178. formLabelAlign.value.dictName = row.dictName
  179. formLabelAlign.value.id = row.id
  180. taskTitle.value = '编辑'
  181. }
  182. if (menuKey.value) {
  183. editTaskModal.value = true
  184. } else {
  185. window.$message.warning('请先选择一级科目')
  186. }
  187. }
  188. const editTaskModal = ref(false)
  189. const testModalClose = () => {
  190. editTaskModal.value = false
  191. }
  192. const delTask = (item) => {
  193. window?.$messageBox?.alert('您确定要删除该预算科目信息吗? 一旦注销数据将彻底清除,请谨慎操作?', '删除提醒', {
  194. showCancelButton: true,
  195. confirmButtonText: '确认注销',
  196. cancelButtonText: '取消',
  197. type: 'warning',
  198. callback: async (action) => {
  199. if (action === 'confirm') {
  200. const { error, code, msg } = await removeDictionary({
  201. ids: item?.id,
  202. })
  203. if (!error && code === 200) {
  204. window?.$message?.success('删除成功')
  205. getParentListData()
  206. } else {
  207. window?.$message?.warning(msg)
  208. }
  209. }
  210. },
  211. })
  212. }
  213. const tableColumn = [
  214. { key: 'dictName', name: '预算二级科目', align:'center' },
  215. // {key: 'text', name: '任务内容'},
  216. // {key: 'color', name: '完成指标'},
  217. { key: 'action', name: '操作', width: 200 },
  218. ]
  219. const tableData = ref([])
  220. const tableLoaing = ref(false)
  221. const formLabelAlign = ref({
  222. name: '',
  223. region: '',
  224. type: '',
  225. })
  226. //新增一级科目
  227. const saveparentClick = async ()=>{
  228. const { error, code, msg } = await submitDictionary({
  229. type:tabsType.value,
  230. dictName:priceform.value?.dictName,
  231. id:menuKey.value || null,
  232. })
  233. if (!error && code === 200) {
  234. window.$message?.success(msg)
  235. priceModal.value = false
  236. getParentListData()
  237. } else {
  238. window.$message?.warning(msg)
  239. }
  240. }
  241. //新增二级级科目
  242. const savechilidClick = async ()=>{
  243. const { error, code, msg } = await submitDictionary({
  244. type:tabsType.value,
  245. dictName:formLabelAlign.value?.dictName,
  246. id:formLabelAlign.value.id || null,
  247. parentId:menuKey.value,
  248. })
  249. if (!error && code === 200) {
  250. window.$message?.success(msg)
  251. editTaskModal.value = false
  252. getChildListData()
  253. } else {
  254. window.$message?.warning(msg)
  255. }
  256. }
  257. //获取一级科目
  258. const getParentListData = async ()=>{
  259. const { error, code, data, msg } = await getParentList({
  260. type:tabsType.value,
  261. })
  262. if (!error && code === 200) {
  263. menuOptions.value = getArrValue(data['records'])
  264. if ( menuOptions.value.length > 0) {
  265. menuKey.value = menuOptions.value[0]?.id
  266. menuItem.value.id = menuOptions.value[0]?.id
  267. getChildListData()
  268. }
  269. } else {
  270. menuOptions.value = []
  271. window.$message?.warning(msg)
  272. }
  273. }
  274. //获取二级科目
  275. const getChildListData = async ()=>{
  276. tableLoaing.value = true
  277. const { error, code, data, msg } = await getChildList({
  278. parentId: menuItem.value.id,
  279. type:tabsType.value,
  280. })
  281. tableLoaing.value = false
  282. if (!error && code === 200) {
  283. tableData.value = getArrValue(data)
  284. // tab.value = getArrValue(data['records'])
  285. } else {
  286. window.$message?.warning(msg)
  287. }
  288. }
  289. </script>
  290. <style lang="scss">
  291. .hc-page-layout-box.system-parameter {
  292. display: flex;
  293. position: relative;
  294. // height: calc(100vh - 228px);
  295. .hc-layout-left-box.menu {
  296. width: 100%;
  297. height: 100%;
  298. position: relative;
  299. background: inherit;
  300. margin-right: auto;
  301. border-radius: 0;
  302. box-shadow: none;
  303. .hc-menu-contents-box {
  304. position: relative;
  305. padding: 0;
  306. height: 100%;
  307. // height: calc(100% - 60px);
  308. }
  309. .hc-menu-simple-box {
  310. padding: 0;
  311. .item-box {
  312. box-shadow: none;
  313. padding: 8px 10px;
  314. border-radius: 4px;
  315. background: var(--el-color-primary-light-8);
  316. .label-box {
  317. color: #8c8c8c;
  318. }
  319. .menu-icon {
  320. margin-left: 20px;
  321. background: inherit;
  322. .menu-popover-icon {
  323. color: #8c8c8c;
  324. .hc-icon-i {
  325. font-size: 20px;
  326. line-height: initial;
  327. }
  328. }
  329. }
  330. }
  331. .item-box.active {
  332. background: var(--el-color-primary-light-5);
  333. .label-box {
  334. color: white;
  335. }
  336. .menu-icon .menu-popover-icon {
  337. color: white;
  338. }
  339. }
  340. }
  341. .hc-menu-header-box {
  342. position: relative;
  343. padding: 15px 18px;
  344. display: flex;
  345. align-items: center;
  346. border-bottom: 1px solid #E9E9E9;
  347. .name {
  348. flex: auto;
  349. position: relative;
  350. }
  351. }
  352. }
  353. .hc-page-content-box {
  354. flex: 1;
  355. position: relative;
  356. }
  357. }
  358. </style>