案例说明

本案例将介绍如何将地图嵌入微应用,如何在自己的应用表单调用系统功能。
案例效果如下:

开发步骤

1. 项目下载

Gitee仓库下载

git clone https://gitee.com/ketr/jecloud-pc-archetype

2. 项目安装

  • 开发环境
    node版本
    v 14.17.5
    npm版本
    v 6.14.14

  • 安装依赖

    npm run setup
  • 增加本地配置文件,在根目录下添加 .env.development.local 文件

    # 开发环境配置
    # 不允许修改,若要修改,可以复制本文件,改名为:.env.development.local,自行修改变量
    # 端口
    VUE_APP_SERVICE_PORT = 3000
    # 代理服务地址
    VUE_APP_SERVICE_PROXY = http://example.jecloud.net/
    # 代理服务地址匹配地址
    VUE_APP_SERVICE_PROXY_PREFIX = /jeapi
    # -1 :启用本地主题变量,可以在build/theme/debug.js里面增加变量,调试主题
    #  0 :全部
    # >0 :设置主题个数,可以缓解初次启动服务加载缓慢
    VUE_APP_THEME_COUNT = -1

3. 项目开发

  • 启动项目

    npm run dev
  • 开发项目(源码案例附在文档后,如有需要,请前往参考~)

1.新建demo文件夹及其相关文件。

  • index.vue
    入口文件

  • api.js
    ajax请求,返回数据

  • url.js
    统一存放ajax请求的url地址

  • form.vue
    右侧表单页面

  • map.vue
    左侧面板页面

2.配置路由router/index.js

  1. 引入高德地图

执行命令:npm i @amap/amap-jsapi-loader –save

  • 效果展示
  1. 页面的整体效果。布局采用jecloud UI组件库中的Panel, 其中左侧展示地图

核心代码方法:initMap

  1. 点击查看功能通过调用JE.showFunc(‘HR_QJSQ’)弹出请假申请的功能

  1. 点击修改,选择请假功能列表的某一条数据,在表单内进行数据回显,点击保存完成修改操作。核心代码如下
    SelectWindow.show({
      title: '修改数据',
      type: 'grid',
      configInfo: 'HR_QJSQ,,,S',
      callback: function ({ rows }) {
          if (rows && rows.length) {
              Object.assign(formState, rows[0]);
          }
      },
    });

4. 打包部署

  1. 构建输出文件
npm run build

在根目录下生成dist文件

  1. 部署文件

JECloud应用增加目录

在服务器/data/application/openresty/nginx/jecloud/micro文件下创建archetype文件夹

将输出文件dist下的文件复制到新增目录,
注意:文件夹命名最好用项目名最后一个’-‘后面的文字进行命名,变为小写~

5. 平台配置

  1. 微应用管理配置

  1. 配置菜单
    添加插件,选择插件,将插件信息带入到配置信息,这里的插件都是必须在微应用功能里面维护的插件数据

  1. 菜单授权

6. 最终效果

案例代码

目录结构说明:

index.vue

说明:入口页面

<template>
  <div class="je-common-demo">
    <je-panel ref="panel">
      <je-panel-item region="left" v-bind="options.left"> <Map /></je-panel-item>
      <je-panel-item>
        <template #default><DemoForm /></template>
      </je-panel-item>
    </je-panel>
  </div>
</template>

<script>
  import { reactive, onBeforeMount } from 'vue';
  import Map from './components/map.vue';
  import DemoForm from './components/form.vue';
  import { Panel } from '@jecloud/ui';

  export default {
    name: 'Demo',
    components: {
      DemoForm,
      Map,
      JePanel: Panel,
      JePanelItem: Panel.Item,
    },
    setup() {
      const options = reactive({
        left: {
          size: 500,
        },
      });
      onBeforeMount(() => {});
      return { options };
    },
  };
</script>
<style lang="less" scoped>
  .je-common-demo {
    padding: 20px;
  }
</style>

map.vue

说明:左侧面板地图。

<template>
  <div ref="mapRef" class="map" style="width: 100%; height: 100%"></div>
</template>

<script>
  import { ref, onMounted, reactive } from 'vue';
  import AMapLoader from '@amap/amap-jsapi-loader';
  export default {
    name: 'Maps',
    components: {},
    setup() {
      const mapRef = ref(null);
      const option = reactive({
        lng: 116.404,
        lat: 39.915,
      });
      const initMap = () => {
        AMapLoader.load({
          key: '651bbe1427b37c74deea8541a643918a', // 申请好的Web端开发者Key,首次调用 load 时必填
          plugins: ['AMap.Scale'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
          AMapUI: {
            version: '1.1',
            plugins: ['overlay/SimpleMarker', 'geo/DistrictExplorer'],
          },
        })
          .then((AMap) => {
            const mapData = new AMap.Map(mapRef.value, {
              mapStyle: 'amap://styles/98b26d04358dd80ee479ca1dfe9edd06', // 配置的地图样式
              zoom: 11,
              zooms: [8, 20],
              center: [116.404, 39.915],
              features: ['road', 'bg', 'point', 'building'], // 支持'bg'(地图背景)、'point'(POI点)、'road'(道路)、'building'(建筑物)
              resizeEnable: true, // 监控地图容器尺寸变化,默认值为false
              expandZoomRange: true, // 支持可以扩展最大缩放级别,和zooms属性配合使用,设置为true的时候,zooms的最大级别在PC上可以扩大到20级
            });
            return mapData;
          })
          .catch((e) => {
            console.log(e, 1111);
          });
      };
      onMounted(() => {
        initMap();
      });
      return { option, initMap, mapRef };
    },
  };
</script>

form.vue

说明:面板右侧的表单页。

<template>
  <div class="je-common-demo-form">
    <h2>请假申请</h2>
    <div class="form-top-button">
      <je-button @click="clikButton('look')">查看功能</je-button>
      <je-button icon="jeicon jeicon-plus" style="margin: 0 30px" @click="clikButton('add')"
        >添加</je-button
      >
      <je-button icon="fal fa-edit" @click="clikButton('edit')">修改</je-button>
    </div>
    <je-form
      name="basic2"
      style="width: 1000px"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 20 }"
      autocomplete="off"
      class="form-container"
    >
      <je-form-item name="SY_CREATEUSERNAME" label="申请人">
        <je-input v-model:value="formState.SY_CREATEUSERNAME" disabled />
      </je-form-item>

      <je-form-item label="申请部门" name="SY_CREATEORGNAME">
        <je-input v-model:value="formState.SY_CREATEORGNAME" disabled />
      </je-form-item>

      <je-form-item name="QJSQ_QJLX_CODE" label="请假类型">
        <je-radio-group
          v-model:value="formState.QJSQ_QJLX_CODE"
          config-info="HR_QJLX,QJSQ_QJLX_NAME~QJSQ_QJLX_CODE,text~code,S"
        />
      </je-form-item>

      <je-form-item name="QJSQ_QJKSRQ" label="请假开始日期" v-bind="validateInfos.QJSQ_QJKSRQ">
        <je-date-picker v-model:value="formState.QJSQ_QJKSRQ" style="width: 100%" picker="date" />
      </je-form-item>

      <je-form-item name="QJSQ_JHGGRQ" label="计划归岗日期" v-bind="validateInfos.QJSQ_JHGGRQ">
        <je-date-picker v-model:value="formState.QJSQ_JHGGRQ" style="width: 100%" picker="date" />
      </je-form-item>
      <je-form-item label="紧急手机号" name="QJSQ_JJSJH" v-bind="validateInfos.QJSQ_JJSJH">
        <je-input v-model:value="formState.QJSQ_JJSJH" />
      </je-form-item>
      <je-form-item label="实际请假天数" name="QJSQ_SJQJTS">
        <je-input v-model:value="formState.QJSQ_SJQJTS" />
      </je-form-item>
      <je-form-item label="假期工作委托人" name="QJSQ_JQGZWTR">
        <je-user-select
          v-model:value="formState.QJSQ_JQGZWTR"
          config-info="JE_RBAC_VUSERQUERY,QJSQ_JQGZWTR~QJSQ_WTRID,USER_NAME~USER_ID,S"
        />
      </je-form-item>
      <je-form-item label="审核状态" name="SY_AUDFLAG">
        <je-select
          v-model:value="formState.SY_AUDFLAG"
          config-info="JE_AUDFLAG,SY_AUDFLAG,code,S"
        />
      </je-form-item>
      <je-form-item label="请假事由" name="QJSQ_QJSY" v-bind="validateInfos.QJSQ_QJSY">
        <je-text-area v-model:value="formState.QJSQ_QJSY" placeholder="请输入请假事由" :rows="4" />
      </je-form-item>
    </je-form>
    <je-button icon="fal fa-save" type="primary" @click="clikButton('save')">保存</je-button>
  </div></template
>

<script>
  import { onBeforeMount, onMounted, reactive, ref } from 'vue';
  import { Button, Form, Input, Radio, DatePicker, InputSelect, Modal, Select } from '@jecloud/ui';
  import { SelectWindow } from '@jecloud/func';
  import { useGlobalStore } from '@common/store/global-store';
  import { doSaveApi } from '../api/api';
  export default {
    name: 'Form',
    components: {
      JeButton: Button,
      JeForm: Form,
      JeFormItem: Form.Item,
      JeInput: Input,
      JeRadioGroup: Radio.up,
      JeDatePicker: DatePicker,
      JeUserSelect: InputSelect.User,
      JeTextArea: Input.TextArea,
      JeSelect: Select,
    },
    setup() {
      const options = reactive({
        left: {
          size: 500,
        },
      });
      const useForm = Form.useForm;
      const globaleStore = useGlobalStore();
      const formState = reactive({
        SY_CREATEUSERNAME: globaleStore.currentAccount?.name,
        SY_CREATEORGNAME: globaleStore.currentAccount.realUser.organization?.name,
        QJSQ_QJLX_CODE: '',
        QJSQ_QJKSRQ: '',
        QJSQ_JHGGRQ: '',
        QJSQ_JJSJH: '',
        QJSQ_SJQJTS: '',
        QJSQ_JQGZWTR: '',
        QJSQ_QJSY: '',
        SY_AUDFLAG: 'NOSTATUS',
      });
      // 表单校验
      const rulesRef = reactive({
        QJSQ_JHGGRQ: [
          {
            required: true,
            message: '该选项为必填项',
          },
        ],
        QJSQ_QJKSRQ: [
          {
            required: true,
            message: '该选项为必填项',
          },
        ],
        QJSQ_JJSJH: [
          {
            required: true,
            message: '该选项为必填项',
          },
        ],
        QJSQ_QJSY: [
          {
            required: true,
            message: '该选项为必填项',
          },
        ],
      });
      const { resetFields, validate, validateInfos } = useForm(formState, rulesRef, {
        onValidate: (...args) => console.log(...args),
      });

      const saveData = (productCode) => {
        const params = {
          funcCode: 'HR_QJSQ',
          tableCode: 'HR_QJSQ',
          pkCode: 'HR_QJSQ_ID',
          ...formState,
        };
        doSaveApi({
          params,
          pd: productCode || 'demo',
          pkValue: formState.HR_QJSQ_ID,
        }).then(() => {
          Modal.message(formState.HR_QJSQ_ID ? '修改成功' : '添加成功', 'success');
          resetFields();
        });
      };
      const clikButton = (type) => {
        switch (type) {
          case 'add':
            console.log('准备添加数据');
            break;
          case 'look':
            JE.showFunc('HR_QJSQ', { readonly: true });
            break;
          case 'edit':
            SelectWindow.show({
              title: '修改数据',
              type: 'grid',
              configInfo: 'HR_QJSQ,,,S',
              callback: function ({ rows }) {
                if (rows && rows.length) {
                  Object.assign(formState, rows[0]);
                }
              },
            });
            break;
          case 'save':
            validate()
              .then(() => {
                saveData();
              })
              .catch((err) => {
                console.log('error', err);
              });
            break;
        }
      };
      onBeforeMount(() => {});
      onMounted(() => {});
      return { options, validateInfos, formState, clikButton, rulesRef };
    },
  };
</script>

<style lang="less" scoped>
  .je-common-demo-form {
    padding: 20px;
    h2 {
      text-align: center;
    }
    .form-container {
      padding: 40px 0 40px 40px;
    }
  }
</style>

url.js

说明: 统一存放ajax请求的url地址

/**
 * 解析公共链接,根据功能配置可以自行设置
 * @param {*} url
 * @param {*} action
 */
export function parseCommonUrl(url, action) {
  action = action || '/je/common';
  return action + url;
}
/**
 * 添加
 */
export const API_COMMON_SAVE = '/doSave';
/**
 * 修改
 */
export const API_COMMON_UPDATE = '/doUpdate';

api.js

说明: ajax请求,返回数据。

import { ajax, transformAjaxData } from '@jecloud/utils';
import { API_COMMON_SAVE, API_COMMON_UPDATE, parseCommonUrl } from './url';
/**
 * 保存
 * @param {*} param0
 * @returns
 */
export function doSaveApi({ params, pd, pkValue, action }) {
  return ajax({
    url: parseCommonUrl(pkValue ? API_COMMON_UPDATE : API_COMMON_SAVE, action),
    headers: { pd },
    params,
  })
    .then(transformAjaxData)
    .then((data) => ({ dynaBean: data }));
}

其他代码块

  1. 路由配置
    {
     path: '/demo',
     name: 'Demo',
     text: t('menu.demo'),
     menu: true,
     component: () => import('../views/demo/index.vue'),
    },
  • END
最后编辑: 秦永莲  文档更新时间: 2024-11-08 17:00   作者:秦永莲