Files
machartaa_admin_dist/dist/assets/index-eb1487b6.js
T
2026-06-17 14:02:02 +03:30

2 lines
20 KiB
JavaScript

import{_ as xe}from"./BasicMainCard-5c0935a0.js";import{_ as ge}from"./BasicModal.vue_vue_type_style_index_0_lang-0a56944e.js";import{_ as be}from"./BasicTextArea.vue_vue_type_style_index_0_lang-227d1ebf.js";import{a as ee,_ as ye,u as G}from"./useBaseTable-733b78fc.js";import{_ as te}from"./BasicInput.vue_vue_type_style_index_0_lang-f55e9984.js";import{_ as ae}from"./button.vue_vue_type_style_index_0_lang-251932bc.js";import{_ as he,I as A,d as ne,g as h,h as U,v as we,D as m,o as P,c as L,F as ke,a as t,b as c,t as D,p as Ie,w as f,e as Z,j as y,G as V,k as X,H as Ae}from"./index-a788bd53.js";import{d as Re,e as Se,f as Pe}from"./supabaseTableQuery-48420152.js";import{t as F}from"./useDataTime-c57a768a.js";import{I as z}from"./Icon-417849dc.js";import{g as Le}from"./index-42f5befb.js";import{e as Y,g as J}from"./convert-67c23be8.js";import{T as W}from"./index-d8ab383c.js";import{M as Ne}from"./index-0cdee960.js";import{S as Ce}from"./index-eb51b631.js";import{T as q}from"./shallowequal-f5e87a5a.js";import{U as $e}from"./index-4acd1bcb.js";import"./index-8174d632.js";import"./index-bdb5a596.js";import"./Col-c7805dec.js";import"./vnode-cf6f01a4.js";import"./_plugin-vue_export-helper-dc00b431.js";import"./isPlainObject-91b090bb.js";import"./index-c82b54d0.js";import"./FormItemContext-b811304e.js";import"./fa_IR-d5b5c457.js";import"./toArray-16bbe0cf.js";import"./pickAttrs-81a356a6.js";import"./useState-01af796f.js";import"./lodash-315d8ef5.js";import"./index-619be9cd.js";import"./usePrice-bc935b83.js";import"./useRefs-7f6d723f.js";import"./index-6cf8818b.js";function se(e,i){return Math.max(0,Math.round(e*(1-(i||0)/100)))}async function Te(e){const{TableEngineRequest:i}=await he(()=>import("./buildSupabaseQuery-279a98f9.js"),["assets/buildSupabaseQuery-279a98f9.js","assets/index-a788bd53.js","assets/index-f5b104f4.css"]),o={...e};!o.sort&&!o.order&&(o.order="-sort_order");const a=await i(o,"subscription_plans");if(Array.isArray(a==null?void 0:a.rows)){const d=a.rows.map((x,g)=>({...x,index:g,final_price:se(Number(x.price),Number(x.discount_percent||0))}));return{...a,rows:d}}return a}async function ze(e){const{limit:i=20,page:o=1,search:a}=e;let d=A.from("subscription_purchases").select("*, users(name, phone, first_name, last_name)",{count:"exact"});if(a!=null&&a.trim()){const u=`%${a.trim()}%`;d=d.or(`plan_title.ilike.${u},payment_status.ilike.${u},status.ilike.${u},users.name.ilike.${u},users.phone.ilike.${u},users.first_name.ilike.${u},users.last_name.ilike.${u}`)}d=Re(d,e,"-created_at",["created_at","plan_title","payment_status","status"]),d=Se(d,o,i);const{data:x,error:g,count:R}=await d;if(g)throw g;return Pe(x,R,e,u=>{const l=Array.isArray(u.users)?u.users[0]:u.users;let p="نامشخص";return l!=null&&l.name?p=l.name:l!=null&&l.first_name||l!=null&&l.last_name?p=`${l.first_name||""} ${l.last_name||""}`.trim():l!=null&&l.phone&&(p=l.phone),{...u,user_name:p,user_phone:(l==null?void 0:l.phone)||""}})}async function Be(e){const{data:i,error:o}=await A.from("subscription_plans").insert([{title:e.title,description:e.description||null,image_url:e.image_url,price:e.price,discount_percent:e.discount_percent??0,duration_days:e.duration_days,is_active:e.is_active??!0,sort_order:e.sort_order??0}]).select().single();if(o)throw o;return i}async function Ue(e,i){const{data:o,error:a}=await A.from("subscription_plans").update({title:i.title,description:i.description||null,image_url:i.image_url,price:i.price,discount_percent:i.discount_percent??0,duration_days:i.duration_days,is_active:i.is_active??!0,sort_order:i.sort_order??0,updated_at:new Date().toISOString()}).eq("id",e).select();if(a)throw a;return o}async function De(e){const{error:i}=await A.from("subscription_plans").delete().eq("id",e);if(i)throw i}async function Ee(e,i){const{data:o,error:a}=await A.from("subscription_plans").update({is_active:i,updated_at:new Date().toISOString()}).eq("id",e).select();if(a)throw a;return o}function Q(e){return Number(e||0).toLocaleString("fa-IR")}const Me=[{title:"ردیف",dataIndex:"id",key:"id",filterable:!1,width:70,align:"center",customRender:e=>(e.record.index??0)+1},{title:"عنوان",dataIndex:"title",key:"title"},{title:"مدت (روز)",dataIndex:"duration_days",key:"duration_days",width:100,align:"center"},{title:"قیمت (ریال)",dataIndex:"price",key:"price",customRender:e=>Q(e.record.price)},{title:"تخفیف %",dataIndex:"discount_percent",key:"discount_percent",width:90,align:"center"},{title:"قیمت نهایی",dataIndex:"final_price",key:"final_price",customRender:e=>Q(e.record.final_price)},{title:"فعال",dataIndex:"is_active",key:"is_active",customRender:e=>e.record.is_active?"بله":"خیر"},{title:"ترتیب",dataIndex:"sort_order",key:"sort_order",width:80,align:"center"},{title:"ایجاد",dataIndex:"created_at",key:"created_at",customRender:e=>F(e.record.created_at)},{title:"عملیات",dataIndex:"action",key:"action",slot:"action",filterable:!1,align:"center"}];function Oe(e){return Number(e||0).toLocaleString("fa-IR")}const qe={pending:"در انتظار",paid:"پرداخت شده",failed:"ناموفق",cancelled:"لغو شده"},Fe={pending:"در انتظار",active:"فعال",expired:"منقضی",cancelled:"لغو شده"},Ze=[{title:"ردیف",dataIndex:"id",key:"id",filterable:!1,width:70,align:"center",customRender:e=>(e.record.index??0)+1},{title:"کاربر",dataIndex:"user_name",key:"user_name"},{title:"موبایل",dataIndex:"user_phone",key:"user_phone"},{title:"پلن",dataIndex:"plan_title",key:"plan_title"},{title:"مبلغ",dataIndex:"final_price",key:"final_price",customRender:e=>Oe(e.record.final_price)},{title:"پرداخت",dataIndex:"payment_status",key:"payment_status",customRender:e=>qe[e.record.payment_status]||e.record.payment_status},{title:"وضعیت",dataIndex:"status",key:"status",customRender:e=>Fe[e.record.status]||e.record.status},{title:"انقضا",dataIndex:"expires_at",key:"expires_at",customRender:e=>e.record.expires_at?F(e.record.expires_at):"-"},{title:"تاریخ خرید",dataIndex:"created_at",key:"created_at",customRender:e=>F(e.record.created_at)}],I={ZARINPAL_MERCHANT_ID:"zarinpal_merchant_id",ZARINPAL_SANDBOX:"zarinpal_sandbox",SUBSCRIPTION_CALLBACK_URL:"subscription_app_callback_url",ZARINPAL_ENABLED:"zarinpal_enabled"},Ke=Object.values(I);function je(e){const i=(e[I.ZARINPAL_SANDBOX]||"no").toLowerCase(),o=(e[I.ZARINPAL_ENABLED]||"yes").toLowerCase();return{zarinpal_merchant_id:e[I.ZARINPAL_MERCHANT_ID]||"",zarinpal_sandbox:i==="yes"||i==="true"||i==="1",zarinpal_enabled:o!=="no"&&o!=="false"&&o!=="0",subscription_app_callback_url:e[I.SUBSCRIPTION_CALLBACK_URL]||"https://macharta.ir"}}async function B(e,i){const{data:o,error:a}=await A.from("configs").select("id").eq("key",e).maybeSingle();if(a)throw a;if(o!=null&&o.id){const{data:g,error:R}=await A.from("configs").update({value:i}).eq("key",e).select("id");if(R)throw R;if(!(g!=null&&g.length))throw new Error("ذخیره انجام نشد. لطفاً migration دسترسی configs را در Supabase اجرا کنید.");return}const{data:d,error:x}=await A.from("configs").insert({key:e,value:i}).select("id");if(x)throw x;if(!(d!=null&&d.length))throw new Error("ایجاد تنظیم انجام نشد. لطفاً migration دسترسی configs را در Supabase اجرا کنید.")}async function ie(){const{data:e,error:i}=await A.from("configs").select("key, value").in("key",Ke);if(i)throw i;const o=(e||[]).reduce((a,d)=>(a[d.key]=d.value??"",a),{});return je(o)}async function He(e){return await B(I.ZARINPAL_MERCHANT_ID,e.zarinpal_merchant_id.trim()),await B(I.ZARINPAL_SANDBOX,e.zarinpal_sandbox?"yes":"no"),await B(I.ZARINPAL_ENABLED,e.zarinpal_enabled?"yes":"no"),await B(I.SUBSCRIPTION_CALLBACK_URL,e.subscription_app_callback_url.trim().replace(/\/$/,"")),ie()}const Ge={class:"max-w-2xl space-y-4"},Ve=t("p",{class:"text-sm text-gray-600 mb-4"}," کد مرچنت و آدرس بازگشت از درگاه در اینجا تنظیم می‌شود. اپ کاربر از همین تنظیمات برای اتصال به زرین‌پال استفاده می‌کند. ",-1),Xe={key:0,class:"py-8 text-center"},Ye=t("div",{class:"mb-1 text-sm text-gray-600"},"کد مرچنت زرین‌پال (Merchant ID)",-1),Je=t("div",{class:"mb-1 text-sm text-gray-600"},"آدرس بازگشت از درگاه (URL اپ کاربر)",-1),We=t("div",{class:"text-xs text-gray-500 mt-1"},[Z(" مسیر callback به‌صورت خودکار اضافه می‌شود: "),t("code",null,"/subscriptions/callback")],-1),Qe={class:"flex items-center gap-3"},et=t("span",{class:"text-sm"},"فعال بودن درگاه زرین‌پال",-1),tt={class:"flex items-center gap-3"},at=t("span",{class:"text-sm"},"حالت تست (Sandbox)",-1),nt=ne({__name:"PaymentGatewaySettings",setup(e){const i=h(!0),o=h(!1),a=h({zarinpal_merchant_id:"",zarinpal_sandbox:!1,zarinpal_enabled:!0,subscription_app_callback_url:"https://macharta.ir"}),d=U(()=>{var u;return a.value.zarinpal_enabled?a.value.zarinpal_sandbox?!0:!!((u=a.value.zarinpal_merchant_id)!=null&&u.trim()):!1}),x=U(()=>{var u;return a.value.zarinpal_enabled?a.value.zarinpal_sandbox?"حالت تست فعال است — پرداخت از sandbox زرین‌پال انجام می‌شود.":(u=a.value.zarinpal_merchant_id)!=null&&u.trim()?"درگاه برای پرداخت واقعی آماده است.":"کد مرچنت وارد نشده — درگاه آماده پرداخت واقعی نیست.":"درگاه غیرفعال است — کاربران نمی‌توانند پرداخت کنند."}),g=U(()=>d.value?"bg-green-50 border-green-200 text-green-800":"bg-amber-50 border-amber-200 text-amber-800");we(async()=>{try{a.value=await ie()}catch(u){m.error((u==null?void 0:u.message)||"خطا در بارگذاری تنظیمات")}finally{i.value=!1}});async function R(){var u,l;if(!((u=a.value.subscription_app_callback_url)!=null&&u.trim())){m.warning("آدرس بازگشت از درگاه الزامی است");return}if(a.value.zarinpal_enabled&&!a.value.zarinpal_sandbox&&!((l=a.value.zarinpal_merchant_id)!=null&&l.trim())){m.warning("برای پرداخت واقعی، کد مرچنت الزامی است");return}o.value=!0;try{a.value=await He(a.value),m.success("تنظیمات درگاه ذخیره شد")}catch(p){m.error((p==null?void 0:p.message)||"خطا در ذخیره")}finally{o.value=!1}}return(u,l)=>{const p=te,w=ee,C=ae;return P(),L("div",Ge,[Ve,i.value?(P(),L("div",Xe,"در حال بارگذاری...")):(P(),L(ke,{key:1},[t("div",null,[Ye,c(p,{value:a.value.zarinpal_merchant_id,"onUpdate:value":l[0]||(l[0]=r=>a.value.zarinpal_merchant_id=r),placeholder:"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"},null,8,["value"])]),t("div",null,[Je,c(p,{value:a.value.subscription_app_callback_url,"onUpdate:value":l[1]||(l[1]=r=>a.value.subscription_app_callback_url=r),placeholder:"https://macharta.ir"},null,8,["value"]),We]),t("div",Qe,[c(w,{value:a.value.zarinpal_enabled,"onUpdate:value":l[2]||(l[2]=r=>a.value.zarinpal_enabled=r)},null,8,["value"]),et]),t("div",tt,[c(w,{value:a.value.zarinpal_sandbox,"onUpdate:value":l[3]||(l[3]=r=>a.value.zarinpal_sandbox=r)},null,8,["value"]),at]),t("div",{class:Ie(["rounded-lg border p-3 text-sm",g.value])},D(x.value),3),c(C,{type:"primary",loading:o.value,onClick:R},{default:f(()=>[Z(" ذخیره تنظیمات درگاه ")]),_:1},8,["loading"])],64))])}}}),st={class:"flex justify-between items-center mb-4"},it=t("h2",null,"مدیریت اشتراک‌ها",-1),rt={class:"gap-2 flex justify-center"},lt=t("span",null,"حذف",-1),ot=t("span",null,"ویرایش",-1),ct=t("div",{class:"mb-4"},[t("h2",null,"لیست خرید اشتراک")],-1),ut=t("div",{class:"mb-4"},[t("h2",null,"تنظیمات درگاه پرداخت")],-1),dt={class:"space-y-4 relative"},_t={key:0,class:"absolute inset-0 bg-white/60 z-10 flex items-center justify-center"},pt={class:"grid grid-cols-2 gap-4"},mt=t("div",{class:"mb-1 text-sm text-gray-600"},"عنوان اشتراک",-1),vt=t("div",{class:"mb-1 text-sm text-gray-600"},"مدت اشتراک (روز)",-1),ft={class:"grid grid-cols-3 gap-4"},xt=t("div",{class:"mb-1 text-sm text-gray-600"},"مبلغ (ریال)",-1),gt=t("div",{class:"mb-1 text-sm text-gray-600"},"تخفیف (درصد)",-1),bt=t("div",{class:"mb-1 text-sm text-gray-600"},"قیمت نهایی (ریال)",-1),yt={class:"mt-2 font-semibold text-green-700"},ht={class:"grid grid-cols-2 gap-4"},wt=t("div",{class:"mb-1 text-sm text-gray-600"},"ترتیب نمایش",-1),kt=t("div",{class:"mb-1 text-sm text-gray-600"},"وضعیت",-1),It={class:"flex items-center gap-2 mt-2"},At={class:"text-sm text-gray-600"},Rt=t("div",{class:"mb-1 text-sm text-gray-600"},"توضیحات",-1),St={class:"flex justify-center"},Pt=t("div",{class:"mb-1 text-sm text-gray-600"},"تصویر اشتراک",-1),Lt={key:0},Nt=t("div",null,"آپلود تصویر",-1),da=ne({__name:"index",setup(e){const i=W,o=W.TabPane,a=h("plans"),d=h(!1),x=h(!1),g=h(null),[R,u]=G(),[l]=G(),p=h([]),w=h(0),C=()=>({title:"",description:"",image_url:null,price:0,discount_percent:0,duration_days:30,is_active:!0,sort_order:0}),r=h(C()),re=U(()=>se(Number(r.value.price),Number(r.value.discount_percent)).toLocaleString("fa-IR")),le={columns:Me,api:Te,defaultPageLimit:20},oe={columns:Ze,api:ze,defaultPageLimit:20};function K(){r.value=C(),p.value=[]}function ce(){x.value=!1,g.value=null,K(),d.value=!0}function j(){d.value=!1,K()}function ue(_){return _.type.startsWith("image/")?_.size/1024/1024>=5?(m.error("حجم تصویر باید کمتر از 5MB باشد"),!1):!0:(m.error("فقط فایل تصویری مجاز است"),!1)}async function de(_){const{file:n,onSuccess:S,onError:b,onProgress:k}=_,$=new FormData;$.append("file",n);const E=`${Ae}/upload/machartaa-img`;w.value++,await new Promise((M,N)=>{const s=new XMLHttpRequest;s.open("POST",E);const T=Le()||localStorage.getItem("tamin_token")||"";s.setRequestHeader("Authorization",`Bearer ${T}`),s.upload.onprogress=v=>{v.lengthComputable&&(k==null||k({percent:Math.round(v.loaded/v.total*100)}))},s.onload=()=>{if(s.status>=200&&s.status<300)try{const v=JSON.parse(s.responseText||"{}"),fe=v.full_src||v.url||v.src||v.path||v.data&&(v.data.full_src||v.data.url||v.data.src||v.data.path)||"",O=Y(fe),H=J(O);r.value.image_url=O,p.value=H?[{uid:`${Date.now()}`,name:"image.jpg",status:"done",url:H,response:{path:O}}]:[],S==null||S(v,s),m.success("تصویر با موفقیت آپلود شد!"),M()}catch(v){b==null||b(v,s),N(v)}else b==null||b(new Error("خطا در آپلود تصویر"),s),N(new Error("خطا در آپلود تصویر"))},s.onerror=()=>{b==null||b(new Error("خطا در آپلود تصویر"),s),N(new Error("خطا در آپلود تصویر"))},s.onloadend=()=>{w.value=Math.max(0,w.value-1)},s.send($)})}async function _e(){var _;if(w.value>0){m.warning("لطفاً تا پایان آپلود صبر کنید");return}if(!((_=r.value.title)!=null&&_.trim())){m.warning("عنوان الزامی است");return}if(!r.value.duration_days||Number(r.value.duration_days)<1){m.warning("مدت اشتراک باید حداقل ۱ روز باشد");return}try{const n={...r.value,price:Number(r.value.price)||0,discount_percent:Number(r.value.discount_percent)||0,duration_days:Number(r.value.duration_days),sort_order:Number(r.value.sort_order)||0};x.value&&g.value?(await Ue(g.value,n),m.success("اشتراک ویرایش شد")):(await Be(n),m.success("اشتراک افزوده شد")),j(),await u()}catch(n){m.error((n==null?void 0:n.message)||"خطا در ذخیره")}}function pe(_){x.value=!0,g.value=_.id;const n=Y(_.image_url)||null;r.value={title:_.title||"",description:_.description||"",image_url:n,price:_.price||0,discount_percent:_.discount_percent||0,duration_days:_.duration_days||30,is_active:_.is_active??!0,sort_order:_.sort_order??0};const S=n?J(n):null;p.value=S?[{uid:"-1",name:"image.jpg",status:"done",url:S,response:{path:n}}]:[],d.value=!0}function me(_){Ne.confirm({title:"حذف اشتراک",content:`آیا از حذف «${_.title}» مطمئن هستید؟`,okText:"بله، حذف کن",cancelText:"انصراف",okType:"danger",centered:!0,onOk:async()=>{try{await De(_.id),m.success("حذف شد"),await u()}catch(n){m.error((n==null?void 0:n.message)||"خطا در حذف")}}})}async function ve(_){try{await Ee(_.id,!_.is_active),m.success("وضعیت به‌روز شد"),await u()}catch(n){m.error((n==null?void 0:n.message)||"خطا")}}return(_,n)=>{const S=ae,b=ye,k=te,$=ee,E=be,M=ge,N=xe;return P(),L("div",null,[c(N,null,{default:f(()=>[c(y(i),{activeKey:a.value,"onUpdate:activeKey":n[0]||(n[0]=s=>a.value=s)},{default:f(()=>[c(y(o),{key:"plans",tab:"پلن‌های اشتراک"},{default:f(()=>[t("div",st,[it,c(S,{type:"primary",onClick:ce},{default:f(()=>[Z("افزودن اشتراک")]),_:1})]),c(b,V(le,{ref:"table",onRegister:y(R)}),{action:f(({record:s})=>[t("div",rt,[c(y(q),{class:"cursor-pointer"},{title:f(()=>[t("span",null,D(s.is_active?"غیرفعال کردن":"فعال کردن"),1)]),default:f(()=>[c(z,{icon:s.is_active?"vuesax-linear:eye-slash":"vuesax-linear:eye",color:s.is_active?"#F59E0B":"#16A34A",onClick:T=>ve(s)},null,8,["icon","color","onClick"])]),_:2},1024),c(y(q),{class:"cursor-pointer"},{title:f(()=>[lt]),default:f(()=>[c(z,{icon:"vuesax-linear:trash",color:"#DC2626",onClick:T=>me(s)},null,8,["onClick"])]),_:2},1024),c(y(q),{class:"cursor-pointer"},{title:f(()=>[ot]),default:f(()=>[c(z,{icon:"vuesax-linear:edit",color:"#1D4ED8",onClick:T=>pe(s)},null,8,["onClick"])]),_:2},1024)])]),_:1},16,["onRegister"])]),_:1}),c(y(o),{key:"purchases",tab:"خریدهای کاربران"},{default:f(()=>[ct,c(b,V(oe,{onRegister:y(l)}),null,16,["onRegister"])]),_:1}),c(y(o),{key:"gateway",tab:"تنظیمات درگاه (زرین‌پال)"},{default:f(()=>[ut,c(nt)]),_:1})]),_:1},8,["activeKey"]),c(M,{visible:d.value,"onUpdate:visible":n[9]||(n[9]=s=>d.value=s),title:x.value?"ویرایش اشتراک":"افزودن اشتراک",onOk:_e,onCancel:j,width:"70%",confirmLoading:w.value>0},{default:f(()=>[t("div",dt,[w.value>0?(P(),L("div",_t,[c(y(Ce),{size:"large"})])):X("",!0),t("div",pt,[t("div",null,[mt,c(k,{value:r.value.title,"onUpdate:value":n[1]||(n[1]=s=>r.value.title=s),placeholder:"مثلاً اشتراک یک ماهه"},null,8,["value"])]),t("div",null,[vt,c(k,{value:r.value.duration_days,"onUpdate:value":n[2]||(n[2]=s=>r.value.duration_days=s),type:"number",min:"1",placeholder:"30"},null,8,["value"])])]),t("div",ft,[t("div",null,[xt,c(k,{value:r.value.price,"onUpdate:value":n[3]||(n[3]=s=>r.value.price=s),type:"number",min:"0",placeholder:"100000"},null,8,["value"])]),t("div",null,[gt,c(k,{value:r.value.discount_percent,"onUpdate:value":n[4]||(n[4]=s=>r.value.discount_percent=s),type:"number",min:"0",max:"100",placeholder:"0"},null,8,["value"])]),t("div",null,[bt,t("div",yt,D(re.value),1)])]),t("div",ht,[t("div",null,[wt,c(k,{value:r.value.sort_order,"onUpdate:value":n[5]||(n[5]=s=>r.value.sort_order=s),type:"number",placeholder:"0"},null,8,["value"])]),t("div",null,[kt,t("div",It,[c($,{value:r.value.is_active,"onUpdate:value":n[6]||(n[6]=s=>r.value.is_active=s)},null,8,["value"]),t("span",At,D(r.value.is_active?"فعال":"غیرفعال"),1)])])]),t("div",null,[Rt,c(E,{value:r.value.description,"onUpdate:value":n[7]||(n[7]=s=>r.value.description=s),placeholder:"توضیحات اشتراک",rows:4},null,8,["value"])]),t("div",St,[t("div",null,[Pt,c(y($e),{"file-list":p.value,"onUpdate:fileList":n[8]||(n[8]=s=>p.value=s),"before-upload":ue,"custom-request":de,accept:"image/*","max-count":1,"list-type":"picture-card"},{default:f(()=>[p.value.length<1?(P(),L("div",Lt,[c(z,{icon:"vuesax-linear:image",class:"text-2xl mb-2"}),Nt])):X("",!0)]),_:1},8,["file-list"])])])])]),_:1},8,["visible","title","confirmLoading"])]),_:1})])}}});export{da as default};