hide-data.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. <template>
  2. <div class="h-full">
  3. <hc-page-split v-if="wbsTypeTabKey === 'tree'" ref="pageSplitRef">
  4. <template #left>
  5. <div class="left-box-container bg-white">
  6. <div class="hc-project-box">
  7. <div class="hc-project-icon-box">
  8. <HcIcon name="stack" />
  9. </div>
  10. <div class="project-name-box ml-2">
  11. <div class="project-alias">{{ projectInfo.projectName }}</div>
  12. </div>
  13. </div>
  14. <div class="hc-tree-box hc-tree-box1">
  15. <div class="hc-search-tree-val">
  16. <el-input
  17. v-model="searchTreeVal"
  18. clearable
  19. block
  20. placeholder="请输入名称关键词检索"
  21. @keyup="searchTreeKeyUp"
  22. >
  23. <template #suffix>
  24. <HcIcon
  25. name="search-2"
  26. ui="text-xl iscusor"
  27. @click="searchTreeClick"
  28. />
  29. </template>
  30. </el-input>
  31. </div>
  32. <div
  33. v-if="isShowLeft"
  34. id="hc-tree-scrollbar"
  35. v-loading="treeLoading"
  36. class="hc-tree-scrollbar"
  37. element-loading-text="获取数据中..."
  38. >
  39. <el-scrollbar
  40. v-show="isSearchTree"
  41. class="scroll-bar-right-16"
  42. >
  43. <HcDataTree
  44. :is-show-eye="true"
  45. :datas="searchTreeData"
  46. :is-mark="TreeMark"
  47. :menus="ElTreeMenu"
  48. is-type
  49. :auto-expand-keys="TreeAutoExpandKeys"
  50. is-counts default-expand-all is-form-date
  51. :is-show-sync="userInfo?.role_id?.split(',').includes('1123598816738675201')"
  52. @node-tap="wbsElTreeClick"
  53. @menu-tap="ElTreeMenuClick"
  54. />
  55. </el-scrollbar>
  56. <el-scrollbar
  57. v-show="!isSearchTree"
  58. class="scroll-bar-right-16"
  59. >
  60. <HcLazyTree
  61. ref="wbstree"
  62. :is-show-eye="true"
  63. :is-show-sync="userInfo?.role_id?.split(',').includes('1123598816738675201')"
  64. is-form-date
  65. :auto-expand-keys="TreeAutoExpandKeys"
  66. :is-mark="TreeMark"
  67. :menus="ElTreeMenu"
  68. is-counts
  69. is-type
  70. show-checkbox
  71. check-strictly
  72. @load="treeLoadNode"
  73. @menu-tap="ElTreeMenuClick"
  74. @node-loading="ElTreeNodeLoading"
  75. @node-tap="wbsElTreeClick"
  76. />
  77. </el-scrollbar>
  78. </div>
  79. </div>
  80. <div class="hc-tree-foot-tip-box">
  81. <div class="dot-view green">已审批</div>
  82. <div class="dot-view black">未填报</div>
  83. <div class="dot-view orange">已填报-待审批</div>
  84. <div class="dot-view blue">已填报-未上报</div>
  85. </div>
  86. </div>
  87. </template>
  88. <hc-tab-card
  89. :tabs="authBtnTabdata"
  90. :tab-key="authBtnTabKey"
  91. @change="authBtnTabClick"
  92. >
  93. <el-scrollbar
  94. v-if="ListItemDatas.length > 0"
  95. ref="ListItemScrollRef"
  96. >
  97. <CollapseForm
  98. ref="ListItemRef"
  99. :contract-info="
  100. contractInfo?.contractType === 2
  101. ? nodeDataInfo?.contractIdRelation
  102. : contractId
  103. "
  104. :tree-auto-expand-keys="TreeAutoExpandKeys"
  105. :classify="authBtnTabKey"
  106. :contract-id="contractId"
  107. :datas="ListItemDatas"
  108. :draw-type="!isDrawType"
  109. :primary-key-id="primaryKeyId"
  110. :status="NodeStatus"
  111. :tenant-id="userInfo?.tenant_id"
  112. :wbs-temp-id="
  113. projectInfo?.referenceWbsTemplateIdTrial
  114. "
  115. :wbs-type="2"
  116. :treenode-data-info="nodeDataInfo"
  117. :newlistdata="newlistdata"
  118. @offset-top="ListItemOffsetTop"
  119. @renew="getTableDataAll"
  120. @get-list="searchNodeAllTable1"
  121. />
  122. </el-scrollbar>
  123. <hc-empty v-else title="暂无表单" />
  124. </hc-tab-card>
  125. </hc-page-split>
  126. </div>
  127. </template>
  128. <script setup>
  129. import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
  130. import { useRoute, useRouter } from 'vue-router'
  131. import { useAppStore } from '~src/store'
  132. import CollapseForm from './collapse-form/index.vue'
  133. import { getStoreValue, setStoreValue } from '~src/utils/storage'
  134. import {
  135. arrToKey,
  136. deepClone,
  137. getArrValue,
  138. getObjValue,
  139. isNullES,
  140. } from 'js-fast-way'
  141. import {
  142. userConfigSave,
  143. } from '~api/other'
  144. import wbsApi from '~api/data-fill/wbs'
  145. import queryApi from '~api/data-fill/query'
  146. import nodeBaseApi from '~api/data-fill/nodebaseinfo'
  147. import { useClick } from 'hc-vue3-ui'
  148. import { HcDelMsg, NewDelMsg } from 'hc-vue3-ui'
  149. import { toPdfPage } from '~uti/btn-auth'
  150. import website from '~src/config'
  151. //初始变量
  152. const router = useRouter()
  153. const useRoutes = useRoute()
  154. const useAppState = useAppStore()
  155. //全局变量
  156. const projectId = ref(useAppState.projectId)
  157. const contractId = ref(useAppState.contractId)
  158. const projectInfo = ref(useAppState.projectInfo)
  159. const contractInfo = ref(useAppState.contractInfo)
  160. const isCollapse = ref(useAppState.getCollapse)
  161. const userInfo = ref(useAppState.getUserInfo)
  162. const isLayout = ref(useAppState.isLayout)
  163. const leftWidth = ref(440)
  164. const isTemplateType = ref(useAppState.contractInfo?.templateType === 2)
  165. //路由参数
  166. const routerQuery = useRoutes?.query
  167. // const typeName = routerQuery?.type || 'map'
  168. const typeName = routerQuery?.type || 'tree'
  169. //是否是抽屉
  170. const isDrawType = ref(true)
  171. //自动展开缓存
  172. const TreeAutoExpandKeys = ref(getStoreValue('wbsTreeExpandKeys') || [])
  173. //树搜索
  174. const isSearchTree = ref(false)
  175. const searchTreeHeight = ref()
  176. const getSearchTreeData = async (type) => {
  177. treeLoading.value = true
  178. let response
  179. response = await queryApi.getTreeNodeByQueryValueAndContractId({
  180. contractId: contractId.value,
  181. tableOwner: authBtnTabKey.value,
  182. queryValue: searchTreeVal.value,
  183. })
  184. const { error, code, data } = response
  185. if (!error && code === 200) {
  186. let treedata = getArrValue(data)
  187. searchTreeData.value = treedata
  188. treeLoading.value = false
  189. } else {
  190. treeLoading.value = false
  191. searchTreeData.value = []
  192. }
  193. }
  194. //监听
  195. const searchTreeVal = ref('')
  196. watch(
  197. () => [useAppState.getCollapse, searchTreeVal.value],
  198. ([Collapse, search]) => {
  199. isCollapse.value = Collapse
  200. if (search.length == 0) {
  201. isSearchTree.value = false
  202. }
  203. },
  204. )
  205. //加载树需要的classType
  206. const classType = ref('')
  207. watch(
  208. () => [classType.value, useAppState.isLayout],
  209. ([classify, isLay]) => {
  210. isLayout.value = isLay || ''
  211. if (classify) {
  212. //重新加载左边树
  213. isShowLeft.value = false
  214. setTimeout(() => {
  215. isShowLeft.value = true
  216. }, 500)
  217. }
  218. },
  219. )
  220. const pageSplitRef = ref(null)
  221. watch(() => pageSplitRef.value?.leftPanelWidth, (newWidth) => {
  222. leftWidth.value = newWidth
  223. setUserConfig(newWidth)
  224. })
  225. //渲染完成
  226. onMounted(() => {
  227. console.log(projectInfo.value)
  228. treeLoading.value = typeName === 'tree'
  229. const treeWidth = useAppState.getTreeWidth
  230. leftWidth.value = isNullES(treeWidth) || treeWidth <= 0 ? 440 : treeWidth
  231. setContractType(contractInfo.value?.contractType)
  232. nextTick(() => {
  233. pageSplitRef.value?.setLeftWidth(leftWidth.value)
  234. })
  235. })
  236. //身份按钮切换数据
  237. const authBtnTabKey = ref('1')
  238. //变量
  239. const wbstree = ref(null)
  240. const isShowLeft = ref(true)
  241. const authBtnTabClick = (val) => {
  242. if (!primaryKeyId.value) {
  243. window?.$message?.warning('请先在左侧项目树选择一个节点')
  244. } else if (val['key'] !== authBtnTabKey.value) {
  245. authBtnTabKey.value = val['key']
  246. //重新加载左边树
  247. isShowLeft.value = false
  248. setTimeout(() => {
  249. isShowLeft.value = true
  250. }, 500)
  251. getTableDataAll()
  252. }
  253. }
  254. //contractType, 1施工,2监理
  255. const setContractType = (contractType) => {
  256. if (contractType <= 0) {
  257. authBtnTabKey.value = '1'
  258. classType.value = '1'
  259. } else if (contractType === 3) {
  260. authBtnTabKey.value = '1'
  261. classType.value = '1'
  262. } else {
  263. authBtnTabKey.value = contractType + ''
  264. classType.value = contractType + ''
  265. }
  266. }
  267. const getTableDataAll = async (key) => {
  268. await searchNodeAllTable()
  269. await queryNodeStatus()
  270. //保存后自动展开到当前表单
  271. if (!isNullES(key)) {
  272. console.log(key)
  273. await nextTick(() => {
  274. ListItemRef.value?.setCollapseKey(key)
  275. })
  276. }
  277. }
  278. //结构类型tab数据和相关处理
  279. const wbsTypeTabKey = ref(typeName)
  280. const authBtnTabdata = ref([
  281. { key: '1', name: '施工质检' },
  282. { key: '2', name: '监理质检' },
  283. ])
  284. const wbsTypeTabChange = (item) => {
  285. wbsTypeTabKey.value = item?.key
  286. ListItemDatas.value = []
  287. isDrawer.value = false
  288. treeLoading.value = typeName === 'tree'
  289. setStoreValue('classifyType', classType.value)
  290. setStoreValue('tableOwner', authBtnTabKey.value)
  291. //路由跳转
  292. router.push({
  293. path: useRoutes.path,
  294. query: {
  295. type: item?.key,
  296. classifyType: classType.value,
  297. tableOwner: authBtnTabKey.value,
  298. },
  299. })
  300. getSearchTreeData()
  301. }
  302. //切换导图结构
  303. const wbsMapTypeTab = () => {
  304. wbsTypeTabChange({ key: 'map', name: '导图结构填报' })
  305. }
  306. //设置图纸数据
  307. const setUploadDrawingsData = async (echoParams, link) => {
  308. const info = nodeDataInfo.value
  309. const { error, code, data } = await wbsApi.saveContractTreeDrawings(
  310. {
  311. fileUrl: link,
  312. id: echoParams['drawingsId'],
  313. primaryKeyId: echoParams['primaryKeyId'],
  314. },
  315. false,
  316. )
  317. //处理数据
  318. if (!error && code === 200) {
  319. if (info['primaryKeyId'] === echoParams['primaryKeyId']) {
  320. nodeDataInfo.value['drawingsId'] = data
  321. nodeDataInfo.value['fileUrl'] = link
  322. window?.$message?.success('图纸上传成功')
  323. } else {
  324. window?.$message?.success(
  325. '图纸上传成功,由于您切换了其他节点,需要手动刷新才能查看到图纸',
  326. )
  327. }
  328. } else {
  329. window?.$message?.error('图纸保存失败')
  330. }
  331. }
  332. //设置树菜单数据
  333. const ElTreeMenu = ref([])
  334. const TreeMark = ref(false)
  335. //树相关变量
  336. const primaryKeyId = ref('')
  337. const nodeItemInfo = ref({})
  338. const nodeDataInfo = ref({})
  339. const searchTreeData = ref([])
  340. //回车
  341. const searchTreeKeyUp = (e) => {
  342. if (e.key === 'Enter') {
  343. searchTreeClick()
  344. }
  345. }
  346. const treeLoading = ref(true)
  347. const searchTreeClick = async () => {
  348. if (searchTreeVal.value) {
  349. searchTreeHeight.value
  350. = document.getElementById('hc-tree-scrollbar').offsetHeight
  351. isSearchTree.value = true
  352. //treeLoading.value = true
  353. getSearchTreeData()
  354. } else {
  355. isSearchTree.value = false
  356. }
  357. }
  358. //懒加载的数据
  359. const treeLoadNode = async ({ node, item, level }, resolve) => {
  360. let contractIdRelation = '',
  361. parentId = '',
  362. primaryKeyId = ''
  363. if (level !== 0) {
  364. const nodeData = getObjValue(item)
  365. contractIdRelation = nodeData?.contractIdRelation || ''
  366. parentId = contractIdRelation ? nodeData?.primaryKeyId : nodeData?.id
  367. primaryKeyId = nodeData?.id || ''
  368. }
  369. //获取数据
  370. const { data } = await queryApi.queryWbsTreeData({
  371. contractId: contractId.value || '',
  372. contractIdRelation,
  373. primaryKeyId,
  374. parentId,
  375. // classifyType: authBtnTabKey.value,
  376. classifyType: classType.value,
  377. tableOwner: authBtnTabKey.value,
  378. dataTime:new Date(),
  379. })
  380. treeLoading.value = false
  381. resolve(getArrValue(data))
  382. }
  383. //树被点击
  384. const wbsElTreeClick = ({ node, data, keys }) => {
  385. nodeItemInfo.value = node
  386. nodeDataInfo.value = data
  387. primaryKeyId.value = data?.primaryKeyId || ''
  388. const { notExsitChild } = data
  389. const { hasChildren } = data
  390. if (notExsitChild || !hasChildren) {
  391. getTableDataAll()
  392. } else {
  393. ListItemDatas.value = []
  394. NodeStatus.value = '1'
  395. }
  396. setStoreValue('wbsTreeExpandKeys', keys)
  397. TreeAutoExpandKeys.value = keys || []
  398. // getTableDataAll()
  399. }
  400. //树加载完成
  401. const ElTreeNodeLoading = () => {
  402. treeLoading.value = false
  403. }
  404. //树菜单被点击
  405. const ElTreeMenuClick = async ({ key, node, data, keys }) => {
  406. nodeItemInfo.value = node
  407. nodeDataInfo.value = data
  408. setStoreValue('wbsTreeExpandKeys', keys)
  409. TreeAutoExpandKeys.value = keys || []
  410. }
  411. //设置滚动条位置
  412. const ListItemScrollRef = ref(null)
  413. const ListItemOffsetTop = (offsetTop) => {
  414. if (offsetTop > 0) {
  415. setTimeout(() => {
  416. ListItemScrollRef.value?.setScrollTop(offsetTop)
  417. }, 350)
  418. } else {
  419. ListItemScrollRef.value?.setScrollTop(offsetTop)
  420. }
  421. }
  422. //获取数据列表
  423. const ListItemDatas = ref([])
  424. const ListItemLoading = ref(false)
  425. const searchNodeAllTable = async () => {
  426. ListItemLoading.value = true
  427. ListItemDatas.value = []
  428. const info = nodeDataInfo.value
  429. const { data } = await wbsApi.searchNodeAllTable({
  430. projectId: projectId.value,
  431. contractId: contractId.value,
  432. primaryKeyId: info['primaryKeyId'],
  433. type: authBtnTabKey.value,
  434. })
  435. ListItemDatas.value = getArrValue(data)
  436. ListItemLoading.value = false
  437. }
  438. //获取文件题名
  439. const newlistdata = ref([])
  440. const searchNodeAllTable1 = async () => {
  441. console.log('重新获取表单列表')
  442. const info = nodeDataInfo.value
  443. const { data } = await wbsApi.searchNodeAllTable({
  444. projectId: projectId.value,
  445. contractId: contractId.value,
  446. primaryKeyId: info['primaryKeyId'],
  447. type: authBtnTabKey.value,
  448. })
  449. newlistdata.value = getArrValue(data)
  450. }
  451. //查询状态
  452. const NodeStatus = ref('1')
  453. const queryNodeStatus = async () => {
  454. const info = nodeDataInfo.value
  455. if (contractInfo.value?.contractType == 1) {
  456. const { error, code, data } = await wbsApi.queryNodeStatus({
  457. primaryKeyId: info['primaryKeyId'],
  458. //classify:1
  459. classify: authBtnTabKey.value,
  460. })
  461. //1 未填报,2待上报,3已上报
  462. if (!error && code === 200) {
  463. NodeStatus.value = data ?? '1'
  464. } else {
  465. NodeStatus.value = '1'
  466. }
  467. } else {
  468. const { error, code, data } = await wbsApi.queryNodeStatusJl({
  469. // primaryKeyId: info['contractIdRelation'] ? info['id'] : info['primaryKeyId'],
  470. primaryKeyId: info['primaryKeyId'],
  471. //classify: 1
  472. classify: authBtnTabKey.value,
  473. })
  474. //1 未填报,2待上报,3已上报
  475. if (!error && code === 200) {
  476. NodeStatus.value = data ?? '1'
  477. } else {
  478. NodeStatus.value = '1'
  479. }
  480. }
  481. }
  482. //表单变量
  483. const ListItemRef = ref(null)
  484. const ListItemsRef = ref(null)
  485. //更新配置
  486. watch(
  487. () => leftWidth.value,
  488. (diffVal) => {
  489. setUserConfig(diffVal)
  490. },
  491. )
  492. const setUserConfig = async (data) => {
  493. if (data > 0) {
  494. await useClick()
  495. useAppState.setTreeWidth(data)
  496. await userConfigSave({ treeWidth: data })
  497. }
  498. }
  499. </script>
  500. <style lang="scss" scoped>
  501. @import "../../styles/data-fill/wbs.scss";
  502. .back-button {
  503. /* 确保按钮有足够的空间来展示放大效果 */
  504. padding: 4px;
  505. /* 过渡效果:所有属性变化在300ms内完成,使用ease-out缓动函数 */
  506. transition: all 300ms ease-out;
  507. /* 防止放大时内容溢出 */
  508. overflow: hidden;
  509. }
  510. /* 缩放状态的样式 */
  511. .back-button.scaling {
  512. /* 放大到1.2倍 */
  513. transform: scale(1.2);
  514. }
  515. .hc-project-box{
  516. display: flex;
  517. justify-content: space-between;
  518. align-items: center;
  519. // font-size:20px;
  520. }
  521. .title-input{
  522. height: 30px;
  523. padding: 10px;
  524. border: 1px solid #dcdfe6;
  525. background-color: #dcdfe6;
  526. line-height: 13px;
  527. border-radius: 5px;
  528. font-weight: 500;
  529. margin-left: 4px;
  530. max-width: 300px;
  531. overflow-x: auto;
  532. overflow-y: hidden;
  533. }
  534. .hc-add-node-modal-foot-box {
  535. position: relative;
  536. display: flex;
  537. align-items: center;
  538. .left-box {
  539. position: relative;
  540. flex: 1;
  541. display: flex;
  542. align-items: center;
  543. }
  544. .right-box {
  545. position: relative;
  546. }
  547. }
  548. .hc-expansion-contraction-tree {
  549. position: absolute;
  550. left: -13px;
  551. top: 0;
  552. width: 10px;
  553. height: 100%;
  554. user-select: none;
  555. cursor: pointer;
  556. display: flex;
  557. justify-content: center;
  558. align-items: center;
  559. color: #8c9099;
  560. font-size: 22px;
  561. border-radius: 5px;
  562. transition: background 0.2s;
  563. background: rgba(255, 255, 255, 0);
  564. &:hover {
  565. background: #f1f5f8;
  566. color: var(--el-color-primary);
  567. }
  568. }
  569. .hc-table-form-action-tip {
  570. position: absolute;
  571. bottom: 77px;
  572. width: 100%;
  573. }
  574. .data-fill-wbs-hide-btn {
  575. background: #fff;
  576. color: #ffffff;
  577. }
  578. html.dark .data-fill-wbs-hide-btn {
  579. background: #141414;
  580. color: #141414;
  581. }
  582. html.theme-dark {
  583. .bg-svg-xml {
  584. background-color: initial;
  585. background-image: initial;
  586. }
  587. .hc-layout-box
  588. .hc-layout-content-box
  589. .hc-card-max-h-box.node-tree
  590. .hc-tree-foot-tip-box {
  591. border-top: 1px solid #303030;
  592. }
  593. }
  594. </style>
  595. <style lang="scss">
  596. .hc-tree-box1 .el-tree-node {
  597. .el-checkbox {
  598. margin-right: 0;
  599. .el-checkbox__inner {
  600. display: none;
  601. }
  602. }
  603. .is-leaf + .el-checkbox {
  604. margin-right: 8px;
  605. .el-checkbox__inner {
  606. display: inline-block;
  607. }
  608. }
  609. }
  610. .data-fill-wbs-content {
  611. position: relative;
  612. height: 100%;
  613. .n-drawer-container {
  614. margin: -20px -24px;
  615. }
  616. .n-drawer.n-drawer--top-placement {
  617. height: auto !important;
  618. background-color: initial;
  619. pointer-events: none;
  620. bottom: 0;
  621. }
  622. .drawer-data-fill-content-box {
  623. position: relative;
  624. height: 100%;
  625. padding: 24px;
  626. .n-card {
  627. pointer-events: auto;
  628. height: 100%;
  629. overflow: auto;
  630. }
  631. .data-fill-content {
  632. position: relative;
  633. height: 100%;
  634. overflow-y: auto;
  635. scroll-behavior: smooth;
  636. .data-fill-list-box .data-fill-list-item-content {
  637. height: calc(100vh - 470px);
  638. .data-fill-table-form-box {
  639. height: 100%;
  640. }
  641. }
  642. }
  643. .data-fill-foot {
  644. position: relative;
  645. text-align: center;
  646. }
  647. }
  648. }
  649. .n-card.hc-card-overflow-box .n-card__content {
  650. padding: 24px;
  651. }
  652. .n-card.hc-custom-card > .n-card-header {
  653. padding: 15px 24px;
  654. }
  655. .n-card.hc-custom-card.copy {
  656. width: 1200px;
  657. max-height: 90vh;
  658. overflow: auto;
  659. .n-card-header .n-card-header__close {
  660. display: none;
  661. }
  662. &.one {
  663. width: 600px;
  664. }
  665. &.many {
  666. width: 1200px;
  667. }
  668. }
  669. .img-preview-box {
  670. position: relative;
  671. height: 100%;
  672. width: 100%;
  673. }
  674. .hc-layout-content-box {
  675. position: relative;
  676. }
  677. .iscusor {
  678. cursor: pointer;
  679. }
  680. .hc-table-form-action-tip .hc-alert {
  681. background-color: #f1f5f8;
  682. display: inline;
  683. vertical-align: middle;
  684. box-shadow: -2px 0 10px 0 rgba(32, 37, 50, 0.03),
  685. 0 10px 21px 20px rgba(32, 37, 50, 0.03);
  686. }
  687. .copy-node-form-box {
  688. margin-top: 24px;
  689. padding-top: 24px;
  690. border-top: 1px solid #efeff5;
  691. }
  692. .hc-position-input-icon {
  693. position: relative;
  694. margin-bottom: 0;
  695. .el-form-item__content {
  696. position: relative;
  697. .el-textarea .el-textarea__inner {
  698. padding-right: 30px;
  699. }
  700. .hc-icon-i {
  701. position: absolute;
  702. right: 10px;
  703. bottom: 0;
  704. font-size: 20px;
  705. cursor: pointer;
  706. color: #0081ff;
  707. opacity: 1;
  708. transition: opacity 0.2s;
  709. &:hover {
  710. opacity: 0.5;
  711. }
  712. }
  713. }
  714. }
  715. </style>
  716. <style lang="scss" scoped>
  717. .hc-tree-back-to{
  718. display: flex;
  719. justify-content: space-between;
  720. }
  721. /* 新增拖拽排序相关样式 */
  722. .sortable-ghost {
  723. opacity: 0.5;
  724. background: #f5f5f5;
  725. justify-content: center;
  726. }
  727. .hc-attachment-item {
  728. transition: all 0.3s;
  729. cursor: move;
  730. display: flex;
  731. justify-content: space-between;
  732. align-items: center;
  733. padding: 12px;
  734. margin-bottom: 8px;
  735. background: #fff;
  736. border-radius: 4px;
  737. border: 1px solid #ebeef5;
  738. &:hover {
  739. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  740. }
  741. }
  742. .hc-attachment-content {
  743. min-height: 20px;
  744. }
  745. /* 原有样式保持不变 */
  746. .hc-attachment-card {
  747. margin-bottom: 16px;
  748. .hc-attachment-header {
  749. font-weight: bold;
  750. margin-bottom: 8px;
  751. padding-left: 8px;
  752. border-left: 3px solid #409eff;
  753. }
  754. .hc-attachment-file-name {
  755. display: flex;
  756. align-items: center;
  757. .name {
  758. margin-left: 8px;
  759. }
  760. }
  761. .hc-attachment-btn-box {
  762. display: flex;
  763. }
  764. }
  765. </style>
  766. <style>
  767. .custom-tooltip-pro {
  768. background-color: #7691E0 !important;
  769. color: white !important;
  770. border: none !important;
  771. max-width: 300px !important; /* 最大宽度 */
  772. padding: 10px !important;
  773. font-size: 14px;
  774. }
  775. .tooltip-content {
  776. width: 100%;
  777. }
  778. .new-folder {
  779. display: flex;
  780. justify-content: space-between;
  781. align-items: center;
  782. padding: 8px 5px;
  783. margin-bottom: 5px;
  784. border-bottom: 1px solid rgba(255, 255, 255, 0.3);
  785. cursor: pointer;
  786. }
  787. .add-icon {
  788. font-size: 18px;
  789. }
  790. .add-input-container {
  791. display: flex;
  792. align-items: center;
  793. gap: 8px;
  794. padding: 8px 5px;
  795. margin-bottom: 8px;
  796. background: white;
  797. }
  798. .folder-input {
  799. flex: 1;
  800. background-color: rgba(255, 255, 255, 1);
  801. border: none;
  802. border-radius: 4px;
  803. }
  804. .input-buttons {
  805. display: flex;
  806. gap: 8px;
  807. }
  808. .confirm-icon {
  809. color: #4CAF50;
  810. font-size: 18px;
  811. }
  812. .cancel-icon {
  813. color: #f44336;
  814. font-size: 18px;
  815. }
  816. .folder-list-container {
  817. max-height: 200px; /* 最大高度 */
  818. overflow-y: auto; /* 超出滚动 */
  819. overflow-x: hidden;
  820. }
  821. .folder-item {
  822. display: flex;
  823. justify-content: space-between;
  824. align-items: center;
  825. padding: 8px 5px;
  826. white-space: nowrap;
  827. text-overflow: ellipsis;
  828. overflow: hidden;
  829. }
  830. .folder-name {
  831. margin-right: 15px; /* 名称与删除图标间距 */
  832. flex: 1;
  833. overflow: hidden;
  834. text-overflow: ellipsis;
  835. }
  836. .delete-icon {
  837. font-size: 18px;
  838. flex-shrink: 0; /* 防止图标被压缩 */
  839. }
  840. /* 滚动条样式优化 */
  841. .folder-list-container::-webkit-scrollbar {
  842. width: 6px;
  843. }
  844. .folder-list-container::-webkit-scrollbar-thumb {
  845. background-color: rgba(255, 255, 255, 0.3);
  846. border-radius: 3px;
  847. }
  848. </style>