houyaf 3 tahun lalu
induk
melakukan
45898464c4

+ 1 - 1
src/api/index.ts

@@ -12,7 +12,7 @@ export function signIn(data: any) {
 // 获取授权
 export function getPermit() {
   return apiRequest({
-    url: '/app/user/permit',
+    url: '/user/permit',
     method: 'GET',
   })
 }

+ 1 - 1
src/api/system/wfDefApi.ts

@@ -69,7 +69,7 @@ export function updateWfDef(data: any) {
  * @returns
  * @param wfDefId
  */
-export function deleteWfDef(wfDefId: number) {
+export function deleteWfDefById(wfDefId: number) {
   return apiRequest({
     url: `/wf/def/${wfDefId}`,
     method: 'DELETE',

+ 144 - 0
src/views/workflow/def/components/WfActivityDef.vue

@@ -0,0 +1,144 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { createWfActivityDef, getWfActivityDefById, updateWfActivityDef } from '@/api/system/wfActivityDefApi'
+const emit = defineEmits(['success'])
+
+const formRef = ref<FormInstance>()
+const formRules = ref<FormRules>({
+  wfDefId: [
+    { required: true, message: '请选择流程定义', trigger: 'blur' },
+  ],
+  activityDefTitle: [
+    { required: true, message: '请输入标题', trigger: 'blur' },
+  ],
+  activityCode: [
+    { required: true, message: '请输入标题', trigger: 'blur' },
+  ],
+  formCode: [
+    { required: true, message: '请输入描述', trigger: 'blur' },
+  ],
+  activityDefDesc: [
+    { required: false, message: '请输入简要说明', trigger: 'blur' },
+  ],
+})
+
+const state = reactive({
+  title: '',
+  dialogVisible: false,
+  loading: false,
+  formData: {
+    wfDefId: 0,
+    activityDefId: 0,
+    activityDefTitle: '',
+    activityCode: '',
+    formCode: '',
+    ractivityDefDesc: '',
+  },
+  search: {
+    wfDefId: 0,
+    activityDefId: 0,
+  },
+  actionType: 1,
+})
+
+onMounted(() => {})
+
+const getData = async () => {
+  state.loading = true
+  const { wfDefId, activityDefId } = state.search
+  const { data } = await getWfActivityDefById(wfDefId, activityDefId)
+  state.loading = false
+  state.formData = data
+}
+
+function onSubmit() {
+  formRef.value && formRef.value.validate(async (valid) => {
+    if (valid) {
+      if (state.actionType === 1) {
+        const { msg } = await createWfActivityDef(state.formData)
+        ElMessage.success(msg)
+        state.dialogVisible = false
+        emit('success')
+      }
+      else {
+        const { msg } = await updateWfActivityDef(state.formData)
+        ElMessage.success(msg)
+        state.dialogVisible = false
+        emit('success')
+      }
+    }
+  })
+}
+
+function onCancel() {
+  state.dialogVisible = false
+}
+
+function resetFormData() {
+  state.formData = {
+    wfDefId: 0,
+    activityDefId: 0,
+    activityDefTitle: '',
+    activityCode: '',
+    formCode: '',
+    ractivityDefDesc: '',
+  }
+}
+
+defineExpose({
+  showAddModel(wfDefId: number) {
+    resetFormData()
+    state.search.wfDefId = wfDefId
+    state.formData.wfDefId = wfDefId
+    state.title = '新增'
+    state.actionType = 1
+    state.dialogVisible = true
+  },
+  showEditModel(wfDefId: number, activityDefId: number) {
+    resetFormData()
+    state.search.wfDefId = wfDefId
+    state.search.activityDefId = activityDefId
+    state.title = '编辑'
+    state.actionType = 2
+    state.dialogVisible = true
+    getData()
+  },
+})
+</script>
+
+<template>
+  <el-drawer v-model="state.dialogVisible" :title="state.title" width="600px" :close-on-click-modal="false" append-to-body destroy-on-close>
+    <el-form ref="formRef" :model="state.formData" :rules="formRules" label-width="120px" label-suffix=":">
+      <el-form-item label="关卡名称" prop="activityDefTitle">
+        <el-input v-model="state.formData.activityDefTitle" placeholder="请输入标题" />
+      </el-form-item>
+
+      <el-form-item label="关卡编码" prop="activityCode">
+        <el-input v-model="state.formData.activityCode" placeholder="编码" />
+      </el-form-item>
+
+      <el-form-item label="表单编码" prop="formCode">
+        <el-input v-model="state.formData.formCode" placeholder="编码" />
+      </el-form-item>
+
+      <el-form-item label="简要说明" prop="activityDefDesc">
+        <el-input v-model="state.formData.activityDefDesc" type="textarea" rows="10" placeholder="请输入简要说明" />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <el-button size="large" @click="onCancel">
+        取消
+      </el-button>
+      <el-button type="primary" size="large" @click="onSubmit">
+        保存
+      </el-button>
+    </template>
+  </el-drawer>
+</template>

+ 124 - 0
src/views/workflow/def/components/WfActivityDefList.vue

@@ -0,0 +1,124 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup>
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { deleteWfActivityDefById, getWfActivityDefByList } from '@/api/system/wfActivityDefApi'
+
+const state = reactive({
+  loading: false,
+  activityDefList: [],
+  search: {
+    wfDefId: -1,
+    keywords: '',
+  },
+})
+
+const activityDefTreeRef = ref()
+
+// 查询帐号列表
+const getWfActivityDefData = async () => {
+  state.loading = true
+  const { data } = await getWfActivityDefByList(state.search.wfDefId)
+  state.loading = false
+  state.activityDefList = data.data
+  state.loading = false
+}
+
+const activityDefTableRef = ref()
+const activityDefRef = ref()
+
+// 查询
+const onSearch = () => {
+  getWfActivityDefData()
+}
+
+// 新增
+const onActivityDefAdd = () => {
+  activityDefRef.value.showAddModel()
+}
+
+// 修改账号
+const onActivityDefEdit = (row: any) => {
+  activityDefRef.value.showEditModel(row.groupId, row.accountId)
+}
+
+// 删除
+const onActivityDefDelete = (row: any) => {
+  const { wfDefId, activityDefId, activityDefTitle } = row
+  ElMessageBox.confirm(`确认删除「${activityDefTitle}」吗?`, '确认信息').then(async () => {
+    const { msg } = await deleteWfActivityDefById(wfDefId, activityDefId)
+    ElMessage.success(msg)
+    await getWfActivityDefData()
+  })
+}
+</script>
+
+<template>
+  <div class="container">
+    <tool-bar>
+      <template #left>
+        <span />
+      </template>
+
+      <template #right>
+        <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
+        <el-button type="primary" @click="onSearch">
+          <template #icon>
+            <el-icon>
+              <svg-icon name="i-ep:search" />
+            </el-icon>
+          </template>
+        </el-button>
+
+        <el-button type="primary" @click="onActivityDefAdd">
+          新增
+        </el-button>
+      </template>
+    </tool-bar>
+
+    <el-table ref="activityDefTreeRef" v-loading="state.loading" class="list-table" :data="state.dataList" border stripe highlight-current-row>
+      <el-table-column type="selection" width="50" align="center" />
+      <el-table-column type="index" align="center" label="序号" width="70" />
+
+      <el-table-column width="250px" label="Activity名称" align="center" header-align="center">
+        <template #default="scope">
+          <span>{{ scope.row.activityDefTitle }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column width="150px" label="Activity Code" align="center" header-align="center">
+        <template #default="scope">
+          <span>{{ scope.row.activityCode }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column width="150px" label="Form Code" align="center" header-align="center">
+        <template #default="scope">
+          <span>{{ scope.row.formCode }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="说明" align="left" header-align="center">
+        <template #default="scope">
+          <span>{{ scope.row.activityDefDesc }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="操作" width="150" align="center" fixed="right">
+        <template #default="scope">
+          <div>
+            <el-button type="primary" size="small" plain @click="onActivityDefEdit(scope.row)">
+              编辑
+            </el-button>
+            <el-button v-if="!scope.row.isFixed" type="danger" size="small" plain @click="onActivityDefDelete(scope.row)">
+              删除
+            </el-button>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>

+ 112 - 0
src/views/workflow/def/components/WfDef.vue

@@ -0,0 +1,112 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { createWfDef, getWfDefById, updateWfDef } from '@/api/system/wfDefApi'
+const emit = defineEmits(['success'])
+
+const formRef = ref<FormInstance>()
+const formRules = ref<FormRules>({
+  wfDefTitle: [
+    { required: true, message: '请输入标题', trigger: 'blur' },
+  ],
+  wfDefDesc: [
+    { required: false, message: '请输入描述', trigger: 'blur' },
+  ],
+})
+
+const state = reactive({
+  title: '',
+  dialogVisible: false,
+  loading: false,
+  formData: {
+    wfDefId: 0,
+    wfDefTitle: '',
+    wfDefDesc: '',
+  },
+  actionType: 1,
+})
+
+onMounted(() => {})
+
+const getData = async (wfDefId: number) => {
+  state.loading = true
+  const { data } = await getWfDefById(wfDefId)
+  state.loading = false
+  state.formData = data
+}
+
+function onSubmit() {
+  formRef.value && formRef.value.validate(async (valid) => {
+    if (valid) {
+      if (state.actionType === 1) {
+        const { msg } = await createWfDef(state.formData)
+        ElMessage.success(msg)
+        state.dialogVisible = false
+        emit('success')
+      }
+      else {
+        const { msg } = await updateWfDef(state.formData)
+        ElMessage.success(msg)
+        state.dialogVisible = false
+        emit('success')
+      }
+    }
+  })
+}
+
+function onCancel() {
+  state.dialogVisible = false
+}
+
+function resetFormData() {
+  state.formData = {
+    wfDefId: 0,
+    wfDefTitle: '',
+    wfDefDesc: '',
+  }
+}
+
+defineExpose({
+  showAddModel() {
+    resetFormData()
+    state.title = '新增'
+    state.actionType = 1
+    state.dialogVisible = true
+  },
+  showEditModel(roleId: number) {
+    resetFormData()
+    state.title = '编辑'
+    state.actionType = 2
+    state.dialogVisible = true
+    getData(roleId)
+  },
+})
+</script>
+
+<template>
+  <el-drawer v-model="state.dialogVisible" :title="state.title" width="600px" :close-on-click-modal="false" append-to-body destroy-on-close>
+    <el-form ref="formRef" :model="state.formData" :rules="formRules" label-width="120px" label-suffix=":">
+      <el-form-item label="名称" prop="roleName">
+        <el-input v-model="state.formData.wfDefTitle" placeholder="请输入标题" />
+      </el-form-item>
+
+      <el-form-item label="简要说明" prop="roleDesc">
+        <el-input v-model="state.formData.wfDefDesc" type="textarea" rows="10" placeholder="请输入标题" />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <el-button size="large" @click="onCancel">
+        取消
+      </el-button>
+      <el-button type="primary" size="large" @click="onSubmit">
+        保存
+      </el-button>
+    </template>
+  </el-drawer>
+</template>

+ 211 - 0
src/views/workflow/def/components/WfDefList.vue

@@ -0,0 +1,211 @@
+<route lang="yaml">
+meta:
+  enabled: false
+</route>
+
+<script lang="ts" setup>
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { deleteWfDefById, getWfDefByList } from '@/api/system/wfDefApi'
+
+interface TreeNode {
+  label: string
+  isLeaf: boolean
+  wfDefId: number
+  children?: TreeNode[]
+}
+
+interface Object {
+  wfDefId: number
+  wfDefTitle: string
+  wfDefDesc: string
+}
+
+const state = reactive({
+  loading: false,
+  keywords: '',
+  treeData: [] as TreeNode[],
+  curWfDefId: 0,
+  dataList: [] as Object[],
+  dialogState: 1,
+  search: {
+    keywords: '',
+  },
+})
+
+const leftTreeRef = ref()
+
+const getWfDefData = async () => {
+  const { data } = await getWfDefByList({})
+  const children: TreeNode[] = []
+  data.forEach((item: any) => {
+    return children.push({
+      label: item.wfDefTitle,
+      wfDefId: item.wfDefId,
+      isLeaf: true,
+    })
+  })
+  state.treeData = [
+    {
+      label: '工作流程',
+      isLeaf: false,
+      wfDefId: -1,
+      children,
+    },
+  ]
+
+  if (data && data.length > 0) {
+    state.curWfDefId = data[0].wfDefId
+    await nextTick(() => {
+      leftTreeRef.value.setCurrentKey(data[0].wfDefId)
+    })
+  }
+}
+
+onMounted(() => {
+  getWfDefData()
+})
+
+// 模型选择
+const onTreeNodeClick = (node: TreeNode) => {
+  if (node.isLeaf) {
+    state.curWfDefId = node.wfDefId
+  }
+}
+
+const wfDefRef = ref()
+// 新增
+const onWfDefAdd = () => {
+  wfDefRef.value.showAddModel()
+}
+
+// 编辑
+const onWfDefEdit = (row: { wfDefId: number }) => {
+  const wfDefId = state.curWfDefId
+  if (wfDefId > 0) {
+    wfDefRef.value.showEditModel(wfDefId)
+  }
+}
+
+// 删除
+const onWfDefDelete = (row: any) => {
+  const { wfDefId, wfDefTitle } = row
+  ElMessageBox.confirm(`确认删除「${wfDefTitle}」吗?`, '确认信息').then(async () => {
+    const { msg } = await deleteWfDefById(wfDefId)
+    ElMessage.success(msg)
+    await getWfDefData()
+  })
+}
+</script>
+
+<template>
+  <el-scrollbar class="tree">
+    <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="wfDefId" @node-click="onTreeNodeClick">
+      <template #default="{ node, data }">
+        <div class="custom-tree-node">
+          <div class="label" :title="node.label">
+            <el-icon v-if="data.isLeaf" size="16px" style="margin-right: 5px;">
+              <svg-icon name="ep:office-building" />
+            </el-icon>
+            <div class="text">
+              {{ data.label }}
+            </div>
+          </div>
+
+          <div class="actions">
+            <el-button-group>
+              <el-button type="primary" plain size="small" @click.stop="onWfDefAdd()">
+                <template #icon>
+                  <el-icon>
+                    <svg-icon name="i-ep:plus" />
+                  </el-icon>
+                </template>
+              </el-button>
+
+              <el-button type="info" plain size="small" @click.stop="onWfDefEdit(data)">
+                <template #icon>
+                  <el-icon>
+                    <svg-icon name="i-ep:edit" />
+                  </el-icon>
+                </template>
+              </el-button>
+
+              <el-button type="danger" plain size="small" @click.stop="onWfDefDelete(data)">
+                <template #icon>
+                  <el-icon>
+                    <svg-icon name="i-ep:delete" />
+                  </el-icon>
+                </template>
+              </el-button>
+            </el-button-group>
+          </div>
+        </div>
+      </template>
+    </ElTree>
+  </el-scrollbar>
+</template>
+
+<style lang="scss" scoped>
+.btns {
+  display: inline-flex;
+  width: 100%;
+  margin-bottom: var(--container-padding);
+
+  .add {
+    width: 100%;
+  }
+}
+
+.tree {
+  flex: 1;
+  overflow-y: auto;
+
+  .el-tree {
+    .el-tree-node__content {
+      height: 40px;
+    }
+
+    .is-current > .el-tree-node__content {
+      background-color: var(--el-color-primary-light-9);
+    }
+
+    .custom-tree-node {
+      flex: 1;
+      position: relative;
+      width: 0;
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+
+      .label {
+        display: inline-flex;
+        align-items: center;
+        width: calc(100% - 10px);
+        color: var(--el-text-color-primary);
+
+        .text {
+          @include text-overflow;
+        }
+      }
+
+      &:hover {
+        .actions {
+          display: block;
+        }
+      }
+
+      .actions {
+        display: none;
+        position: absolute;
+        right: 10px;
+        top: 50%;
+        transform: translateY(-50%);
+
+        .el-button {
+          padding: 5px 8px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 16 - 16
src/views/workflow/def/index.vue

@@ -4,24 +4,24 @@ meta:
 </route>
 
 <script lang="ts" setup>
-const value = ref(true)
-const value1 = ref(true)
-const value2 = ref(true)
-const value3 = ref(false)
+import WfDefListComponent from './components/WfDefList.vue'
+import WfActivityDefListComponent from './components/WfActivityDefList.vue'
+const wDefListRef = ref()
+const wfActivityDefListRef = ref()
 </script>
 
 <template>
-  <div>
-    <page-header title="开关" />
-    <page-main title="基础用法" class="demo">
-      <el-switch v-model="value" active-color="#13ce66" inactive-color="#ff4949" />
-    </page-main>
-    <page-main title="文字描述" class="demo">
-      <el-switch v-model="value1" active-text="按月付费" inactive-text="按年付费" />
-    </page-main>
-    <page-main title="禁用状态" class="demo">
-      <el-switch v-model="value2" disabled style="margin-right: 10px;" />
-      <el-switch v-model="value3" disabled />
-    </page-main>
+  <div class="absolute-container">
+    <tool-header title="客户分类" />
+
+    <div class="page-main">
+      <LayoutContainer left-side-width="250px" hide-left-side-toggle>
+        <template #leftSide>
+          <WfDefListComponent ref="wfDefListRef" />
+        </template>
+
+        <WfActivityDefListComponent ref="wfActivityDefListRef" />
+      </LayoutContainer>
+    </div>
   </div>
 </template>