Try   HackMD

透過流程開發網頁(Directus 資料新增)

Directus 新增集合&欄位

集合名稱: form
預設欄位: 擁有者 / 建立於
新增欄位: 文字區塊,content

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

流程概覽

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

回應請求節點

<!DOCTYPE html>
<html lang="zh-Hant">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <script src="https://cdn.jsdelivr.net/npm/babel-preset-vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/babel-standalone@6"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/polyfill@7"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios"></script>
    <script src="https://cdn.jsdelivr.net/npm/scroll-behavior-polyfill@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/moment@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/moment@2/locale/zh-tw.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
    <script src="https://cdn.jsdelivr.net/npm/vconsole@3"></script>
    
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/reseter.css"
    />
    <link
      rel="stylesheet" 
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
    />
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap"
    />

    <title>網頁標題</title>
  </head>
  <body>
    <div id="app">

    </div>
  </body>

  <script>

    const app = new Vue({
      el: "#app",
      data: { },
      mounted: async function () { },
      computed: { },
      methods: { },
    });

    const vConsole = new window.VConsole();
  </script>
</html>

這是一個在 GOSU 中常見的網頁基本架構,載入了 VUE / moment / sweetalert2 套件
並且在開發過程中我們會載入 vConsole 以方便除錯

新增表單

  • 這邊進行了兩個資料的綁定,並且在按下送出的時候顯示了內容
  • 要注意的是在回應請求節點中因為後端解析的問題,無法使用 Template literals
  • 如果要顯示使用者的名稱,可以透過 ${from.profile.name} 將使用者的名稱顯示在畫面中/或者是在變數裡
  • 如果要把後端的變數放置前端使用,要注意資料型態的處理,例如要變成字串的話,要透過雙引號(")將其包住。
<body>
  <div id="app">
    <div class="form-field">
      <label>回覆者</label>
      <input v-model="user" disabled="disabled" />
    </div>

    <div class="form-field">
      <label>回報內容</label>
      <textarea v-model="content" placeholder="回報內容"></textarea>
    </div>

    <div class="buttons">
      <button v-on:click="submit">送出</button>
    </div>
  </div>
</body>

<script>
  const app = new Vue({
    el: "#app",
    data: {
      user: "${from.profile.name}",
      content: "",
    },
    mounted: async function () {},
    computed: {},
    methods: {
      submit: function () {
        console.log({ content: this.content });
      },
    },
  });

  const vConsole = new window.VConsole();
</script>

寫回 Directus

  • mounted 時從 API 讀取 token
    • 需要在起始點啟用檢查登入狀態
    • 網站必須放置在流程中執行(Cookies 安全性政策)
  • 在送出時發送請求至 directus / gosu / proxy 的服務中(將能夠把GOSU中的使用者身份帶到 Directus中)
const app = new Vue({ el: "#app", data: { user: "${from.profile.name}", content: "", }, mounted: async function () { this.oauth = await axios({ method: "get", url: "/oauth/line/verify/", baseURL: "https://${from.bot.id}.api.gosu.bar", withCredentials: true, }); }, computed: {}, methods: { submit: async function () { try { const res = await axios.post( "https://directus.gosu.bar/gosu/proxy/${from.company.id}/items/form", { content: this.content, }, { headers: { Authorization: "Bearer " + this.oauth.data.token.token, }, } ); Swal.fire("恭喜你!", "成功回報資料!", "success"); } catch (error) { Swal.fire("糟糕!", "發生不明錯誤!", "error"); } }, }, });

設定 Directus 權限

  • 需要打過 Directus GOSU Proxy API 後才會產生 Profile 身份
  • 在 Directus > 管理者設定 > 角色和權限 > Profile
  • 在 Form 集合集旁邊開啟新增的權限
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

參考資料