wujingjing
2024-09-10 312dd4fbc040b0f413c9b27149613d6f22c949a0
src/components/amis/AMISRenderer.vue
@@ -1,63 +1,20 @@
<template><div class="my-amis-scope">加载中...</div></template>
<template><div ref="amisRootRef" class="my-amis-scope">加载中...</div></template>
<script lang="ts">
// import '/static/sdk/sdk.js';
// import '/static/sdk/sdk.css';
// import '/static/sdk/iconfont.css';
import { accessSessionKey, handleNoAuth } from '/@/utils/request';
import { NO_AUTH_API_LIST } from '/@/api/ai/chat';
import { LOGIN_URL, TEL_LOGIN_URL } from '/@/api/ai/user';
<script setup lang="ts">
import { MAIN_URL } from '/@/constants';
import router from '/@/router/index';
import { Local } from '/@/utils/storage';
import { accessSessionKey, handleNoAuth } from '/@/utils/request';
// 可以不引用, 如果你不想要任何辅助类样式的话 (比如 `m-t-xs` 这种)
// https://aisuda.bce.baidu.com/amis/zh-CN/style/index
// import 'amis/sdk/helper.css';
import qs from 'qs';
import { onMounted, onUnmounted, reactive, ref, shallowRef, watch } from 'vue';
import { NO_AUTH_API_LIST } from '/@/api/ai/chat';
import { LOGIN_URL, TEL_LOGIN_URL } from '/@/api/ai/user';
import { Local } from '/@/utils/storage';
const amisRootRef = ref<HTMLDivElement>(null);
function loadScript(callback) {
   window.eventList.amisSdkJsPromise
      .then(() => {
         callback();
      })
      .catch((error) => {
         callback(error);
      });
}
function loadStyles(styles) {
   for (const path of styles) {
      const style = document.createElement('link');
      style.setAttribute('rel', 'stylesheet');
      style.setAttribute('type', 'text/css');
      style.setAttribute('href', path);
      document.head.appendChild(style);
   }
}
function loadSDK() {
   return new Promise((resolve, reject) => {
      if (window.amisRequire) {
         resolve();
         return;
      }
      loadScript((err) => {
         if (err) {
            reject(err);
            return;
         }
         resolve();
      });
   });
}
export default {
   name: 'AMISRenderer',
   components: {},
   props: {
const props = defineProps({
      schema: {
         type: Object,
         default: () => ({
@@ -77,67 +34,106 @@
         type: Object,
         default: () => ({}),
      },
   },
   data() {
      return {
         // 这里面的数据所有 amis 页面都可以获取到
         // 可以用来放一下公共数据,比如用户信息等
         // 不要放受控数据,受控数据应该通过 data 下发
         context: {
});
const emit = defineEmits(['ready']);
function loadScript(callback) {
   window.eventList.amisSdkJsPromise
      .then(() => {
         callback();
      })
      .catch((error) => {
         callback(error);
      });
}
function loadSDK() {
   return new Promise((resolve, reject) => {
      // loadStyles(['/static/amis/sdk/sdk.css', '/static/amis/sdk/helper.css', '/static/amis/sdk/iconfont.css']);
      if (window.amisRequire) {
         resolve();
         return;
      }
      loadScript((err) => {
         if (err) {
            reject(err);
            return;
         }
         resolve();
      });
   });
}
const context = reactive({
            siteName: 'AMIS DEMO',
         },
         get location() {
});
            const current = router.currentRoute.value;
            return {
const location = {
               pathname: current?.path,
               hash: current?.hash,
               query: current?.query,
               search: `?${qs.stringify(current.query)}`,
            };
            // return 'localtion'
         },
         loading: false,
         amisInstance: null,
         unmounted: false,
      };
   },
   watch: {
      locals: function () {
         this.updateProps();
const loading = ref(false);
const amisInstance = shallowRef(null);
const unmounted = ref(false);
const updateProps = () => {
   amisInstance.value?.updateProps({
      data: {
         ...props.locals,
      },
      props: function () {
         this.updateProps();
      },
      $route: function () {
         this.updateProps();
      },
   },
   async mounted() {
      context: context,
      ...props.props,
   });
};
watch(
   () => props.locals,
   (val) => {
      updateProps();
   }
);
watch(
   () => props.props,
   (val) => {
      updateProps();
   }
);
// watch(() => router.value, (val) => {
// })
onMounted(async () => {
      try {
         this.loading = true;
      loading.value = true;
         await loadSDK();
      } finally {
         this.loading = false;
      loading.value = false;
      }
      if (this.unmounted) {
   if (unmounted.value) {
         return;
      }
      const scoped = amisRequire('amis/embed');
      const { normalizeLink } = amisRequire('amis');
      const instance = scoped.embed(
         this.$el,
         this.schema,
      amisRootRef.value,
      props.schema,
         {
            data: {
               ...this.locals,
            ...props.locals,
            },
            context: this.context,
            location: this.location,
         context: context,
         location: location,
            // todo 下发 location 对象
            ...this.props,
         ...props.props,
         },
         {
            requestAdaptor(api) {
@@ -161,12 +157,45 @@
               api.url = `${MAIN_URL}${api.url}`;
               return api;
            },
         // 全局 api 适配器。
         // 另外在 amis 配置项中的 api 也可以配置适配器,针对某个特定接口单独处理。
         responseAdaptor(api, payload, query, request, response) {
            //                {
            //   "json_ok": true,
            //   "sections": [
            //     {
            //       "section_id": "knowledge_base",
            //       "section_name": "水务知识库",
            //       "section_title": "拥有水务行业相关的通用知识,包括:法律法规、设计规范、给排水相关知识等等"
            //     },
            //     {
            //       "section_id": "office_assistant",
            //       "section_name": "办公助手",
            //       "section_title": "办公助手能够辅助写会议通知、请假条、工作总结、PPT等工作。"
            //     },
            //     {
            //       "section_id": "customer_service",
            //       "section_name": "客户服务",
            //       "section_title": "针对水务企业对外客户服务相关的内容,包括:抄表、开账、收费,以及热线相关"
            //     },
            //     {
            //       "section_id": "network_operation",
            //       "section_name": "管网运行",
            //       "section_title": "针对水务企业管网运行与维护管理、水质管理等相关"
            //     },
            //     {
            //       "section_id": "waterworks_operation",
            //       "section_name": "水厂运行",
            //       "section_title": "针对水务企业水厂运日常运营管理服务,包括:水厂工艺流程、水泵运行调度"
            //     }
            //   ]
            // }
            return payload;
         },
            // 覆盖 amis env
            // 参考 https://aisuda.bce.baidu.com/amis/zh-CN/docs/start/getting-started#sdk
            jumpTo: (to, action) => {
               return;
               console.log('🚀 ~ to:', to);
               console.log('🚀 ~ action:', action);
               if (to === 'goBack') {
                  return router.go(-1);
               }
@@ -194,8 +223,6 @@
            updateLocation: (location, replace) => {
               // 禁止跳转
               return;
               console.log('🚀 ~ location:', location);
               console.log('🚀 ~ replace:', replace);
               if (location === 'goBack') {
                  return router.go(-1);
               }
@@ -204,33 +231,20 @@
               replace ? router.replace(location) : router.replace(location);
            },
            ...this.env,
         ...props.env,
         },
         () => {
            this.$emit('ready', {
         emit('ready', {
               instance,
            });
         }
      );
      this.amisInstance = instance;
   },
   methods: {
      updateProps() {
         this.amisInstance?.updateProps({
            data: {
               ...this.locals,
            },
            context: this.context,
            ...this.props,
   amisInstance.value = instance;
         });
      },
   },
   unmounted() {
      this.unmounted = true;
      this.amisInstance?.unmount();
   },
};
onUnmounted(() => {
   unmounted.value = true;
   amisInstance.value?.unmount();
});
</script>