操作手册

前端代码

前端模块开发流程


front-end

  1. src/views目录中定义入口界面
  2. router.js中的routes定义页面组件导入
  3. router.js中MENUS中将菜单加入到需要放置的位置,菜单中key值和routes中的name值一一对应,权限控制需要定义auth值。
  4. src/api中增加模块统一接口调用

以凭证字模块为例:

页面实现可以采用Composition API或Options API两种方式。下面给出两种方式的实现。

列表页面(Options API):

<template>
  <div class="flex flex-column h-full p-10px bg-white-color">
    <div class="mb-10px">
      <vxe-button v-p="'setting-vouchergroup-canedit'" status="primary" @click="showForm()">新增凭证字</vxe-button>
    </div>
    <div class="flex-1 h-0px">
      <vxe-table :loading="loading" height="auto" :data="datas" :border="true">
        <vxe-column title="凭证字" field="word" width="200"></vxe-column>
        <vxe-column title="打印标题" field="printTitle" :width="120" align="center"></vxe-column>
        <vxe-column title="是否默认" :width="100" align="center">
          <template #default="{row}">
            {{ row.isDefault ? '是' : '否' }}
          </template>
        </vxe-column>
        <vxe-column title="操作">
          <template #default="{row}">
            <div class="actions" v-if="!row.isDefault">
              <span v-p="'setting-vouchergroup-canedit'" @click="showForm(row)"> <i class="fa fa-edit"></i> 编辑</span>
              <span v-p="'setting-vouchergroup-candelete'" @click="remove(row)"><i class="fa fa-trash"></i> 删除</span>
            </div>
          </template>
        </vxe-column>
      </vxe-table>
    </div>
  </div>
</template>

<script>
import setting from "@api/setting";
import {layer} from "@layui/layer-vue";
import {h} from "vue";
import VoucherWordForm from "@/views/setting/voucherWord/VoucherWordForm.vue";

export default {
  name: 'VoucherWord',
  data() {
    return {
      datas: [],
      loading: false
    };
  },
  methods: {
    loadList() {
      this.loading = true;
      setting.voucherWord.list().then(({data}) => {
        this.datas = data || [];
      }).finally(() => this.loading = false)
    },
    showForm(entity) {
      let layerId = layer.open({
        title: "凭证字信息",
        shadeClose: false,
        closeBtn: false,
        zIndex: 1000,
        area: ['400px', 'auto'],
        content: h(VoucherWordForm, {
          entity,
          onClose: () => {
            layer.close(layerId);
          },
          onSuccess: () => {
            layer.close(layerId);
            this.loadList();
          }
        })
      });
    },
    remove(data) {
      this.$Confirm("确认删除?").then(() => {
        setting.voucherWord.delete(data.id).then(() => {
          this.loadList();
        })
      })
    }
  },
  created() {
    this.loadList();
  }
};
</script>

表单页面(Composition API):

<template>
  <div class="modal-column">
    <div class="modal-column-body">
      <Form mode="block" ref="formRef" :labelWidth="100" :model="form" :rules="{}">
        <FormItem label="凭证字" prop="word" required>
          <Input type="text" v-model="form.word"/>
        </FormItem>
        <FormItem label="打印标题" prop="printTitle" required>
          <Input type="text" v-model="form.printTitle"/>
        </FormItem>
        <FormItem label="是否默认" prop="isDefault">
          <Radio v-model="form.isDefault" dict="defaultRadios"></Radio>
        </FormItem>
      </Form>
    </div>
    <div class="modal-column-btn">
      <Button @click="$emit('close')">取消</Button>
      <Button color="primary" @click="submit" :loading="loading">{{ form.id ? '更新' : '保存' }}</Button>
    </div>
  </div>
</template>

<script setup>

import setting from "@api/setting";
import {useStore} from "vuex";
import {reactive, ref} from "vue";
import {CopyObj} from "@js/common/utils";

const store = useStore();
const emits = defineEmits(['close', 'success']);
const props = defineProps(['entity']);

const loading = ref(false)
const formRef = ref(null)

const form = reactive({
  "id": null,
  "word": "",
  "printTitle": "",
  "isDefault": false
})

CopyObj(form, props.entity)

const submit = () => {
  let validResult = formRef.value.valid();
  if (validResult.result) {
    loading.value = true;
    setting.voucherWord[form.id ? 'update' : 'save'](form).then(() => {
      emits('success')
    }).catch(() => {
      loading.value = false;
    })
  }
}
</script>

按钮级别的权限控制通过自定义指令:v-p 进行控制。如果是在代码中或者不能使用指令时可以通过全局方法 SaCheckPermission 进行控制。

js代码中使用:

if (this.SaCheckPermission('checkout-checkoutmanage-cancheck')) {
  this.datas.push({
    title: '期末处理',
    key: 'CheckList'
  });
}

界面中使用:

<template v-if="SaCheckPermission('voucher-vouchermanage-canexport')">
    <DropdownMenu class="mx-10px" @clickItem="downloadTrigger" :datas="{all:'导出所有',checked:'导出选中'}" :toggleIcon="false">
      <vxe-button>导出凭证 <i class="fa fa-caret-down"></i></vxe-button>
    </DropdownMenu>
</template>

routes定义页面组件导入

const routes = [
...
{name: 'VoucherWord', title: '凭证字', component: defineAsyncComponent(() => import('@/views/setting/VoucherWord.vue'))},
...
]

MENUS中将菜单加入

const MENUS = [
...
{
    title: '设置',
    key: 'Setting',
    icon: 'fi fi-sz',
    children: [
    ...
    {
        title: '凭证字',
        key: 'VoucherWord',
        auth: 'setting-vouchergroup-canview'
    }
    ...
    ]
}
...
]

api中增加模块统一接口调用

src/api/setting.js中

voucherWord: {
    list() {
      return Ajax.get("/voucher-word")
    },
    load(id) {
      return Ajax.get(`/voucher-word/${id}`)
    },
    delete(id) {
      return Ajax.delete(`/voucher-word/${id}`)
    },
    save(params = {}) {
      return Ajax.post(`/voucher-word`, params)
    },
    update(params = {}) {
      return Ajax.put(`/voucher-word`, params)
    }
}

admin-front

admin-front模块和font-end模块类型,不同地方是也菜单的加载方式。

admin-front的页面菜单加载方式采用约定式定义。

菜单页面入口约定定义再admin-front/src/admin/pages目录下通过router属性定义菜单属性。

具体实现参考admin-front/src/admin/pages/index.js

<script>
export default {
  name: "Versions",
  router: {
    icon: "fa fa-users",
    title: "版本管理",
    pos: 102
  }
}

</script>