1392 lines
47 KiB
JavaScript
1392 lines
47 KiB
JavaScript
// nuxt 3 - plugins/my-plugin.ts
|
|
import { useStore } from "~/stores/index";
|
|
import axios from "axios";
|
|
import { io } from "socket.io-client";
|
|
|
|
export default defineNuxtPlugin(() => {
|
|
const module = "application";
|
|
const mode = "dev";
|
|
const paths = [
|
|
{ name: "dev", url: "https://dev.api.utopia.com.vn/" },
|
|
{ name: "local", url: "http://localhost:8000/" },
|
|
{ name: "prod", url: "https://api.utopia.com.vn/" },
|
|
];
|
|
const path = paths.find((v) => v.name === mode).url;
|
|
const apis = [
|
|
{ name: 'sendemail', url: 'send-email/' },
|
|
{ name: 'deleteentry', url: 'delete-entry/' },
|
|
{ name: 'emailpreview', url: 'email-preview/' },
|
|
{ name: 'workflow', url: 'workflow/execute/' },
|
|
{ name: 'accountentry', url: 'account-entry/', params: {} },
|
|
{ name: 'accountmultientry', url: 'account-multi-entry/', params: {} },
|
|
{ name: 'entryfile', url: 'data/Entry_File/', url_detail: 'data-detail/Entry_File/', params: { values: 'id,file__file,file__name,file__caption,file,file__user__fullname,create_time' } },
|
|
{ name: 'importsetting', url: 'data/Import_Setting/', url_detail: 'data-detail/Import_Setting/', params: {} },
|
|
{ name: 'modelfields', url: 'model-fields/', params: {} },
|
|
{ name: 'readexcel', url: 'read-excel/', params: {} },
|
|
{ name: 'findkey', url: 'find-key/', params: {} },
|
|
{ name: 'dealerrights', url: 'data/Biz_Rights/', url_detail: 'data-detail/Biz_Rights/', params: { sort: '-id' } },
|
|
{
|
|
name: "individual",
|
|
url: "data/Individual/",
|
|
url_detail: "data-detail/Individual/",
|
|
params: {
|
|
sort: "-id",
|
|
values: "id,customer,dob,sex,sex__name,sex__en,zalo,facebook,company,company__fullname,create_time,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "transactiondiscount",
|
|
url: "data/Transaction_Discount/",
|
|
url_detail: "data-detail/Transaction_Discount/",
|
|
params: {
|
|
values: "id,transaction,discount,discount__code,discount__name,type,type__code,type__name,value,create_time,update_time"
|
|
}
|
|
},
|
|
{
|
|
name: "organization",
|
|
url: "data/Organization/",
|
|
url_detail: "data-detail/Organization/",
|
|
params: {
|
|
sort: "-id",
|
|
values: "id,customer,shortname,established_date,website,type,type__name,create_time,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "co_op",
|
|
url: "data/Co_Ownership/",
|
|
url_detail: "data-detail/Co_Ownership/",
|
|
params: {
|
|
values: 'id,transaction,people,people__code,people__fullname,people__phone,people__legal_code'
|
|
}
|
|
},
|
|
{
|
|
name: "companytype",
|
|
url: "data/Company_Type/",
|
|
url_detail: "data-detail/Company_Type/",
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "cart",
|
|
url: "data/Cart/",
|
|
url_detail: "data-detail/Cart/",
|
|
commit: 'cart',
|
|
params: {
|
|
sort: "id",
|
|
values: "id,code,name,dealer,dealer__code,dealer__name,create_time",
|
|
distinct_values: {
|
|
label: {
|
|
type: "Concat",
|
|
field: ["code", "name"]
|
|
}
|
|
},
|
|
summary: "annotate",
|
|
}
|
|
},
|
|
{
|
|
name: "payment_schedule",
|
|
url: "data/Payment_Schedule/",
|
|
url_detail: "data-detail/Payment_Schedule/",
|
|
params: {
|
|
sort: "-id",
|
|
values:
|
|
"batch_date,amount_remain,penalty_remain,penalty_paid,penalty_amount,penalty_reduce,ovd_days,remain_amount,paid_amount,txn_detail__transaction__product__trade_code,txn_detail__status,txn_detail__transaction__product__code,txn_detail__phase__name,txn_detail,id,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__code,txn_detail__transaction__customer__legal_code,status__name,type__name,code,from_date,txn_detail__transaction__policy__code,to_date,amount,cycle,cycle_days,txn_detail__transaction,type,status,updater,entry,detail,txn_detail__transaction__code,txn_detail__code"
|
|
},
|
|
},
|
|
{
|
|
name: "people",
|
|
url: "data/People/",
|
|
url_detail: "data-detail/People/",
|
|
params: {
|
|
sort: "-id",
|
|
values:
|
|
"id,issued_place,issued_place__code,issued_place__name,contact_address,address,country__name,company__fullname,legal_code,company,country,email,creator,code,fullname,dob,sex,legal_code,sex__name,phone,issued_date,legal_type,legal_type__name,address,note,updater,updater__fullname,create_time,update_time",
|
|
distinct_values: {
|
|
label: { type: "Concat", field: ["code", "fullname", "phone"] },
|
|
order: { type: "RowNumber" },
|
|
},
|
|
summary: "annotate",
|
|
},
|
|
},
|
|
{ name: 'productnote', url: 'data/Product_Note/', url_detail: 'data-detail/Product_Note/', commit: 'productnote', params: {sort: 'id',values: 'id,detail,user,user__username,user__fullname,create_time,update_time,ref,ref__cart__dealer,ref__trade_code' } },
|
|
{
|
|
name:"customernote",
|
|
url: "data/Customer_Note/",
|
|
url_detail: "data-detail/Customer_Note/",
|
|
params: {
|
|
values: 'id,ref,detail,user,create_time,update_time'
|
|
}
|
|
},
|
|
{ name: 'entrytype', url: 'data/Entry_Type/', url_detail: 'data-detail/Entry_Type/', params: {} },
|
|
{ name: 'entrycategory', url: 'data/Entry_Category/', url_detail: 'data-detail/Entry_Category/', params: {} },
|
|
{ name: 'accounttype', url: 'data/Account_Type/', url_detail: 'data-detail/Account_Type/', params: { sort: 'id' } },
|
|
{ name: 'internalaccount', url: 'data/Internal_Account/', url_detail: 'data-detail/Internal_Account/', params: { sort: 'branch,currency,type', values: 'id,currency,currency__code,currency__name,code,balance,create_time,update_time,type,type__code,type__name,branch,branch__code,branch__name', distinct_values: { label: { type: 'Concat', field: ['branch__name', 'code', 'type__name'] } }, summary: 'annotate' } },
|
|
{ name: "currency", url: "data/Currency/", url_detail: "data-detail/Currency/", params: {} },
|
|
{ name: "approvestatus", url: "data/Approve_Status/", url_detail: "data-detail/Approve_Status/", params: {} },
|
|
{ name: 'bizrights', url: 'data/Biz_Rights/', url_detail: 'data-detail/Biz_Rights/', params: { sort: '-id' } },
|
|
{
|
|
name: "feetype",
|
|
url: "data/Fee_Type/",
|
|
url_detail: "data-detail/Fee_Type/",
|
|
params: {
|
|
sort: "id",
|
|
values: "id,index,code,name,type,value,type__code,type__name,method,method__code,method__name,create_time",
|
|
distinct_values: {
|
|
label: {
|
|
type: "Concat",
|
|
field: ["name", "method__name", "type__name", "value"],
|
|
},
|
|
},
|
|
summary: "annotate",
|
|
},
|
|
},
|
|
{
|
|
name: "dealersetting",
|
|
url: "data/Biz_Setting/",
|
|
url_detail: "data-detail/Biz_Setting/",
|
|
params: { sort: "index" },
|
|
},
|
|
{
|
|
name: "documentaudit",
|
|
url: "data/Document_Audit/",
|
|
url_detail: "data-detail/Document_Audit/",
|
|
params: { sort: "index" },
|
|
},
|
|
{
|
|
name: "documenttype",
|
|
url: "data/Document_Type/",
|
|
url_detail: "data-detail/Document_Type/",
|
|
params: { sort: "index" },
|
|
},
|
|
{
|
|
name: "getcodeCustomer",
|
|
url: "increment/Customer/KH/",
|
|
|
|
params: {},
|
|
},
|
|
{
|
|
name: "getcodepeople",
|
|
url: "increment/People/RE/",
|
|
|
|
params: {},
|
|
},
|
|
{
|
|
name: "getcodecompany",
|
|
url: "increment/Company/CP/",
|
|
|
|
params: {},
|
|
},
|
|
{
|
|
name: "country",
|
|
url: "data/Country/",
|
|
commit: "country",
|
|
params: {
|
|
sort: "id",
|
|
values: "id,code,name,en,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "status",
|
|
url: "data/Approve_Status/",
|
|
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{ name: "image", url: "data/Image/", url_detail: "data-detail/Image/", params: {} },
|
|
{ name: "file", url: "data/File/", url_detail: "data-detail/File/", params: {} },
|
|
{ name: "filetype", url: "data/File_Type/", url_detail: "data-detail/File_Type/", params: {} },
|
|
{
|
|
name: "news",
|
|
commit: "updateNews",
|
|
url: "data/News/",
|
|
url_detail: "data-detail/News/",
|
|
params: { values: "id,title,subtitle,create_time" },
|
|
},
|
|
{
|
|
name: "category",
|
|
commit: "updateCategory",
|
|
url: "data/Category/",
|
|
url_detail: "data-detail/Category/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "contract",
|
|
url: "data/Contract/",
|
|
url_detail: "data-detail/Contract/",
|
|
params: {
|
|
sort: "-id"
|
|
},
|
|
},
|
|
{
|
|
name: "contractstatus",
|
|
url: "data/Contract_Status/",
|
|
url_detail: "data-detail/Contract_Status/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "token",
|
|
url: "data/Token/",
|
|
url_detail: "data-detail/Token/",
|
|
params: {
|
|
values:
|
|
"id,token,browser,browser_version,ip,os,platform,expiry,create_time,update_time,user,user__fullname,user__username",
|
|
sort: "-id",
|
|
},
|
|
},
|
|
{ name: "authtoken", url: "auth-token/", params: {} },
|
|
{
|
|
name: "notification",
|
|
commit: "updateNotification",
|
|
url: "data/Notify/",
|
|
url_detail: "data-detail/Notify/",
|
|
params: {
|
|
values:
|
|
"id,title,content,image,link,task_log,user,user__username,user__fullname,event,seen,create_time,event__code,event__name,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "common",
|
|
commit: "common",
|
|
url: "data/Biz_Setting/",
|
|
url_detail: "data-detail/Biz_Setting/",
|
|
params: { sort: "index" },
|
|
},
|
|
{ name: "upload", url: "upload/", params: {} },
|
|
{
|
|
name: "paymentstatus",
|
|
url: "data/Payment_Status/",
|
|
url_detail: "data-detail/Payment_Status/",
|
|
params: {
|
|
values: "id,code,name,en,index,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "paymenttype",
|
|
url: "data/Payment_Type/",
|
|
url_detail: "data-detail/Payment_Type/",
|
|
params: {
|
|
values: "id,code,name,en,index,create_time",
|
|
},
|
|
},
|
|
{ name: "paymentmethod", url: "data/Payment_Method/", url_detail: "data-detail/Payment_Method/", params: {} },
|
|
{ name: "salepolicy", url: "data/Sale_Policy/", url_detail: "data-detail/Sale_Policy/", params: { values: "id,code,name,deposit,method,method__code,method__name,create_time,enable,contract_allocation_percentage,create_time,update_time,index", sort: "index" } },
|
|
{
|
|
name: "paymentplan",
|
|
url: "data/Payment_Plan/",
|
|
url_detail: "data-detail/Payment_Plan/",
|
|
params: {
|
|
values: "policy__enable,id,policy,policy__code,policy__name,cycle,value,type,days,payment_note,due_note,create_time,update_time",
|
|
sort: "cycle"
|
|
},
|
|
},
|
|
{ name: "request", url: "data/Request/", url_detail: "data-detail/Request/", params: {} },
|
|
{ name: "register", url: "data/Register/", url_detail: "data-detail/Register/", params: {} },
|
|
{ name: "sendemail", url: "send-email/", path: "etl", params: {} },
|
|
{ name: "sendemailnow", url: "send-email-now/", path: "etl", params: {} },
|
|
{ name: "usersession", url: "data/User_Session/", url_detail: "data-detail/User_Session/", params: {} },
|
|
{ name: "userlog", url: "data/User_Log/", url_detail: "data-detail/User_Log/", params: {} },
|
|
{ name: "usersetting", url: "data/User_Setting/", url_detail: "data-detail/User_Setting/", params: {} },
|
|
{ name: "account-entry", url: "/account-entry/", params: {} },
|
|
{
|
|
name: "valuetype",
|
|
url: "data/Value_Type/",
|
|
url_detail: "data-detail/Value_Type/",
|
|
params: {
|
|
values: "id,code,name,en,index,create_time",
|
|
sort: "index"
|
|
},
|
|
},
|
|
{
|
|
name: "bizsetting",
|
|
commit: "bizsetting",
|
|
url: "data/Biz_Setting/",
|
|
url_detail: "data-detail/Biz_Setting/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "discounttype",
|
|
commit: "discounttype",
|
|
url: "data/Discount_Type/",
|
|
url_detail: "data-detail/Discount_Type/",
|
|
params: {
|
|
values: 'id,code,name,value,type,type__name,method,method__name',
|
|
distinct_values: {
|
|
label: { type: "Concat", field: ["code", "name", "type__name"] },
|
|
},
|
|
summary: "annotate",
|
|
},
|
|
},
|
|
{
|
|
name: "customer",
|
|
url: "data/Customer/",
|
|
url_detail: "data-detail/Customer/",
|
|
params: {
|
|
values:
|
|
"id,update_time,creator,creator__fullname,country,country__name,country__en,issued_date,issued_place,issued_place__name,code,email,fullname,legal_code,phone,legal_type,legal_type__name,address,contact_address,note,type,type__name,updater,updater__fullname,create_time,update_time",
|
|
distinct_values: {
|
|
label: { type: "Concat", field: ["code", "fullname", "phone", "legal_code"] },
|
|
order: { type: "RowNumber" },
|
|
image_count: { type: "Count", field: "id", subquery: { model: "Customer_File", column: "ref" } },
|
|
count_note: { type: "Count", field: "id", subquery: { model: "Customer_Note", column: "ref" } },
|
|
count_product: { type: "Count", field: "id", subquery: { model: "Product_Booked", column: "transaction__customer" } },
|
|
sum_product: { type: "Sum", field: "transaction__sale_price", subquery: { model: "Product_Booked", column: "transaction__customer" } },
|
|
sum_receiver: { type: "Sum", field: "transaction__amount_received", subquery: { model: "Product_Booked", column: "transaction__customer" } },
|
|
sum_remain: { type: "Sum", field: "transaction__amount_remain", subquery: { model: "Product_Booked", column: "transaction__customer" } }
|
|
},
|
|
summary: "annotate",
|
|
filter: { deleted: 0 },
|
|
sort: "-id",
|
|
},
|
|
},
|
|
{
|
|
name: "transaction",
|
|
commit: "transaction",
|
|
url: "data/Transaction/",
|
|
url_detail: "data-detail/Transaction/",
|
|
params: {
|
|
sort: '-date',
|
|
values: "date,txncurrent__detail,txncurrent__detail__status,customer__type,txncurrent,txncurrent__detail__amount,txncurrent__detail__amount_remaining,txncurrent__detail__status__name,product__zone_type__name,product__trade_code,product__cart__dealer,customer__legal_code,customer__legal_type__name,payment_plan,id,code,customer,customer__code,customer__fullname,customer__phone,product,phase,phase__name,phase__code,policy,policy__code,policy__name,origin_price,discount_amount,sale_price,deposit_amount,deposit_received,deposit_remaining,amount_received,amount_remain,create_time,update_time"
|
|
}
|
|
},
|
|
{
|
|
name: "transactionphase",
|
|
url: "data/Transaction_Phase/",
|
|
url_detail: "data-detail/Transaction_Phase/",
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "phasedoctype",
|
|
url: "data/Phase_Doctype/",
|
|
url_detail: "data-detail/Phase_Doctype/",
|
|
params: {
|
|
values: "id,phase,doctype,doctype__code,doctype__name",
|
|
sort:"doctype__index"
|
|
}
|
|
},
|
|
{
|
|
name: "transactiontype",
|
|
url: "data/Transaction_Type/",
|
|
url_detail: "data-detail/Transaction_Type/",
|
|
params: {
|
|
values: "id,code,name,detail,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "reservation",
|
|
commit: "reservation",
|
|
url: "data/Transaction_Detail/",
|
|
url_detail: "data-detail/Transaction_Detail/",
|
|
params: {
|
|
values: "id,code,date,amount,amount_received,amount_remaining,phase,due_date,transaction,creator,status,approver,approve_time,create_time,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "transactionfile",
|
|
commit: "transactionfile",
|
|
url: "data/Transaction_File/",
|
|
url_detail: "data-detail/Transaction_File/",
|
|
params: {
|
|
values: "id,txn_detail,file,file__name,file__size,file__file,create_time,file__doc_type",
|
|
},
|
|
},
|
|
{
|
|
name: "productbooked",
|
|
commit: "productbooked",
|
|
url: "data/Product_Booked/",
|
|
url_detail: "data-detail/Product_Booked/",
|
|
params: {
|
|
},
|
|
},
|
|
{
|
|
name: "product",
|
|
commit: "product",
|
|
url: "data/Product/",
|
|
url_detail: "data-detail/Product/",
|
|
params: {
|
|
sort: "id",
|
|
values:
|
|
"prdbk__transaction__amount_remain,prdbk__transaction,price_excluding_vat,prdbk__transaction__txncurrent__detail__status__name,locked_until,note,cart,cart__name,cart__code,cart__dealer,cart__dealer__code,cart__dealer__name,direction,type,zone_type,dealer,link,type__name,dealer__code,dealer__name,prdbk,prdbk__transaction__customer,prdbk__transaction,prdbk__transaction__policy__code,prdbk__transaction__sale_price,prdbk__transaction__discount_amount,prdbk__transaction__code,prdbk__transaction__customer__code,prdbk__transaction__customer__phone,prdbk__transaction__customer__fullname,prdbk__transaction__customer__legal_code,id,code,trade_code,land_lot_code,zone_code,zone_type__name,lot_area,building_area,total_built_area,number_of_floors,land_lot_size,origin_price,direction__name,villa_model,product_type,template_name,project,project__name,status,status__code,status__name,status__color,status__sale_status,status__sale_status__color,create_time,prdbk__transaction__amount_received",
|
|
distinct_values: {
|
|
label: { type: "Concat", field: ["trade_code", "type__name", "land_lot_size", "zone_type__name", "status__name"] },
|
|
count_note: { type: 'Count', field: 'prdnote' }
|
|
},
|
|
summary: "annotate",
|
|
},
|
|
},
|
|
{
|
|
name: "productdocument",
|
|
commit: "productdocument",
|
|
url: "data/Product_Document/",
|
|
url_detail: "data-detail/Product_Document/",
|
|
params: {
|
|
values:
|
|
"id,product,product__code,product__type,product__type__code,product__type__name,product__type__en,product__category,product__category__code,product__category__name,document,document__code,document__name,document__en",
|
|
},
|
|
},
|
|
{
|
|
name: "productstatus",
|
|
url: "data/Product_Status/",
|
|
url_detail: "data-detail/Product_Status/",
|
|
params: {
|
|
sort: "name",
|
|
values: "id,code,name,color,index,sale_status,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "producttype",
|
|
url: "data/Product_Type/",
|
|
url_detail: "data-detail/Product_Type/",
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "salestatus",
|
|
url: "data/Sale_Status/",
|
|
url_detail: "data-detail/Sale_Status/",
|
|
params: {
|
|
values: "id,code,name,color,index,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "project",
|
|
url: "data/Project/",
|
|
url_detail: "data-detail/Project/",
|
|
params: {
|
|
values: "id,code,name,investor,status,create_time,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "zonetype",
|
|
url: "data/Zone_Type/",
|
|
url_detail: "data-detail/Zone_Type/",
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "direction",
|
|
url: "data/Direction/",
|
|
url_detail: "data-detail/Direction/",
|
|
params: {
|
|
values: "id,code,name,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "settingclass",
|
|
commit: "settingclass",
|
|
url: "data/Setting_Class/",
|
|
url_detail: "data-detail/Setting_Class/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "user",
|
|
url: "data/User/",
|
|
url_detail: "data-detail/User/",
|
|
params: {
|
|
sort: "-id",
|
|
values:
|
|
"id,auth_method__code,blocked,auth_status__code,username,register_method__code,fullname,type,type__code,type__name,create_time,create_time__date,auth_method,auth_status,register_method,create_time,update_time",
|
|
distinct_values: { label: { type: "Concat", field: ["username", "fullname"] } },
|
|
summary: "annotate",
|
|
},
|
|
},
|
|
{ name: "gethash", url: "get-hash/", params: {} },
|
|
{
|
|
name: "login",
|
|
url: "login/",
|
|
params: {
|
|
values:
|
|
"id,username,password,avatar,fullname,display_name,type,type__code,type__name,blocked,block_reason,block_reason__code,block_reason__name,blocked_by,last_login,auth_method,auth_method__code,auth_method__name,auth_status,auth_status__code,auth_status__name,register_method,register_method__code,register_method__name,create_time,update_time",
|
|
},
|
|
},
|
|
{
|
|
name: "reservation",
|
|
commit: "reservation",
|
|
url: "data/Reservation/",
|
|
url_detail: "data-detail/Reservation/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "settingtype",
|
|
commit: "settingtype",
|
|
url: "data/Setting_Type/",
|
|
url_detail: "data-detail/Setting_Type/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "colorchoice",
|
|
commit: "colorchoice",
|
|
url: "data/Color_Choice/",
|
|
url_detail: "data-detail/Color_Choice/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "filterchoice",
|
|
commit: "filterchoice",
|
|
url: "data/Filter_Choice/",
|
|
url_detail: "data-detail/Filter_Choice/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "datatype",
|
|
commit: "datatype",
|
|
url: "data/Data_Type/",
|
|
url_detail: "data-detail/Data_Type/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "textalign",
|
|
commit: "textalign",
|
|
url: "data/Text_Align/",
|
|
url_detail: "data-detail/Text_Align/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "placement",
|
|
commit: "placement",
|
|
url: "data/Placement/",
|
|
url_detail: "data-detail/Placement/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "colorscheme",
|
|
commit: "colorscheme",
|
|
url: "data/Color_Scheme/",
|
|
url_detail: "data-detail/Color_Scheme/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "textcolor",
|
|
commit: "textcolor",
|
|
url: "data/Text_Color/",
|
|
url_detail: "data-detail/Text_Color/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "filtertype",
|
|
commit: "filtertype",
|
|
url: "data/Filter_Type/",
|
|
url_detail: "data-detail/Filter_Type/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "sorttype",
|
|
commit: "sorttype",
|
|
url: "data/Sort_Type/",
|
|
url_detail: "data-detail/Sort_Type/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "tablesetting",
|
|
commit: "tablesetting",
|
|
url: "data/Table_Setting/",
|
|
url_detail: "data-detail/Table_Setting/",
|
|
params: { sort: "id", values: "id,code,name,detail" },
|
|
},
|
|
{
|
|
name: "settingchoice",
|
|
commit: "settingchoice",
|
|
url: "data/Setting_Choice/",
|
|
url_detail: "data-detail/Setting_Choice/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "menuchoice",
|
|
commit: "menuchoice",
|
|
url: "data/Menu_Choice/",
|
|
url_detail: "data-detail/Menu_Choice/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "moneyunit",
|
|
commit: "moneyunit",
|
|
url: "data/Money_Unit/",
|
|
url_detail: "data-detail/Money_Unit/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "legaltype",
|
|
commit: "legaltype",
|
|
url: "data/Legal_Type/",
|
|
url_detail: "data-detail/Legal_Type/",
|
|
params: { page: -1 },
|
|
},
|
|
{ name: "sex", commit: "sex", url: "data/Sex/", url_detail: "data-detail/Sex/", params: {} },
|
|
{ name: "usertype", commit: "UserType", url: "data/User_Type/", url_detail: "data-detail/User_Type/", params: {} },
|
|
|
|
{
|
|
name: "executionmethod",
|
|
commit: "executionmethod",
|
|
url: "data/Execution_Method/",
|
|
url_detail: "data-detail/Execution_Method/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "customerpeople",
|
|
url: "data/Customer_People/",
|
|
url_detail: "data-detail/Customer_People/",
|
|
params: {
|
|
values:
|
|
"people__legal_code,id,customer,people,people__code,people__address,people__fullname,people__phone,relation,relation__code,relation__name,relation__en,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "legalrep",
|
|
url: "data/Legal_Rep/",
|
|
url_detail: "data-detail/Legal_Rep/",
|
|
params: {
|
|
values:
|
|
"id,organization,people,people__code,people__address,people__fullname,people__phone,relation,relation__code,relation__name,relation__en,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "customerfile",
|
|
url: "data/Customer_File/",
|
|
url_detail: "data-detail/Customer_File/",
|
|
params: { values: "id,ref,file,file__name,file__file" },
|
|
},
|
|
{
|
|
name: "customertype",
|
|
url: "data/Customer_Type/",
|
|
url_detail: "data-detail/Customer_Type/",
|
|
params: { values: "id,code,name,create_time" },
|
|
},
|
|
{
|
|
name: "peoplefile",
|
|
url: "data/People_File/",
|
|
url_detail: "data-detail/People_File/",
|
|
params: { values: "id,ref,file,file__name,file__file" },
|
|
},
|
|
{
|
|
name: "collaboratorfile",
|
|
url: "data/Collaborator_File/",
|
|
url_detail: "data-detail/Collaborator_File/",
|
|
params: { values: "id,ref,file,file__name,file__file" },
|
|
},
|
|
{
|
|
name: "applicationfile",
|
|
url: "data/Application_File/",
|
|
url_detail: "data-detail/Application_File/",
|
|
params: {
|
|
values:
|
|
"id,ref,file,file__name,file__file,file__type__code,file__type__name,file__doc_type__code,file__doc_type__name,file__doc_type__en",
|
|
},
|
|
},
|
|
{
|
|
name: "useraction",
|
|
url: "data/User_Action/",
|
|
url_detail: "data-detail/User_Action/",
|
|
params: {
|
|
values:
|
|
"id,action,action__code,action__name,action__message,action__image,action__file,action__link,user,message,image,file,link,create_time",
|
|
},
|
|
},
|
|
{
|
|
name: "relation",
|
|
commit: "relation",
|
|
url: "data/Relation/",
|
|
url_detail: "data-detail/Relation/",
|
|
params: { sort: "id" },
|
|
},
|
|
{
|
|
name: "company",
|
|
url: "data/Company/",
|
|
url_detail: "data-detail/Company/",
|
|
params: {
|
|
values:
|
|
"id,country,website,email,code,phone,shortname,fullname,address,create_time,update_time,creator,creator__fullname,updater,updater__fullname",
|
|
},
|
|
},
|
|
{ name: "exportlog", url: "data/Export_Log/", url_detail: "data-detail/Export_Log/", params: {} },
|
|
{ name: "bank", url: "data/Bank/", url_detail: "data-detail/Bank/", params: {} },
|
|
{ name: "exportcsv", url: "exportcsv/", params: {} },
|
|
{
|
|
name: "internalentry",
|
|
url: "data/Internal_Entry/",
|
|
url_detail: "data-detail/Internal_Entry/",
|
|
params: {
|
|
sort: "-id",
|
|
values:
|
|
"product__trade_code,allocation_amount,allocation_remain,allocation_detail,id,customer__fullname,product__trade_code,customer,customer__code,product,product__code,ref,category,category__code,category__name,account__currency__code,balance_before,balance_after,code,account,account__code,account__branch__name,account__type__name,date,amount,content,inputer,inputer__fullname,approver,approver__fullname,create_time,update_time,type,type__code,type__name",
|
|
},
|
|
},
|
|
{
|
|
name: "applicationrights",
|
|
url: "data/Application_Rights/",
|
|
url_detail: "data-detail/Application_Rights/",
|
|
params: { sort: "-id" },
|
|
},
|
|
|
|
{
|
|
name: "productfile",
|
|
url: "data/Product_File/",
|
|
url_detail: "data-detail/Product_File/",
|
|
params: { values: "id,product,file,create_time" },
|
|
},
|
|
{
|
|
name: "Email_Template",
|
|
url: "data/Email_Template/",
|
|
url_detail: "data-detail/Email_Template/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "projectfile",
|
|
url: "data/Project_File/",
|
|
url_detail: "data-detail/Project_File/",
|
|
params: { values: "id,project,file,create_time" },
|
|
},
|
|
{
|
|
name: "issuedplace",
|
|
url: "data/Issued_Place/",
|
|
url_detail: "data-detail/Issued_Place/",
|
|
params: { values: "id,code,name,create_time" },
|
|
},
|
|
{
|
|
name: "dealer",
|
|
url: "data/Dealer/",
|
|
url_detail: "data-detail/Dealer/",
|
|
params: { values: "id,count_sale,code,name,phone,address,email,create_time,sale_amount,pay_sale,commission_amount,pay_commission,commission_remain,batch_date" },
|
|
},
|
|
{
|
|
name: "layersetting",
|
|
url: "data/Layer_Setting/",
|
|
url_detail: "data-detail/Layer_Setting/",
|
|
params: { values: "id,code,name,detail,user,create_time,update_time" }
|
|
},
|
|
{
|
|
name: "grouprights",
|
|
commit: "grouprights",
|
|
url: "data/Group_Rights/",
|
|
url_detail: "data-detail/Group_Rights/",
|
|
params: {
|
|
values: 'id,setting,setting__vi,setting__code,setting__category,group,group__name,is_edit,create_time',
|
|
sort: '-id'
|
|
},
|
|
},
|
|
{
|
|
name: "discountmethod",
|
|
commit: "discountmethod",
|
|
url: "data/Discount_Method/",
|
|
url_detail: "data-detail/Discount_Method/",
|
|
params: {sort: '-id'},
|
|
},
|
|
{
|
|
name: "emailtemplate",
|
|
url: "data/Email_Template/",
|
|
url_detail: "data-detail/Email_Template/",
|
|
params: { values: "id,name,content,create_time,update_time" }
|
|
},
|
|
{
|
|
name: "gift",
|
|
commit: "gift",
|
|
url: "data/Gift/",
|
|
url_detail: "data-detail/Gift/",
|
|
params: {sort: '-id'},
|
|
},
|
|
{
|
|
name: "transactiongift",
|
|
commit: "transactiongift",
|
|
url: "data/Transaction_Gift/",
|
|
url_detail: "data-detail/Transaction_Gift/",
|
|
params: {},
|
|
},
|
|
{
|
|
name: "invoice",
|
|
commit: "invoice",
|
|
url: "data/Invoice/",
|
|
url_detail: "data-detail/Invoice/",
|
|
params: {},
|
|
},
|
|
];
|
|
const store = useStore();
|
|
const { $copy, $clone, $updateSeriesFields, $snackbar, $remove, $dialog } = useNuxtApp();
|
|
|
|
const requestLogin = function () {
|
|
store.commit("login", undefined);
|
|
store.commit("layersetting", undefined);
|
|
store.commit("lastlegendfiltertab", "Giỏ hàng");
|
|
window.location.href = `https://${mode === "dev" ? "dev." : ""}login.utopia.com.vn/signin?module=${module}&link=${window.location.origin}`;
|
|
};
|
|
|
|
const getpath = function (name) {
|
|
return name ? paths.find((v) => v.name === name).url : path;
|
|
};
|
|
|
|
const findapi = function (name) {
|
|
const result = Array.isArray(name)
|
|
? apis.filter((v) => name.findIndex((x) => v.name === x) >= 0)
|
|
: apis.find((v) => v.name === name);
|
|
return $copy(result);
|
|
};
|
|
|
|
const readyapi = function (list) {
|
|
var array = [];
|
|
list.forEach((element) => {
|
|
let found = apis.find((v) => v.name === element);
|
|
if (found) {
|
|
let ele = JSON.parse(JSON.stringify(found));
|
|
ele.ready = store[element] ? true : false;
|
|
array.push(ele);
|
|
}
|
|
});
|
|
return array;
|
|
};
|
|
|
|
// get data
|
|
const getapi = async function (list) {
|
|
try {
|
|
let arr = list.map((v) => {
|
|
let found = apis.find((api) => api.name === v.name);
|
|
let url = (v.path ? paths.find((x) => x.name === v.path).url : path) + (v.url ? v.url : found.url);
|
|
let params = v.params ? v.params : found.params === undefined ? {} : found.params;
|
|
params.login = store.login ? store.login.id : undefined;
|
|
return { url: url, params: params };
|
|
});
|
|
//let data = await Promise.all(arr.map(v=>axios.get(v.url, {params: v.params})))
|
|
let data = await Promise.all(arr.map((v) => $fetch(v.url, { params: v.params })));
|
|
data.map((v, i) => {
|
|
list[i].data = v;
|
|
if (list[i].commit) {
|
|
let data = v.rows ? v.rows : v;
|
|
store.commit(list[i].commit, data);
|
|
}
|
|
});
|
|
return list;
|
|
} catch (err) {
|
|
console.log(err);
|
|
return "error";
|
|
}
|
|
};
|
|
|
|
// insert data
|
|
const insertapi = async function (name, data, values, notify) {
|
|
try {
|
|
let found = findapi(name);
|
|
let curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
|
|
var rs;
|
|
if (!Array.isArray(data)) rs = await axios.post(`${curpath}${found.url}`, data, { params: { values: values } });
|
|
else {
|
|
let params = { action: "import", values: values };
|
|
rs = await axios.post(`${curpath}import-data/${found.url.substring(5, found.url.length - 1)}/`, data, {
|
|
params: params,
|
|
});
|
|
}
|
|
// update store
|
|
if (found.commit) {
|
|
if (store[found.commit]) {
|
|
let copy = JSON.parse(JSON.stringify(store[found.commit]));
|
|
let rows = Array.isArray(rs.data) ? rs.data : [rs.data];
|
|
rows.map((v) => {
|
|
if (v.id && !v.error) {
|
|
let idx = copy.findIndex((x) => x.id === v.id);
|
|
if (idx >= 0) copy[idx] = v;
|
|
else copy.push(v);
|
|
}
|
|
});
|
|
store.commit(found.commit, copy);
|
|
}
|
|
}
|
|
if (notify !== false) {
|
|
store.lang === "en"
|
|
? $snackbar("Data has been successfully saved to the system.", "Success", "Success")
|
|
: $snackbar("Dữ liệu đã được lưu vào hệ thống", "Thành công", "Success");
|
|
}
|
|
return rs.data;
|
|
} catch (err) {
|
|
console.log(err);
|
|
return "error";
|
|
}
|
|
};
|
|
|
|
// update api
|
|
const updateapi = async function (name, data, values, notify) {
|
|
try {
|
|
let found = findapi(name);
|
|
let curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
|
|
let updateUrl = found.url_detail ? found.url_detail : found.url;
|
|
let rs = await axios.put(`${curpath}${updateUrl}${data.id}/`, data, {
|
|
params: { values: values ? values : found.params.values },
|
|
});
|
|
if (found.commit) {
|
|
let index = store[found.commit] ? store[found.commit].findIndex((v) => v.id === rs.data.id) : -1;
|
|
if (index >= 0) {
|
|
var copy = JSON.parse(JSON.stringify(store[found.commit]));
|
|
if (Array.isArray(rs.data) === false) copy[index] = rs.data;
|
|
else {
|
|
rs.data.forEach((v) => {
|
|
let index = copy.findIndex((v) => v.id === v.id);
|
|
if (index >= 0) copy[index] = v;
|
|
});
|
|
}
|
|
store.commit(found.commit, copy);
|
|
}
|
|
}
|
|
if (notify !== false) {
|
|
store.lang === "en"
|
|
? $snackbar("Data has been successfully saved to the system.", "Success", "Success")
|
|
: $snackbar("Dữ liệu đã được lưu vào hệ thống", "Thành công", "Success");
|
|
}
|
|
return rs.data;
|
|
} catch (err) {
|
|
console.log(err);
|
|
return "error";
|
|
}
|
|
};
|
|
|
|
// patch api
|
|
const patchapi = async function (name, data, values, notify) {
|
|
try {
|
|
let found = findapi(name);
|
|
let curpath = found.path ? paths.find((x) => x.name === found.path).url : path;
|
|
let updateUrl = found.url_detail ? found.url_detail : found.url;
|
|
let rs = await axios.patch(`${curpath}${updateUrl}${data.id}/`, data, {
|
|
params: { values: values ? values : found.params?.values },
|
|
});
|
|
if (notify !== false) {
|
|
store.lang === "en"
|
|
? $snackbar("Data has been successfully saved to the system.", "Success", "Success")
|
|
: $snackbar("Dữ liệu đã được lưu vào hệ thống", "Thành công", "Success");
|
|
}
|
|
return rs.data;
|
|
} catch (err) {
|
|
console.log(err);
|
|
return "error";
|
|
}
|
|
};
|
|
|
|
const findpage = function (arr) {
|
|
var copy = $copy(store.pagetrack);
|
|
var doFind = function () {
|
|
let found = undefined;
|
|
for (let i = 1; i <= 30; i++) {
|
|
let name = `pagedata${i}`;
|
|
if (!copy[name]) {
|
|
found = name;
|
|
copy[name] = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) console.log("pagename not found");
|
|
return found;
|
|
};
|
|
let result;
|
|
if (arr) {
|
|
result = [];
|
|
arr.map((v) => {
|
|
result.push({ name: v, value: doFind() });
|
|
});
|
|
} else {
|
|
result = doFind(copy);
|
|
}
|
|
store.commit("pagetrack", copy);
|
|
return result;
|
|
};
|
|
|
|
const getpage = function (showFilter) {
|
|
return {
|
|
data: [],
|
|
fields: [],
|
|
filters: [],
|
|
update: undefined,
|
|
action: undefined,
|
|
filterby: undefined,
|
|
api: { full_data: true },
|
|
origin_api: { full_data: true },
|
|
tablesetting: undefined,
|
|
setting: undefined,
|
|
tabfield: true,
|
|
setpage: {},
|
|
showFilter: !showFilter ? true : showFilter,
|
|
};
|
|
};
|
|
|
|
const setpage = function (pagename, row, api) {
|
|
let json = row.detail;
|
|
let fields = $updateSeriesFields(json.fields);
|
|
let copy = store[pagename] || getpage();
|
|
copy.fields = fields;
|
|
copy.setting = $copy(row);
|
|
if (json.filters) copy.filters = $copy(json.filters);
|
|
if (json.tablesetting) copy.tablesetting = json.tablesetting;
|
|
if (api) {
|
|
let copyApi = $copy(api);
|
|
delete copyApi.data;
|
|
copyApi.full_data = api.data.full_data;
|
|
copyApi.total_rows = api.data.total_rows;
|
|
copy.api = copyApi;
|
|
copy.origin_api = copy;
|
|
}
|
|
store.commit(pagename, copy);
|
|
return copy;
|
|
};
|
|
|
|
const getdata = async function (name, filter, params, first) {
|
|
let found = findapi(name);
|
|
if (params) found.params = params;
|
|
else if (filter) found.params.filter = filter;
|
|
let rs = await getapi([found]);
|
|
let data = rs[0].data;
|
|
if (data) {
|
|
if (data.rows) {
|
|
return first ? (data.rows.length > 0 ? data.rows[0] : undefined) : data.rows;
|
|
} else {
|
|
let rows = Array.isArray(data) ? data : [data];
|
|
return first ? (rows.length > 0 ? rows[0] : data) : data;
|
|
}
|
|
} else {
|
|
let rows = Array.isArray(data) ? data : [data];
|
|
return first ? (rows.length > 0 ? rows[0] : data) : data;
|
|
}
|
|
};
|
|
|
|
const subscribe = (name, filter, callback) => {
|
|
const apiConfig = findapi(name);
|
|
if (!apiConfig) {
|
|
console.error(`[subscribe] API config for '${name}' not found.`);
|
|
return;
|
|
}
|
|
|
|
const urlParts = apiConfig.url.split('/').filter(p => p);
|
|
// Capitalize the model name for the backend consumer
|
|
const modelName = urlParts.length > 1 ? urlParts[1].charAt(0).toUpperCase() + urlParts[1].slice(1) : null;
|
|
|
|
if (!modelName) {
|
|
console.error(`[subscribe] Could not determine model name from URL for '${name}'.`);
|
|
return;
|
|
}
|
|
|
|
const params = $clone(apiConfig.params) || {};
|
|
|
|
// List of parameters that need to be stringified if they are objects
|
|
const paramsToJSONify = ['filter_or', 'exclude', 'distinct_values', 'calculation', 'final_filter', 'final_exclude'];
|
|
|
|
// Apply the filter passed to subscribe function
|
|
if (filter) {
|
|
params.filter = JSON.stringify(filter);
|
|
}
|
|
|
|
// Stringify other dictionary-like parameters if they exist and are objects
|
|
for (const key of paramsToJSONify) {
|
|
if (params[key] && typeof params[key] === 'object' && !Array.isArray(params[key])) {
|
|
params[key] = JSON.stringify(params[key]);
|
|
}
|
|
}
|
|
|
|
const payload = {
|
|
name: modelName,
|
|
params: params
|
|
};
|
|
|
|
subscribeToData(payload, callback);
|
|
};
|
|
|
|
// insert row
|
|
var insertrow = async function (name, data, values, pagename, notify) {
|
|
let result = await insertapi(name, data, values, notify);
|
|
if (result === "error" || !pagename || !store[pagename]) return result;
|
|
let copy = $clone(store[pagename]);
|
|
copy.update = { refresh: true };
|
|
store.commit(pagename, copy);
|
|
return result;
|
|
};
|
|
|
|
// update row
|
|
const updaterow = async function (name, data, values, pagename, notify) {
|
|
let result = await updateapi(name, data, values, notify);
|
|
if (result === "error" || !pagename || !store[pagename]) return result;
|
|
let copy = $clone(store[pagename]);
|
|
copy.update = { refresh: true };
|
|
store.commit(pagename, copy);
|
|
return result;
|
|
};
|
|
|
|
// patch row
|
|
const patchrow = async function (name, data, values, pagename, notify) {
|
|
let result = await patchapi(name, data, values, notify);
|
|
if (result === "error" || !pagename || !store[pagename]) return result;
|
|
let copy = $clone(store[pagename]);
|
|
copy.update = { refresh: true };
|
|
store.commit(pagename, copy);
|
|
return result;
|
|
};
|
|
|
|
// delete data
|
|
const deleteapi = async function (name, id) {
|
|
try {
|
|
var rs;
|
|
let found = findapi(name);
|
|
if (!Array.isArray(id)) rs = await $fetch(`${path}${found.url_detail}${id}`, { method: "delete" });
|
|
else {
|
|
let params = { action: "delete" };
|
|
rs = await $fetch(`${path}import-data/${found.url.substring(5, found.url.length - 1)}/`, id, {
|
|
params: params,
|
|
});
|
|
}
|
|
if (found.commit) {
|
|
let copy = JSON.parse(JSON.stringify(store[found.commit]));
|
|
if (!Array.isArray(id)) {
|
|
let index = copy.findIndex((v) => v.id === id);
|
|
if (index >= 0) $remove(copy, index);
|
|
} else {
|
|
rs.data.forEach((element) => {
|
|
let index = copy.findIndex((v) => v.id === element.id);
|
|
if (index >= 0) $remove(copy, index);
|
|
});
|
|
}
|
|
store.commit(found.name, copy);
|
|
console.log("copy", copy);
|
|
}
|
|
return id;
|
|
} catch (err) {
|
|
console.log(err);
|
|
if (err.response) {
|
|
let content = `<span class="has-text-danger">Đã xảy ra lỗi, xóa dữ liệu không thành công</span>`;
|
|
if (err.response.data)
|
|
content += `<p class="mt-2 has-text-grey-dark">
|
|
<sapn class="icon-text">Chi tiết<SvgIcon class="ml-1" v-bind="{name: 'right.svg', type: 'dark', size: 20}"></SvgIcon></span></p>
|
|
<p class="mt-2 has-text-grey-dark">${JSON.stringify(err.response.data)}</p>`;
|
|
$dialog(content, "Lỗi", "Error");
|
|
}
|
|
return "error";
|
|
}
|
|
};
|
|
|
|
// delete row
|
|
const deleterow = async function (name, id, pagename) {
|
|
let result = await deleteapi(name, id);
|
|
if (result === "error" || !pagename || !store[pagename]) return result;
|
|
let copy = $clone(store[pagename]);
|
|
copy.update = { refresh: true };
|
|
store.commit(pagename, copy);
|
|
return result;
|
|
};
|
|
|
|
// update page
|
|
const updatepage = function (pagename, row, action) {
|
|
let copy = $clone(store[pagename]);
|
|
let rows = Array.isArray(row) ? row : [row];
|
|
rows.map((x) => {
|
|
let idx = copy.data.findIndex((v) => v.id === x.id);
|
|
if (action === "delete") {
|
|
if (idx >= 0) $remove(copy.data, idx);
|
|
} else {
|
|
idx >= 0 ? (copy.data[idx] = x) : copy.data.unshift(x);
|
|
}
|
|
});
|
|
copy.update = { data: copy.data };
|
|
store.commit(pagename, copy);
|
|
};
|
|
|
|
const buildFileUrl = (file) => {
|
|
if (!file || typeof file !== 'string') {
|
|
console.error(`Invalid file__file: ${file}`)
|
|
return;
|
|
}
|
|
return `${getpath()}static/files/${encodeURIComponent(file)}`;
|
|
}
|
|
|
|
const generateDocument = async (params) => {
|
|
const apiBaseUrl = path;
|
|
|
|
const url = new URL(`${apiBaseUrl}generate-document/`);
|
|
if (params) {
|
|
for (const key in params) {
|
|
if (Object.hasOwnProperty.call(params, key)) {
|
|
const value = params[key];
|
|
if (value !== undefined && value !== null) {
|
|
url.searchParams.append(key, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
const response = await $fetch(url.toString(), {
|
|
method: "GET",
|
|
});
|
|
|
|
if (response && response.pdf) {
|
|
const pdfUrl = `${apiBaseUrl}static/contract/${response.pdf}`;
|
|
return { success: true, pdfUrl: pdfUrl, data: response };
|
|
} else {
|
|
console.error("generateDocument: Định dạng phản hồi API không hợp lệ.", response);
|
|
return { success: false, error: "Định dạng phản hồi API không hợp lệ." };
|
|
}
|
|
} catch (error) {
|
|
console.error("Lỗi khi tạo tài liệu:", error);
|
|
return { success: false, error: error.data?.message || error.message };
|
|
}
|
|
};
|
|
|
|
const accountEntry = async (params) => {
|
|
const apiBaseUrl = path;
|
|
|
|
try {
|
|
const response = await $fetch(`${apiBaseUrl}account-entry/`, {
|
|
method: "POST",
|
|
body: params,
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
if (response) {
|
|
return { success: true, data: response };
|
|
} else {
|
|
console.error("Định dạng phản hồi API không hợp lệ.", response);
|
|
return { success: false, error: "Định dạng phản hồi API không hợp lệ." };
|
|
}
|
|
} catch (error) {
|
|
console.error("Lỗi khi tạo accountEntry:", error);
|
|
return { success: false, error: error.data?.message || error.message };
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {'edit' | 'view'} right
|
|
* @param {{ code?: string, category?: string }} options
|
|
* `code` & `category` from `Biz_Setting`
|
|
* - If passed options, returns edit rights for `code` (useful for components used in modals in many different tabs)
|
|
* - If not passed, returns edit rights for current tab & subtab
|
|
* @returns {boolean}
|
|
*/
|
|
const getEditRights = (right = 'edit', { code, category } = {}) => {
|
|
if (!['edit', 'view'].includes(right)) throw new Error(`right ${right} is not one of ['edit', 'view']`);
|
|
|
|
const getRight = (rightObj) => {
|
|
return right === 'edit' ? rightObj && rightObj.is_edit : Boolean(rightObj);
|
|
}
|
|
|
|
if (store.rights.length === 0) return true; // full rights
|
|
|
|
if (code && category) {
|
|
// if passed, must pass both
|
|
const foundRight = store.rights.find(({ setting__category, setting__code }) => setting__category === category && setting__code === code);
|
|
return getRight(foundRight);
|
|
} else {
|
|
const { tab, subtab } = store.tabinfo;
|
|
let isTabEdit;
|
|
let isSubTabEdit;
|
|
|
|
const tabRight = store.rights.find(rights => rights.setting === tab.id);
|
|
isTabEdit = getRight(tabRight);
|
|
|
|
if (!subtab) isSubTabEdit = false;
|
|
else {
|
|
const subTabRight = store.rights.find(rights => rights.setting === subtab.id);
|
|
isSubTabEdit = getRight(subTabRight);
|
|
}
|
|
|
|
return isTabEdit || isSubTabEdit;
|
|
}
|
|
}
|
|
|
|
// --- WebSocket Integration ---
|
|
let socket = null;
|
|
const requests = {}; // Store callbacks for subscription responses
|
|
|
|
const connectWebSocket = () => {
|
|
if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
|
|
return;
|
|
}
|
|
|
|
// Use wss for https, ws for http
|
|
const wsProtocol = window.location.protocol === "https:" ? "wss:" : "wss:";
|
|
// Construct base URL without http/https protocol
|
|
const baseUrl = path.replace(/^https?:\/\//, '');
|
|
const wsUrl = `${wsProtocol}//${baseUrl}ws/data/`;
|
|
|
|
socket = new WebSocket(wsUrl);
|
|
|
|
socket.onopen = () => {
|
|
console.log("WebSocket connection established");
|
|
};
|
|
|
|
socket.onmessage = (event) => {
|
|
const response = JSON.parse(event.data);
|
|
|
|
// Handle initial subscription responses with specific callbacks
|
|
if (response.type === 'subscription_response' && response.request_id && requests[response.request_id]) {
|
|
const callback = requests[response.request_id];
|
|
callback(response.data);
|
|
delete requests[response.request_id]; // Clean up callback after use
|
|
} else {
|
|
// For all other messages (like realtime_update), dispatch a global event
|
|
// This decouples the plugin from the store logic
|
|
window.dispatchEvent(new CustomEvent('ws_message', { detail: response }));
|
|
}
|
|
};
|
|
|
|
socket.onclose = (event) => {
|
|
console.log("WebSocket connection closed:", event);
|
|
socket = null;
|
|
// Attempt to reconnect after a delay
|
|
setTimeout(connectWebSocket, 5000);
|
|
};
|
|
|
|
socket.onerror = (error) => {
|
|
console.error("WebSocket error:", error);
|
|
};
|
|
};
|
|
|
|
const subscribeToData = (payload, callback) => {
|
|
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
|
console.warn("WebSocket is not connected. Attempting to connect and retry.");
|
|
connectWebSocket();
|
|
// Retry subscription after a short delay
|
|
setTimeout(() => subscribeToData(payload, callback), 1000);
|
|
return;
|
|
}
|
|
|
|
const requestId = `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
if (callback) {
|
|
requests[requestId] = callback;
|
|
}
|
|
|
|
const request = {
|
|
action: "subscribe",
|
|
request_id: requestId,
|
|
payload: payload
|
|
};
|
|
|
|
socket.send(JSON.stringify(request));
|
|
console.log('[WebSocket] Sent subscription request:', request);
|
|
};
|
|
|
|
return {
|
|
provide: {
|
|
getpath,
|
|
findapi,
|
|
readyapi,
|
|
getapi,
|
|
getdata,
|
|
subscribe,
|
|
insertapi,
|
|
updateapi,
|
|
patchapi,
|
|
updaterow,
|
|
findpage,
|
|
getpage,
|
|
setpage,
|
|
insertrow,
|
|
deleteapi,
|
|
deleterow,
|
|
updatepage,
|
|
store,
|
|
requestLogin,
|
|
buildFileUrl,
|
|
generateDocument,
|
|
accountEntry,
|
|
getEditRights,
|
|
connectWebSocket,
|
|
subscribeToData,
|
|
mode,
|
|
},
|
|
};
|
|
});
|