API web services

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-11-27 16:08:36 +07:00
parent 67787dab34
commit b11a943885
7 changed files with 259 additions and 97 deletions

View file

@ -0,0 +1,7 @@
import env from "../index";
const apiKey = `${env.API_URI}/org/apiKey`;
export default {
apiKeyMain: apiKey,
};

View file

@ -46,6 +46,9 @@ import backup from "./api/04_system/api.backup";
/** API Command/*/
import command from "./api/05_command/api.command";
/** API Webservices*/
import webservices from "./api/06_webservices/api.webservices";
// environment variables
export const compettitivePanel = import.meta.env.VITE_COMPETITIVE_EXAM_PANEL;
export const qualifyDisableExamPanel = import.meta.env
@ -120,6 +123,8 @@ const API = {
...backup,
/** command*/
...command,
/** webservices*/
...webservices,
};
export default {

View file

@ -1,76 +1,155 @@
<script setup lang="ts">
import { computed, reactive, ref } from "vue";
import { computed, reactive, ref, watch } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
/** importType*/
import type { ListApi } from "@/modules/06_webservices/interface/index/Main";
import type { FormCreate } from "@/modules/06_webservices/interface/request/Main";
import type { ResApiName } from "@/modules/06_webservices/interface/response/Main";
/** importComponents*/
import DialogHeader from "@/components/DialogHeader.vue";
/** use*/
const $q = useQuasar();
const { dialogMessageNotify } = useCounterMixin();
const {
dialogMessageNotify,
showLoader,
hideLoader,
messageError,
dialogConfirm,
success,
} = useCounterMixin();
/** props*/
const modal = defineModel<boolean>("modal", { required: true });
const props = defineProps({
fetchData: {
type: Function,
required: true,
},
});
const isAPIKey = ref<boolean>(false);
const topicRef = ref<any>(null);
const apiKey = ref<string>("");
const options = ref<ListApi[]>([
{ label: "API 1", value: "API 1" },
{ label: "API 2", value: "API 2" },
{ label: "API 3", value: "API 3" },
]);
const topicRef = ref<any>(null); //refinput /
const isAPIKey = ref<boolean>(false); //status API Key
const apiKey = ref<string>(""); // API Key
const options = ref<ListApi[]>([]); // API
// form API Key
const formData = reactive<FormCreate>({
topic: "",
access: [],
name: "", ///
apiId: [], //id API
});
const titleName = computed<string>(() => {
return !isAPIKey.value ? "สร้าง API Key" : "API Key";
});
/** ฟังก์ชันเรียกรายการข้อมูล API ที่เข้าถึงได้*/
function fetchListApiKeyName() {
showLoader();
http
.get(config.API.apiKeyMain + "/name")
.then(async (res) => {
const data = (await res.data?.result) || [];
options.value = data.map((e: ResApiName) => ({
label: e.name,
value: e.id,
}));
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/** ฟังก์ชันยืนยันการสร้าง API Key */
function onCreateAPIKey() {
topicRef.value.validate();
// /
if (topicRef.value.validate()) {
if (formData.access.length > 0) {
console.log(formData);
apiKey.value = "APIKEY";
isAPIKey.value = true;
// API popup API Key
if (formData.apiId.length > 0) {
dialogConfirm($q, async () => {
showLoader();
await http
.post(config.API.apiKeyMain, {
...formData,
name: formData.name.replace(/\s+/g, ""), //
})
.then(async (res) => {
const data = await res.data.result;
apiKey.value = data;
success($q, "สร้าง API Key สำเร็จ");
isAPIKey.value = true;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
});
} else {
// Popup API
dialogMessageNotify($q, "กรุณาเลือก API ที่เข้าถึงได้");
}
}
}
/** ฟังก์ชันคัดลอก API API Key*/
function onCopyToClipboard() {
navigator.clipboard.writeText(apiKey.value);
}
/**
* งกนป popup
* าม API Key ใหเรยกขอมลรายการ web services ใหม
*/
function onCloseDialog() {
// API Key
if (isAPIKey.value) {
props.fetchData?.();
}
modal.value = false;
isAPIKey.value = false;
formData.topic = "";
formData.access = [];
formData.name = "";
formData.apiId = [];
}
/**
* การเปลยนแปลงขอมลของ `modal`
* modal เป True เรยกรายการขอม API เขาถงได
*/
watch(modal, (val) => {
if (val) {
fetchListApiKeyName();
}
});
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card style="width: 700px; max-width: 80vw">
<!-- header -->
<DialogHeader :tittle="titleName" :close="onCloseDialog" />
<q-separator />
<q-card-section v-if="!isAPIKey">
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-12">
<!-- /คำอธบาย -->
<div class="col-12" v-if="!isAPIKey">
<q-input
ref="topicRef"
class="inputgreen"
dense
outlined
v-model="formData.topic"
v-model="formData.name"
label="ชื่อ/คำอธิบาย"
hide-bottom-space
lazy-rules
@ -78,22 +157,8 @@ function onCloseDialog() {
/>
</div>
<div class="col-12">
API เขาถงได
<q-option-group
:options="options"
type="checkbox"
keep-color
color="primary"
v-model="formData.access"
/>
</div>
</div>
</q-card-section>
<q-card-section v-else>
<div class="row q-col-gutter-sm">
<div class="col-12">
<!-- apiKey -->
<div class="col-12" v-else>
<span class="text-red">
* API Key านลางนจะแสดงเพยงครงเดยว
ขอใหทำสำเนาไวในทปลอดภ
@ -114,21 +179,24 @@ function onCloseDialog() {
</q-input>
</div>
<!-- API เขาถงได -->
<div class="col-12">
API เขาถงได
<q-option-group
disable
:disable="isAPIKey"
:options="options"
type="checkbox"
keep-color
color="primary"
v-model="formData.access"
v-model="formData.apiId"
/>
</div>
</div>
</q-card-section>
<q-separator />
<!-- footer -->
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
:label="!isAPIKey ? 'สร้าง API Key' : 'ปิด'"

View file

@ -1,8 +1,19 @@
interface ListWebServices {
createdAt: string;
createdFullName: string;
createdUserId: string;
id: string;
topic: string;
access: string[];
amount: string;
keyApi: string;
name: string;
amount: number;
apiNames: ApiNames[];
}
interface ApiNames {
id: string;
methodApi: string;
name: string;
pathApi: string;
}
interface ListApi {

View file

@ -1,6 +1,6 @@
interface FormCreate {
topic: string;
access: string[];
name: string;
apiId: string[];
}
export type { FormCreate };

View file

@ -5,4 +5,17 @@ interface ResListWebServices {
amount: string;
}
export type { ResListWebServices };
interface ResApiName {
createdAt: string;
createdFullName: string;
createdUserId: string;
id: string;
lastUpdateFullName: string;
lastUpdateUserId: string;
lastUpdatedAt: string;
methodApi: string;
name: string;
pathApi: string;
}
export type { ResListWebServices, ResApiName };

View file

@ -3,41 +3,62 @@ import { onMounted, ref } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
/** importType*/
import type { QTableProps } from "quasar";
import type { ListWebServices } from "@/modules/06_webservices/interface/index/Main";
import type { ResListWebServices } from "@/modules/06_webservices/interface/response/Main";
import type { ResApiName } from "@/modules/06_webservices/interface/response/Main";
import DialogApiKey from "@/modules/06_webservices/components/DialogApiKey.vue";
import DialogUsability from "@/modules/06_webservices/components/DialogUsability.vue";
/** importComponents*/
import DialogApiKey from "@/modules/06_webservices/components/DialogApiKey.vue"; // API Key
import DialogUsability from "@/modules/06_webservices/components/DialogUsability.vue"; //
/** use*/
const $q = useQuasar();
const { dialogRemove } = useCounterMixin();
const {
dialogRemove,
showLoader,
hideLoader,
messageError,
success,
date2Thai,
} = useCounterMixin();
/** Table*/
const rows = ref<ListWebServices[]>([]);
const keyword = ref<string>("");
const visibleColumns = ref<string[]>(["topic", "access", "amount"]);
const rows = ref<ListWebServices[]>([]); // webservices
const keyword = ref<string>(""); // webservices
const visibleColumns = ref<string[]>([
"name",
"apiNames",
"amount",
"createdAt",
"createdFullName",
]);
const columns = ref<QTableProps["columns"]>([
{
name: "topic",
name: "name",
align: "left",
label: "ชื่อ-คำอธิบาย",
sortable: true,
field: "topic",
field: "name",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "access",
name: "apiNames",
align: "left",
label: "API ที่เข้าถึง",
sortable: true,
field: "access",
field: "apiNames",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
format(val) {
return val
.map((e: ResApiName) => `<div class='q-mt-sm'>-${e.name}</div>`)
.join("");
},
},
{
name: "amount",
@ -48,36 +69,78 @@ const columns = ref<QTableProps["columns"]>([
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "createdAt",
align: "left",
label: "วันที่สร้าง",
sortable: true,
field: "createdAt",
format(val) {
return date2Thai(val, false, true);
},
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "createdFullName",
align: "left",
label: "ผู้ดำเนินการ",
sortable: true,
field: "createdFullName",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
/** API Key*/
const modalApiKey = ref<boolean>(false);
const modalApiKey = ref<boolean>(false); //popup API Key
/** usability*/
const modalUsability = ref<boolean>(false);
const modalUsability = ref<boolean>(false); //popup
function fetchListWebServices() {
const data: ResListWebServices[] = [
{
id: "",
topic: "รายการ web services 1",
access: ["API1", "API2", "API3"],
amount: "1",
},
{
id: "",
topic: "รายการ web services 2",
access: ["API1", "API2", "API3"],
amount: "2",
},
];
rows.value = data;
/** ฟังก์ชันเรียกข้อมูลรายการ Web services*/
async function fetchListWebServices() {
showLoader();
await http
.get(config.API.apiKeyMain + "/list")
.then(async (res) => {
const data = await res.data.result;
rows.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/**
* งก ลบขอมลรายการ Web services
* @param id รายการ Web services องการลบ
* เมอสำเรจจะเรยกฟงก 'fetchListWebServices' มาเรยกขอมลรายการ web servcice ใหม
*/
function onDeleteData(id: string) {
dialogRemove($q, () => {});
dialogRemove($q, () => {
showLoader();
http
.delete(config.API.apiKeyMain + `/${id}`)
.then(async () => {
// web servcice
await fetchListWebServices();
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
});
}
/** hook เมื่อเรียก Components จะเรียกฟังก์ชัน 'fetchListWebServices' เรียกข้อมูลรายการ webservices*/
onMounted(() => {
fetchListWebServices();
});
@ -98,6 +161,7 @@ onMounted(() => {
</div>
<q-card flast bordered class="q-pa-md">
<!-- toolbar -->
<div class="items-center col-12 row q-col-gutter-sm">
<q-btn
class="q-ml-sm"
@ -139,13 +203,14 @@ onMounted(() => {
/>
</div>
<!-- Table -->
<div class="col-12 q-pt-sm">
<d-table
ref="table"
:columns="columns"
:rows="rows"
row-key="id"
:filters="keyword"
:filter="keyword"
flat
bordered
:paging="true"
@ -176,40 +241,33 @@ onMounted(() => {
</q-btn></q-td
>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div v-if="col.name === 'access'">
<!-- <div v-if="col.name === 'apiNames'">
<q-list dense>
<q-item v-for="(item, key) in col.value">
<q-item-section> - {{ item }}</q-item-section>
<q-item-section>- {{ item.name }}</q-item-section>
</q-item>
</q-list>
</div>
</div> -->
<div v-html="col.value ? col.value : '-'"></div>
<div v-else>
{{ col.value ? col.value : "-" }}
<div>
<!-- {{ col.value ? col.value : "-" }} -->
</div>
</q-td>
</q-tr>
</template>
<!-- <template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="currentPage"
active-color="primary"
color="dark"
:max="Number(maxPage)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="fetchListUsers"
></q-pagination>
</template> -->
</d-table>
</div>
</q-card>
<DialogApiKey v-model:modal="modalApiKey" />
<DialogUsability y v-model:modal="modalUsability" />
<!-- สราง API Key -->
<DialogApiKey
v-model:modal="modalApiKey"
:fetch-data="fetchListWebServices"
/>
<!-- การใชงาน -->
<DialogUsability v-model:modal="modalUsability" />
</template>
<style scoped></style>