index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <route lang="yaml">
  2. meta:
  3. enabled: false
  4. </route>
  5. <script lang="ts" setup name="PagesExampleTable">
  6. import type { TabsPaneContext } from 'element-plus'
  7. import { ElMessage, ElMessageBox } from 'element-plus'
  8. import ObjectOAMComponent from './components/objectOAM.vue'
  9. import useSettingsStore from '@/store/modules/settings'
  10. import { getObjectById } from '@/api/biz/bizObjectApi'
  11. import { deleteObjectOAMById, getObjectOAMById, getObjectOAMByList } from '@/api/biz/bizObjectOAMApi'
  12. import { oamType, sqlType } from '@/utils/tool'
  13. const settingsStore = useSettingsStore()
  14. const route = useRoute()
  15. const router = useRouter()
  16. const tabbar = useTabbar()
  17. const bizId = parseInt(route.params.bizId.toString())
  18. const objectId = parseInt(route.params.objectId.toString())
  19. interface TreeNode {
  20. label: string
  21. isLeaf: boolean
  22. oamId: number
  23. children?: TreeNode[]
  24. }
  25. interface ObjectOAM {
  26. bizId: number
  27. objectId: number
  28. oamId: number
  29. oamTitle: string
  30. oamCode: string
  31. oamType: number
  32. oamStatement: string
  33. oamDesc: string
  34. sqlStatement: string
  35. sqlSelect: string
  36. sqlFrom: string
  37. sqlWhere: string
  38. sqlOrder: string
  39. sqlCount: string
  40. }
  41. const state = reactive({
  42. loading: false,
  43. objectTitle: '',
  44. objectCode: '',
  45. objectType: 0,
  46. keywords: '',
  47. curOamId: 0,
  48. oamList: [],
  49. objectRuleList: [],
  50. treeData: [] as TreeNode[],
  51. oam: {} as ObjectOAM,
  52. dialogState: 1,
  53. search: {
  54. bizId,
  55. objectId,
  56. keywords: '',
  57. },
  58. params: '',
  59. result: '',
  60. })
  61. const leftTreeRef = ref()
  62. const getObjectData = async () => {
  63. state.loading = true
  64. const { data } = await getObjectById(bizId, objectId)
  65. state.objectTitle = data.objectTitle
  66. state.objectCode = data.objectCode
  67. state.objectType = data.objectType
  68. state.loading = false
  69. }
  70. const getObjectOAMData = async () => {
  71. const curOamId = state.curOamId
  72. if (curOamId > 0) {
  73. state.loading = true
  74. const { data } = await getObjectOAMById(bizId, objectId, curOamId)
  75. state.oam = data
  76. state.loading = false
  77. }
  78. }
  79. const getOAMTree = async () => {
  80. const { data } = await getObjectOAMByList(state.search)
  81. data.forEach((item: any) => {
  82. state.treeData.push({
  83. label: item.oamTitle,
  84. oamId: item.oamId,
  85. isLeaf: true,
  86. })
  87. })
  88. if (data && data.length > 0) {
  89. state.curOamId = data[0].oamId
  90. nextTick(() => {
  91. leftTreeRef.value.setCurrentKey(data[0].oamId)
  92. })
  93. await getObjectOAMData()
  94. }
  95. }
  96. onMounted(() => {
  97. getObjectData()
  98. getOAMTree()
  99. })
  100. // Object OAM选择
  101. const onTreeNodeClick = (node: TreeNode) => {
  102. if (node.isLeaf) {
  103. state.curOamId = node.oamId
  104. getObjectOAMData()
  105. }
  106. }
  107. const objectOAMRef = ref()
  108. const onAddOAM = () => {
  109. objectOAMRef.value.showAddModel(bizId, objectId)
  110. }
  111. const onEditOAM = () => {
  112. objectOAMRef.value.showEditModel(bizId, objectId, state.curOamId)
  113. }
  114. const onDelete = (data: { modelId: number; objectId: number; oamId: number; oamTitle: string }) => {
  115. const { modelId, objectId, oamId, oamTitle } = data
  116. ElMessageBox.confirm(`确认删除「${oamTitle}」吗?`, '确认信息').then(async () => {
  117. await deleteObjectOAMById(modelId, objectId, oamId)
  118. await getOAMTree()
  119. ElMessage.success({
  120. message: '删除成功',
  121. center: true,
  122. })
  123. })
  124. }
  125. // 选择对象模型回调
  126. const onSuccess = () => {
  127. getOAMTree()
  128. }
  129. const activeName = ref('first')
  130. const handleClick = (tab: TabsPaneContext, event: Event) => {
  131. console.log(tab, event)
  132. }
  133. const onObjectRuleSearch = () => {
  134. }
  135. const onObjectRuleAdd = () => {
  136. }
  137. const onObjectRuleEdit = (row: { }) => {
  138. }
  139. const onObjectRuleDelete = (row: { }) => {
  140. }
  141. // 返回列表页
  142. function goBack() {
  143. if (settingsStore.settings.tabbar.enable && settingsStore.settings.tabbar.mergeTabsBy !== 'activeMenu') {
  144. tabbar.close({ name: 'biz_object_index' })
  145. }
  146. else {
  147. router.push({ name: 'biz_object_index' })
  148. }
  149. }
  150. </script>
  151. <template>
  152. <div class="absolute-container">
  153. <page-header :title="state.objectTitle" :content="state.objectCode ">
  154. <el-button size="default" round @click="goBack">
  155. <template #icon>
  156. <el-icon>
  157. <svg-icon name="i-ep:arrow-left" />
  158. </el-icon>
  159. </template>
  160. 返回
  161. </el-button>
  162. </page-header>
  163. <div class="page-main">
  164. <LayoutContainer left-side-width="250px" hide-left-side-toggle>
  165. <template #leftSide>
  166. <el-button-group class="btns">
  167. <el-button type="primary" class="add" @click="onAddOAM()">
  168. 新增对象行为
  169. </el-button>
  170. <el-button @click="getObjectOAMData">
  171. <template #icon>
  172. <el-icon>
  173. <svg-icon name="i-ep:refresh" />
  174. </el-icon>
  175. </template>
  176. </el-button>
  177. </el-button-group>
  178. <el-scrollbar class="tree">
  179. <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="oamId" @node-click="onTreeNodeClick">
  180. <template #default="{ node, data }">
  181. <div class="custom-tree-node">
  182. <div class="label" :title="node.label">
  183. <el-icon v-if="data.isLeaf" size="16px" style="margin-right: 5px;">
  184. <svg-icon name="ep:key" />
  185. </el-icon>
  186. <div class="text">
  187. {{ data.label }}
  188. </div>
  189. <div class="code">
  190. {{ oamType(data.oamType) }}
  191. </div>
  192. </div>
  193. </div>
  194. </template>
  195. </ElTree>
  196. </el-scrollbar>
  197. </template>
  198. <div class="container">
  199. <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
  200. <el-tab-pane label="行为定义" name="first">
  201. <div class="form">
  202. <tool-header>
  203. <template #right>
  204. <el-button type="primary" @click="onEditOAM">
  205. 编辑
  206. </el-button>
  207. </template>
  208. </tool-header>
  209. <page-main :title="state.oam.oamTitle">
  210. <div class="question">
  211. <ol class="answer">
  212. <li><span>编码:</span><br>{{ state.oam.oamCode }}</li>
  213. <li><span>行为类型:</span><br>{{ oamType(state.oam.oamType) }}</li>
  214. <li><span>操作类型:</span><br>{{ sqlType(state.oam.sqlType) }}</li>
  215. <li v-if="state.oam.sqlType === 1">
  216. <span>Sql:</span><br>{{ state.oam.sqlStatement }}
  217. </li>
  218. <li v-if="state.oam.oamType === 3">
  219. <span>Count</span><br>{{ state.oam.sqlCount }}
  220. </li>
  221. <li><span>说明</span><br>{{ state.oam.oamDesc }}</li>
  222. </ol>
  223. </div>
  224. </page-main>
  225. </div>
  226. </el-tab-pane>
  227. <el-tab-pane label="业务规则" name="second">
  228. <tool-bar>
  229. <template #right>
  230. <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
  231. <el-button type="primary" @click="onObjectRuleSearch">
  232. <template #icon>
  233. <el-icon>
  234. <svg-icon name="i-ep:search" />
  235. </el-icon>
  236. </template>
  237. </el-button>
  238. <el-button type="primary" size="default" @click.stop="onObjectRuleAdd">
  239. <template #icon>
  240. <el-icon>
  241. <svg-icon name="i-ep:plus" />
  242. </el-icon>
  243. </template>
  244. 业务对象
  245. </el-button>
  246. </template>
  247. </tool-bar>
  248. <el-table ref="objectRuleTableRef" v-loading="state.loading" class="list-table" :data="state.objectRuleList" border stripe highlight-current-row height="100%">
  249. <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
  250. <el-table-column prop="objectTitle" label="名称" header-align="center" align="center" width="200">
  251. <template #default="scope">
  252. <el-icon>
  253. <svg-icon name="lucide:clipboard-check" />
  254. </el-icon>
  255. <span> &nbsp;&nbsp;{{ scope.row.objectTitle }}</span>
  256. </template>
  257. </el-table-column>
  258. <el-table-column prop="objectCode" label="代码" header-align="center" align="center" width="150" />
  259. <el-table-column prop="comment" label="说明" header-align="center" align="left" />
  260. <el-table-column label="操作" header-align="center" align="center" width="230">
  261. <template #default="scope">
  262. <el-button type="warning" size="small" plain @click="onObjectRuleEdit(scope.row)">
  263. 编辑
  264. </el-button>
  265. <el-button type="danger" size="small" plain @click="onObjectRuleDelete(scope.row)">
  266. 删除
  267. </el-button>
  268. </template>
  269. </el-table-column>
  270. </el-table>
  271. </el-tab-pane>
  272. </el-tabs>
  273. </div>
  274. </LayoutContainer>
  275. </div>
  276. <ObjectOAMComponent ref="objectOAMRef" @success="getOAMTree" />
  277. </div>
  278. </template>
  279. <style lang="scss" scoped>
  280. .absolute-container {
  281. .page-header {
  282. margin-bottom: 0;
  283. }
  284. :deep(.left-side) {
  285. display: flex;
  286. flex-direction: column;
  287. height: 100%;
  288. .btns {
  289. display: inline-flex;
  290. width: 100%;
  291. .add {
  292. width: 100%;
  293. }
  294. }
  295. .tree {
  296. flex: 1;
  297. overflow-y: auto;
  298. .el-tree {
  299. .el-tree-node__content {
  300. height: 40px;
  301. }
  302. .is-current > .el-tree-node__content {
  303. background-color: var(--el-color-primary-light-9);
  304. }
  305. .custom-tree-node {
  306. flex: 1;
  307. position: relative;
  308. width: 0;
  309. height: 100%;
  310. display: flex;
  311. flex-direction: column;
  312. justify-content: center;
  313. .label {
  314. display: inline-flex;
  315. align-items: center;
  316. width: calc(100% - 10px);
  317. color: var(--el-text-color-primary);
  318. .text {
  319. @include text-overflow;
  320. }
  321. }
  322. &:hover {
  323. .actions {
  324. display: block;
  325. }
  326. }
  327. .actions {
  328. display: none;
  329. position: absolute;
  330. right: 10px;
  331. top: 50%;
  332. transform: translateY(-50%);
  333. .el-button {
  334. padding: 5px 8px;
  335. }
  336. }
  337. }
  338. }
  339. }
  340. }
  341. }
  342. .question {
  343. .answer {
  344. margin: 20px 0 0;
  345. padding-left: 20px;
  346. font-size: 16px;
  347. color: var(--el-text-color-secondary);
  348. li {
  349. margin-bottom: 10px;
  350. line-height: 1.5;
  351. &:last-child {
  352. margin-bottom: 0;
  353. }
  354. }
  355. span {
  356. color: var(--el-text-color-primary);
  357. font-weight: bold;
  358. }
  359. }
  360. }
  361. .demo-tabs > .el-tabs__content {
  362. padding: 22px;
  363. color: #6b778c;
  364. font-size: 32px;
  365. font-weight: 600;
  366. }
  367. </style>