2 lines
35 KiB
JavaScript
2 lines
35 KiB
JavaScript
import{_ as Oe}from"./BasicShowContext.vue_vue_type_script_setup_true_lang-2980cfed.js";import{_ as ye}from"./BasicModal.vue_vue_type_style_index_0_lang-aed8f5e4.js";import{u as ce,_ as xe}from"./useBaseTable-e7a67916.js";import{_ as ze}from"./button.vue_vue_type_style_index_0_lang-f90e25b2.js";import{g as qe}from"./member-0bd612b3.js";import{I as J,d as fe,i as u,j as _e,z as Ee,o as k,c as T,b as n,e as a,l as M,w as s,f as d,t as p,n as q,F as be,q as Fe,R as ue,H as h,x as Ne,V as Ve,k as pe,h as Ke}from"./index-1ba0f9ec.js";import{t as de}from"./useDataTime-6e234adb.js";import{_ as je,v as ke,t as $e}from"./AudienceSegmentPicker.vue_vue_type_script_setup_true_lang-65f61d77.js";import{M as ve,_ as He}from"./index-ec322234.js";import{C as ge}from"./index-e22339b6.js";import{I as he,_ as Le}from"./index-aafc0fe2.js";import{I as Y}from"./Icon-29e38d16.js";import{S as Pe}from"./index-4bff02a6.js";import{B as Ae}from"./index-8f2b7e91.js";import{D as Be,_ as De}from"./index-5258a30e.js";import{S as Ue,_ as Me}from"./index-e0664925.js";import{T as Z}from"./isSymbol-355a1404.js";import{_ as Je}from"./BasicInput.vue_vue_type_style_index_0_lang-e6a4e582.js";import{_ as Ge,T as Qe}from"./index-f22a4554.js";import"./updateLocale-a8654270.js";import"./shallowequal-e0d9eafb.js";import"./_plugin-vue_export-helper-31e07528.js";import"./vnode-c4e67237.js";import"./useState-dcd360f8.js";import"./useMemo-ee45fb46.js";import"./FormItemContext-33ef1221.js";import"./omit-f5d28cd3.js";import"./lodash-27f814e6.js";import"./BaseSwitch.vue_vue_type_script_setup_true_lang-36a1ea6e.js";import"./index-c8127d4e.js";import"./Badge-8a8eeb58.js";import"./isNumeric-3f69e2aa.js";import"./index-a8579634.js";import"./index-73cafb1e.js";import"./index-175b83cf.js";import"./userSegments-081d8da2.js";import"./index-f847a367.js";import"./isMobile-e2e89480.js";import"./dayjs-1cfa00b1.js";import"./index-0d716d4e.js";import"./DialogWrap-394d7eb0.js";import"./pickAttrs-0ddf9a54.js";import"./styleChecker-19ce40ea.js";import"./index-876da578.js";import"./index-3f6d5caa.js";import"./LeftOutlined-93011b30.js";import"./css-aae66f86.js";import"./SearchOutlined-95278fe5.js";import"./toArray-41940180.js";import"./isPlainObject-e945bc1f.js";import"./usePrice-bc935b83.js";import"./useRefs-5e33302c.js";import"./_flatRest-7877cdf8.js";const Ie=async t=>(await J.post("/admin/sms/preview",t)).data,We=async t=>(await J.post("/admin/sms/test",t)).data,Re=async t=>(await J.post("/admin/sms/campaigns/start",t)).data,Xe=async t=>(await J.post(`/admin/sms/campaigns/${t}/continue-batch`)).data,Ye=async t=>(await J.post(`/admin/sms/campaigns/${t}/resume`)).data,Ze=async t=>{var v;const o=await J.get("/admin/sms/campaigns",{params:{page:t.page,limit:t.limit,search:t.search}}),x=t.page||1,R=t.limit||20,F=(x-1)*R;return{rows:(o.data||[]).map((b,L)=>({...b,index:F+L})),total:o.total??((v=o.data)==null?void 0:v.length)??0,query:{...t,total:o.total??0,page:x,limit:R}}},Se=async(t,o)=>(await J.get(`/admin/sms/campaigns/${t}`,{params:o})).data,et=async t=>{const o=await J.get("/admin/sms/automations"),x=t.page||1,R=t.limit||20,F=(x-1)*R,v=o.data||[];return{rows:v.map((b,L)=>({...b,index:F+L})),total:o.total??v.length,query:{...t,total:o.total??v.length,page:x,limit:R}}},Ce=async(t,o)=>(await J.patch(`/admin/sms/automations/${t}`,o)).data,Te=async(t,o)=>(await J.get(`/admin/sms/automations/${t}/sends`,{params:o})).data,tt=async(t,o)=>(await J.post(`/admin/sms/automations/${t}/test`,{phone:o})).data,at=[{title:"ردیف",dataIndex:"id",key:"id",filterable:!1,customRender:t=>t.index+1},{title:"نام",dataIndex:"first_name",key:"first_name",filterable:!0},{title:"نام خانوادگی",dataIndex:"last_name",key:"last_name",filterable:!0},{title:"شماره همراه",dataIndex:"phone",key:"phone",filterable:!0},{title:"زمان ثبتنام",dataIndex:"created_at",key:"created_at",type:"Date",filterable:!0,customRender:t=>t.record.created_at?de(t.record.created_at):"-"}],nt={class:"grid grid-cols-1 xl:grid-cols-3 gap-4 mb-4"},st={class:"xl:col-span-2 space-y-4"},lt=n("div",{class:"mb-1 text-sm text-gray-600"},"متن پیامک *",-1),it={class:"flex flex-wrap gap-4 items-center"},ot={class:"flex flex-wrap gap-2"},rt={class:"bg-gray-50 rounded-lg p-4 border border-gray-200 space-y-2 text-sm"},ct=n("div",{class:"font-semibold text-gray-700 mb-2"},"خلاصه ارسال",-1),ut={key:0},dt={key:0,class:"text-amber-600 mt-1"},mt={key:0},pt={key:1,class:"text-gray-500"},_t={key:2,class:"pt-2 border-t border-gray-200"},vt=n("div",{class:"font-medium mb-1"},"نمونه گیرندگان:",-1),ft={class:"space-y-1 text-xs text-gray-600"},gt={key:3,class:"pt-2 border-t border-gray-200"},ht=n("div",{class:"font-medium mb-1"},"آخرین کمپین:",-1),yt={class:"text-blue-600 mt-1"},xt={class:"border-t border-gray-200 pt-4"},bt=n("div",{class:"mb-2 text-sm text-gray-600"}," کاربران را فیلتر کنید و گیرندگان مورد نظر را انتخاب کنید. فقط کاربرانی که شماره موبایل دارند نمایش داده میشوند. ",-1),wt={class:"space-y-3"},kt=n("div",{class:"mb-1 text-sm text-gray-600"},"شماره موبایل",-1),$t=n("div",{class:"text-xs text-gray-500"}," متن پیامک از باکس اصلی استفاده میشود. ",-1),It=fe({__name:"SendPanel",emits:["campaign-started"],setup(t,{emit:o}){const{TextArea:x}=he,[R,F]=ce(),v=u(""),b=u(!0),L=u(!0),y=u(null),O=u(!1),i=u(!1),S=u(null),A=u(!1),B=u(""),K=u(!1),I=u([]),C=u({}),N=u({segments:[],inactiveDays:7,subscriberInactiveDays:3}),j=u(!1),V=u(""),G=_e(()=>({selectedRowKeys:I.value,onChange:f=>{I.value=f.map(String)},preserveSelectedRowKeys:!0})),ee=u({columns:at,api:async f=>{const r={...f,filters:[...f.filters||[],{field:"phone",op:"nn",value:!0,cr:"and",type:"switch",hidden:!0}]};return b.value&&r.filters.push({field:"first_name",op:"nn",value:!0,cr:"and",type:"switch",hidden:!0},{field:"last_name",op:"nn",value:!0,cr:"and",type:"switch",hidden:!0}),!r.sort&&!r.order&&(r.order="-created_at"),C.value=r,qe(r)},defaultPageLimit:20,height:"45vh"});Ee(b,()=>{y.value=null,F()});function Q(f){var r;return{message:v.value.trim(),appendAppName:L.value,registrationComplete:b.value,search:C.value.search||void 0,filters:(r=C.value.filters)==null?void 0:r.filter(l=>!l.hidden),sort:C.value.sort||void 0,order:C.value.order||void 0,mode:f,userIds:f==="selected"?I.value:void 0}}async function te(){var f,r;if(!v.value.trim()){h.warning("ابتدا متن پیامک را وارد کنید");return}O.value=!0;try{y.value=await Ie(Q("filtered"))}catch(l){h.error(((r=(f=l==null?void 0:l.response)==null?void 0:f.data)==null?void 0:r.error)||"خطا در پیشنمایش")}finally{O.value=!1}}async function ae(){var f,r;if(!v.value.trim()){h.warning("متن پیامک الزامی است");return}if(!B.value.trim()){h.warning("شماره موبایل الزامی است");return}K.value=!0;try{await We({...Q("filtered"),phone:B.value.trim()}),h.success("پیامک تستی ارسال شد"),A.value=!1}catch(l){h.error(((r=(f=l==null?void 0:l.response)==null?void 0:f.data)==null?void 0:r.error)||"ارسال تستی ناموفق بود")}finally{K.value=!1}}async function X(f){if(!v.value.trim()){h.warning("متن پیامک الزامی است");return}if(f==="selected"&&!I.value.length){h.warning("حداقل یک کاربر انتخاب کنید");return}const r=f==="selected"?`آیا از ارسال پیامک به ${I.value.length} کاربر انتخابشده مطمئن هستید؟`:"آیا از ارسال پیامک به همه کاربران فیلترشده مطمئن هستید؟";return new Promise(l=>{ve.confirm({title:"تأیید ارسال پیامک",content:r,okText:"بله، ارسال کن",cancelText:"انصراف",okType:"danger",centered:!0,onOk:async()=>{var m,$;i.value=!0,S.value=null;try{const _=await Re(Q(f));S.value=_,o("campaign-started",_.campaignId),h.success(_.hasMoreBatches?`کمپین #${_.campaignId}: دسته اول ${_.totalRecipients.toLocaleString("fa-IR")} نفر — پس از اتمام، ${(_.remainingRecipients||0).toLocaleString("fa-IR")} نفر باقیمانده با تأیید ارسال میشود`:`کمپین #${_.campaignId} با ${_.totalRecipients.toLocaleString("fa-IR")} گیرنده در پسزمینه ارسال میشود`)}catch(_){h.error((($=(m=_==null?void 0:_.response)==null?void 0:m.data)==null?void 0:$.error)||"شروع کمپین ناموفق بود")}finally{i.value=!1,l()}},onCancel:()=>l()})})}function ne(){return X("selected")}function W(){return X("filtered")}async function se(){var l,m;if(!v.value.trim()){h.warning("ابتدا متن پیامک را وارد کنید");return}const f={...N.value,includeUserIds:I.value},r=ke(f);if(r){h.warning(r);return}j.value=!0,V.value="";try{const $=$e(f),_=await Ie({message:v.value.trim(),appendAppName:L.value,registrationComplete:b.value,mode:"segment",...$});y.value=_;const z=I.value.length>0?` (+ ${I.value.length.toLocaleString("fa-IR")} کاربر از جدول)`:"";V.value=_.cappedAt?`گیرندگان این دستهها: ${_.totalRecipients.toLocaleString("fa-IR")} شماره${z} — دسته اول ${(_.firstBatchSize||_.cappedAt).toLocaleString("fa-IR")} نفر؛ باقیمانده پس از تأیید`:`گیرندگان این دستهها: ${_.totalRecipients.toLocaleString("fa-IR")} شماره${z}`}catch($){console.log($),h.error(((m=(l=$==null?void 0:$.response)==null?void 0:l.data)==null?void 0:m.error)||"خطا در پیشنمایش")}finally{j.value=!1}}async function le(){if(!v.value.trim()){h.warning("متن پیامک الزامی است");return}const f={...N.value,includeUserIds:I.value},r=ke(f);if(r){h.warning(r);return}const l=N.value.segments.length,m=I.value.length,$=m>0?`ارسال به ${l} دسته (OR) بهعلاوه ${m} کاربر انتخابشده؟`:`ارسال به ${l} دسته مخاطب (اتحاد / OR)؟`;return new Promise(_=>{ve.confirm({title:"تأیید ارسال پیامک",content:$,okText:"بله، ارسال کن",cancelText:"انصراف",okType:"danger",centered:!0,onOk:async()=>{var z,e;i.value=!0,S.value=null;try{const c=$e(f),g=await Re({message:v.value.trim(),appendAppName:L.value,registrationComplete:b.value,mode:"segment",...c});S.value=g,o("campaign-started",g.campaignId),h.success(g.hasMoreBatches?`کمپین #${g.campaignId}: دسته اول ${g.totalRecipients.toLocaleString("fa-IR")} نفر — پس از اتمام، ${(g.remainingRecipients||0).toLocaleString("fa-IR")} نفر باقیمانده با تأیید ارسال میشود`:`کمپین #${g.campaignId} با ${g.totalRecipients.toLocaleString("fa-IR")} گیرنده در پسزمینه ارسال میشود`)}catch(c){h.error(((e=(z=c==null?void 0:c.response)==null?void 0:z.data)==null?void 0:e.error)||"شروع کمپین ناموفق بود")}finally{i.value=!1,_()}},onCancel:()=>_()})})}return(f,r)=>{var _,z;const l=ze,m=xe,$=ye;return k(),T("div",null,[n("div",nt,[n("div",st,[n("div",null,[lt,a(M(x),{value:v.value,"onUpdate:value":r[0]||(r[0]=e=>v.value=e),placeholder:"متن پیامک را وارد کنید...",rows:6,maxlength:1e3,"show-count":""},null,8,["value"])]),n("div",it,[a(M(ge),{checked:b.value,"onUpdate:checked":r[1]||(r[1]=e=>b.value=e)},{default:s(()=>[d(" فقط کاربران با ثبتنام کامل (نام و نام خانوادگی) ")]),_:1},8,["checked"]),a(M(ge),{checked:L.value,"onUpdate:checked":r[2]||(r[2]=e=>L.value=e)},{default:s(()=>[d(" افزودن نام اپلیکیشن به انتهای پیام ")]),_:1},8,["checked"])]),n("div",ot,[a(l,{loading:O.value,onClick:te},{default:s(()=>[d(" پیشنمایش گیرندگان ")]),_:1},8,["loading"]),a(l,{onClick:r[3]||(r[3]=e=>A.value=!0)},{default:s(()=>[d(" ارسال تست ")]),_:1}),a(l,{type:"primary",loading:i.value,disabled:!v.value.trim(),onClick:ne},{default:s(()=>[d(" ارسال به انتخابشدهها ("+p(I.value.length)+") ",1)]),_:1},8,["loading","disabled"]),a(l,{type:"primary",ghost:"",loading:i.value,disabled:!v.value.trim(),onClick:W},{default:s(()=>[d(" ارسال به همه فیلترشدهها ")]),_:1},8,["loading","disabled"])]),a(je,{modelValue:N.value,"onUpdate:modelValue":r[4]||(r[4]=e=>N.value=e),"include-user-count":I.value.length,"preview-loading":j.value,sending:i.value,disabled:!v.value.trim(),"preview-text":V.value,onPreview:se,onSend:le},null,8,["modelValue","include-user-count","preview-loading","sending","disabled","preview-text"])]),n("div",rt,[ct,y.value?(k(),T("div",ut,[n("div",null,[d("تعداد گیرنده: "),n("strong",null,p(y.value.totalRecipients),1)]),n("div",null,[d("شماره یکتا: "),n("strong",null,p(y.value.uniquePhones),1)]),n("div",null,[d("پارت پیامک (هر نفر): "),n("strong",null,p(y.value.smsPartsPerRecipient),1)]),n("div",null,[d("تخمین کل پارت: "),n("strong",null,p(y.value.estimatedTotalParts),1)]),y.value.cappedAt?(k(),T("div",dt,[d(" مخاطبان بیشتر از "+p(y.value.cappedAt.toLocaleString("fa-IR"))+" نفر هستند. ابتدا "+p((y.value.firstBatchSize||y.value.cappedAt).toLocaleString("fa-IR"))+" نفر ارسال میشود؛ سپس با تأیید شما دسته بعدی ",1),y.value.remainingAfterFirstBatch?(k(),T("span",mt," ("+p(y.value.remainingAfterFirstBatch.toLocaleString("fa-IR"))+" باقیمانده) ",1)):q("",!0),d(" ارسال میشود. ")])):q("",!0)])):(k(),T("div",pt," برای مشاهده تعداد گیرندگان، پیشنمایش بگیرید. ")),(z=(_=y.value)==null?void 0:_.samples)!=null&&z.length?(k(),T("div",_t,[vt,n("ul",ft,[(k(!0),T(be,null,Fe(y.value.samples,e=>(k(),T("li",{key:e.id},p(e.first_name)+" "+p(e.last_name)+" — "+p(e.phone),1))),128))])])):q("",!0),S.value?(k(),T("div",gt,[ht,n("div",null,[d("کمپین: "),n("strong",null,"#"+p(S.value.campaignId),1)]),n("div",null,[d("گیرندگان: "),n("strong",null,p(S.value.totalRecipients),1)]),n("div",yt,p(S.value.message),1)])):q("",!0)])]),n("div",xt,[bt,a(m,ue(ee.value,{"row-selection":G.value,onRegister:M(R)}),null,16,["row-selection","onRegister"])]),a($,{visible:A.value,"onUpdate:visible":r[6]||(r[6]=e=>A.value=e),title:"ارسال پیامک تست",onOk:ae,onCancel:r[7]||(r[7]=e=>A.value=!1),"confirm-loading":K.value},{default:s(()=>[n("div",wt,[n("div",null,[kt,a(M(he),{value:B.value,"onUpdate:value":r[5]||(r[5]=e=>B.value=e),placeholder:"مثال: 09123456789"},null,8,["value"])]),$t])]),_:1},8,["visible","confirm-loading"])])}}}),Rt={pending:"در انتظار",sending:"در حال ارسال",completed:"تکمیل شده",failed:"ناموفق",awaiting_next_batch:"منتظر تأیید دسته بعدی"},St={selected:"انتخابشده",filtered:"فیلترشده",segment:"دسته مخاطب"},Ct=[{title:"ردیف",dataIndex:"id",key:"row_index",filterable:!1,customRender:t=>t.index+1},{title:"شناسه",dataIndex:"id",key:"id",filterable:!1},{title:"متن پیام",dataIndex:"message",key:"message",filterable:!1,customRender:t=>{const o=t.record.message||"";return o.length>60?`${o.slice(0,60)}...`:o}},{title:"گیرندگان",dataIndex:"total_recipients",key:"total_recipients",filterable:!1,customRender:t=>{const o=t.record,x=o.total_recipients||0,R=o.audience_total||x;return R>x?`${x.toLocaleString("fa-IR")} / ${R.toLocaleString("fa-IR")}`:x}},{title:"پیشرفت",dataIndex:"sent_count",key:"progress",filterable:!1,customRender:t=>{const o=t.record;if(!o.total_recipients)return"-";const x=(o.sent_count||0)+(o.failed_count||0),R=Math.round(x/o.total_recipients*100);return`${x}/${o.total_recipients} (${R}%)`}},{title:"ناموفق",dataIndex:"failed_count",key:"failed_count",filterable:!1},{title:"نوع ارسال",dataIndex:"send_mode",key:"send_mode",filterable:!1,customRender:t=>St[t.record.send_mode]||t.record.send_mode},{title:"وضعیت",dataIndex:"status",key:"status",filterable:!1,customRender:t=>Rt[t.record.status]||t.record.status},{title:"تاریخ",dataIndex:"created_at",key:"created_at",filterable:!1,customRender:t=>t.record.created_at?de(t.record.created_at):"-"},{title:"عملیات",dataIndex:"action",key:"action",slot:"action",filterable:!1,align:"center"}],Tt={pending:"در انتظار",sent:"ارسال شده",failed:"ناموفق"},Lt=[{title:"ردیف",dataIndex:"id",key:"row_index",filterable:!1,customRender:t=>t.index+1},{title:"نام",dataIndex:"first_name",key:"first_name",filterable:!1},{title:"نام خانوادگی",dataIndex:"last_name",key:"last_name",filterable:!1},{title:"شماره",dataIndex:"phone",key:"phone",filterable:!1},{title:"وضعیت",dataIndex:"status",key:"status",filterable:!1,customRender:t=>Tt[t.record.status]||t.record.status},{title:"زمان ارسال",dataIndex:"sent_at",key:"sent_at",filterable:!1,customRender:t=>t.record.sent_at?de(t.record.sent_at):"-"},{title:"خطا",dataIndex:"error_message",key:"error_message",filterable:!1,customRender:t=>t.record.error_message||"-"}],Pt={key:0,class:"mb-3 text-sm text-blue-600 flex items-center gap-2"},At=n("span",null,"یک یا چند کمپین در حال ارسال است — جدول هر ۵ ثانیه بهروز میشود.",-1),Bt={class:"gap-2 flex justify-center"},Dt=n("span",null,"جزئیات کمپین",-1),Ut=n("span",null,"ارسال دسته بعدی",-1),Mt=n("span",null,"ازسرگیری ارسال",-1),Ot={class:"flex justify-end gap-2 w-full flex-wrap"},zt={key:0},qt={key:0,class:"text-gray-500 mr-1"},Et={class:"text-green-600"},Ft={class:"text-red-600"},Nt={key:0,class:"text-gray-500 mr-2"},Vt={class:"whitespace-pre-wrap text-sm"},Kt={key:0,class:"mb-3 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800"},jt={key:1,class:"mb-3 rounded-md border border-blue-200 bg-blue-50 px-3 py-2 text-sm text-blue-800"},Ht={class:"flex flex-wrap gap-2 items-center mb-3"},Jt=n("span",{class:"text-sm text-gray-600"},"فیلتر وضعیت گیرندگان:",-1),Gt=fe({__name:"CampaignsPanel",setup(t,{expose:o}){const[x,R]=ce(),[F,v]=ce(),b=u(!1),L=u(!1),y=u(!1),O=u(!1),i=u(null),S=u(null),A=u(),B=u(""),K=u(!1);let I=null;const C={pending:"در انتظار",sending:"در حال ارسال",completed:"تکمیل شده",failed:"ناموفق",awaiting_next_batch:"منتظر تأیید دسته بعدی"},N={selected:"انتخابشده",filtered:"فیلترشده",segment:"دسته مخاطب"},j=u({columns:Ct,api:ee,defaultPageLimit:20,height:"55vh"}),V=_e(()=>{var c;if(!((c=i.value)!=null&&c.campaign))return 0;const e=i.value.campaign;return Math.max(e.total_recipients-e.sent_count-e.failed_count,0)}),G=_e(()=>{var c;const e=(c=i.value)==null?void 0:c.campaign;return e?!!e.can_continue_batch&&(e.remaining_recipients||0)>0:!1}),me=_e(()=>{var c;const e=(c=i.value)==null?void 0:c.campaign;return e?e.status==="sending"&&e.sent_count+e.failed_count===0&&V.value>0:!1});async function ee(e){const c=await Ze(e);return K.value=c.rows.some(g=>g.status==="sending"||g.status==="awaiting_next_batch"),c}const Q=u({columns:Lt,api:ne,defaultPageLimit:20,height:"40vh",showOptionHeader:!1});function te(e){return C[e]||e}function ae(e){return N[e]||e}function X(e){return e?de(e):"-"}async function ne(e){if(!S.value)return{rows:[],total:0,query:{...e,total:0}};const c=await Se(S.value,{page:e.page,limit:e.limit,status:A.value,search:B.value||e.search||void 0});i.value=c;const g=e.page||1,D=e.limit||20,E=(g-1)*D;return{rows:c.recipients.rows.map((P,ie)=>({...P,index:E+ie})),total:c.recipients.total,query:{...e,total:c.recipients.total,page:g,limit:D}}}async function W(e){L.value=!0;try{S.value=e,i.value=await Se(e,{page:1,limit:20,status:A.value,search:B.value||void 0}),await v()}finally{L.value=!1}}function se(e){A.value=void 0,B.value="",b.value=!0,W(e.id)}async function le(e){A.value=void 0,B.value="",b.value=!0,await W(e.id),G.value&&m()}function f(){b.value=!1,i.value=null,S.value=null}function r(){v()}function l(){R()}function m(){var g;const e=(g=i.value)==null?void 0:g.campaign;if(!(e!=null&&e.id)||!G.value)return;const c=e.next_batch_size||Math.min(1e4,e.remaining_recipients||0);ve.confirm({title:"تأیید ارسال دسته بعدی",content:`آیا از ارسال دسته بعدی (${c.toLocaleString("fa-IR")} نفر از ${(e.remaining_recipients||0).toLocaleString("fa-IR")} باقیمانده) مطمئن هستید؟`,okText:"بله، ارسال کن",cancelText:"انصراف",okType:"danger",centered:!0,onOk:async()=>{var D,E;y.value=!0;try{const P=await Xe(e.id);h.success(P.message),await W(e.id),R()}catch(P){throw h.error(((E=(D=P==null?void 0:P.response)==null?void 0:D.data)==null?void 0:E.error)||"ارسال دسته بعدی ناموفق بود"),P}finally{y.value=!1}}})}function $(e){!(e!=null&&e.id)||e.status!=="sending"||ve.confirm({title:"ازسرگیری ارسال کمپین",content:`کمپین #${e.id} دوباره در صف ارسال قرار میگیرد. ادامه میدهید؟`,okText:"بله، ازسر بگیر",cancelText:"انصراف",centered:!0,onOk:async()=>{var c,g;O.value=!0;try{const D=await Ye(e.id);h.success(D.message),b.value&&S.value===e.id&&await W(e.id),R()}catch(D){throw h.error(((g=(c=D==null?void 0:D.response)==null?void 0:c.data)==null?void 0:g.error)||"ازسرگیری کمپین ناموفق بود"),D}finally{O.value=!1}}})}function _(){I||(I=setInterval(()=>{var e,c;R(),b.value&&S.value&&(((e=i.value)==null?void 0:e.campaign.status)==="sending"||((c=i.value)==null?void 0:c.campaign.status)==="awaiting_next_batch")&&v()},5e3))}function z(){I&&(clearInterval(I),I=null)}return Ne(()=>{_()}),Ve(()=>{z()}),o({reload:l}),(e,c)=>{const g=Pe,D=xe,E=Ae,P=Be,ie=De,oe=Ue,w=Me,H=Le,re=ye;return k(),T("div",null,[K.value?(k(),T("div",Pt,[a(g,{size:"small"}),At])):q("",!0),a(D,ue(j.value,{onRegister:M(x)}),{action:s(({record:U})=>[n("div",Bt,[a(M(Z),{class:"cursor-pointer"},{title:s(()=>[Dt]),default:s(()=>[a(Y,{icon:"vuesax-linear:eye",color:"#1D4ED8",onClick:we=>se(U)},null,8,["onClick"])]),_:2},1024),U.can_continue_batch?(k(),pe(M(Z),{key:0,class:"cursor-pointer"},{title:s(()=>[Ut]),default:s(()=>[a(Y,{icon:"vuesax-linear:send-2",color:"#D97706",onClick:we=>le(U)},null,8,["onClick"])]),_:2},1024)):q("",!0),U.status==="sending"&&U.sent_count+U.failed_count===0?(k(),pe(M(Z),{key:1,class:"cursor-pointer"},{title:s(()=>[Mt]),default:s(()=>[a(Y,{icon:"vuesax-linear:refresh",color:"#059669",onClick:we=>$(U)},null,8,["onClick"])]),_:2},1024)):q("",!0)])]),_:1},16,["onRegister"]),a(re,{visible:b.value,"onUpdate:visible":c[3]||(c[3]=U=>b.value=U),title:"جزئیات کمپین پیامکی","custom-footer":"",width:"90%",onClose:f},{footer:s(()=>[n("div",Ot,[G.value?(k(),pe(E,{key:0,type:"primary",loading:y.value,onClick:m},{default:s(()=>{var U;return[d(" ارسال دسته بعدی "),(U=i.value)!=null&&U.campaign.next_batch_size?(k(),T("span",zt," ("+p(i.value.campaign.next_batch_size.toLocaleString("fa-IR"))+" نفر) ",1)):q("",!0)]}),_:1},8,["loading"])):q("",!0),me.value?(k(),pe(E,{key:1,type:"primary",ghost:"",loading:O.value,onClick:c[0]||(c[0]=U=>$(i.value.campaign))},{default:s(()=>[d(" ازسرگیری ارسال ")]),_:1},8,["loading"])):q("",!0),a(E,{onClick:f},{default:s(()=>[d("بستن")]),_:1})])]),default:s(()=>[a(g,{spinning:L.value},{default:s(()=>[i.value?(k(),T(be,{key:0},[a(ie,{bordered:"",column:2,size:"small",class:"mb-4"},{default:s(()=>[a(P,{label:"شناسه کمپین"},{default:s(()=>[d("#"+p(i.value.campaign.id),1)]),_:1}),a(P,{label:"وضعیت"},{default:s(()=>[d(p(te(i.value.campaign.status)),1)]),_:1}),a(P,{label:"تعداد گیرندگان"},{default:s(()=>[n("span",null,p(i.value.campaign.total_recipients.toLocaleString("fa-IR")),1),(i.value.campaign.audience_total||0)>i.value.campaign.total_recipients?(k(),T("span",qt," از "+p(i.value.campaign.audience_total.toLocaleString("fa-IR"))+" مخاطب ",1)):q("",!0)]),_:1}),a(P,{label:"موفق / ناموفق"},{default:s(()=>[n("span",Et,p(i.value.campaign.sent_count),1),d(" / "),n("span",Ft,p(i.value.campaign.failed_count),1),i.value.campaign.status==="sending"?(k(),T("span",Nt," ("+p(V.value)+" در انتظار) ",1)):q("",!0)]),_:1}),a(P,{label:"نوع ارسال"},{default:s(()=>[d(p(ae(i.value.campaign.send_mode)),1)]),_:1}),a(P,{label:"تاریخ ایجاد"},{default:s(()=>[d(p(X(i.value.campaign.created_at)),1)]),_:1}),a(P,{label:"ایجادکننده",span:2},{default:s(()=>[d(p(i.value.campaign.created_by_admin_name||"-"),1)]),_:1}),a(P,{label:"متن پیام",span:2},{default:s(()=>[n("div",Vt,p(i.value.campaign.message),1)]),_:1})]),_:1}),G.value?(k(),T("div",Kt,[d(" مخاطب این کمپین دوباره محاسبه شد و شمارههای ارسالشده کم شدند. "),n("strong",null,p((i.value.campaign.remaining_recipients||0).toLocaleString("fa-IR")),1),d(" گیرنده باقی ماندهاند. با تأیید شما حداکثر "+p((i.value.campaign.batch_limit||1e4).toLocaleString("fa-IR"))+" نفر بعدی ارسال میشود. ",1)])):i.value.campaign.needs_remaining_probe?(k(),T("div",jt," این کمپین احتمالاً به سقف ۱۰٬۰۰۰ رسیده بود. در حال بررسی باقیمانده مخاطب… ")):q("",!0),n("div",Ht,[Jt,a(w,{value:A.value,"onUpdate:value":c[1]||(c[1]=U=>A.value=U),"allow-clear":"",placeholder:"همه",style:{width:"160px"},onChange:r},{default:s(()=>[a(oe,{value:"sent"},{default:s(()=>[d("ارسال شده")]),_:1}),a(oe,{value:"failed"},{default:s(()=>[d("ناموفق")]),_:1}),a(oe,{value:"pending"},{default:s(()=>[d("در انتظار")]),_:1})]),_:1},8,["value"]),a(H,{value:B.value,"onUpdate:value":c[2]||(c[2]=U=>B.value=U),placeholder:"جستجو نام یا شماره",style:{width:"220px"},onSearch:r},null,8,["value"])]),a(D,ue(Q.value,{onRegister:M(F)}),null,16,["onRegister"])],64)):q("",!0)]),_:1},8,["spinning"])]),_:1},8,["visible"])])}}}),Qt=[{title:"ردیف",dataIndex:"id",key:"row_index",filterable:!1,customRender:t=>t.index+1},{title:"نام",dataIndex:"name",key:"name",filterable:!1},{title:"کد",dataIndex:"code",key:"code",filterable:!1},{title:"متن پیام",dataIndex:"message",key:"message",filterable:!1,customRender:t=>{const o=t.record.message||"";return o.length>50?`${o.slice(0,50)}...`:o}},{title:"فعال",dataIndex:"is_active",key:"is_active",slot:"is_active",filterable:!1,align:"center"},{title:"ارسالشده",dataIndex:"sent_count",key:"sent_count",filterable:!1},{title:"ناموفق",dataIndex:"failed_count",key:"failed_count",filterable:!1},{title:"لغو/رد",dataIndex:"cancelled_count",key:"cancelled_count",filterable:!1},{title:"عملیات",dataIndex:"action",key:"action",slot:"action",filterable:!1,align:"center"}],Wt={pending:"در انتظار",sent:"ارسال شده",failed:"ناموفق",cancelled:"لغو شده",skipped:"رد شده"},Xt=[{title:"ردیف",dataIndex:"id",key:"row_index",filterable:!1,customRender:t=>t.index+1},{title:"شماره",dataIndex:"phone",key:"phone",filterable:!1},{title:"وضعیت",dataIndex:"status",key:"status",filterable:!1,customRender:t=>Wt[t.record.status]||t.record.status},{title:"تاریخ برنامهریزی",dataIndex:"scheduled_for",key:"scheduled_for",filterable:!1},{title:"زمان ارسال",dataIndex:"sent_at",key:"sent_at",filterable:!1,customRender:t=>t.record.sent_at?de(t.record.sent_at):"-"},{title:"توضیح",dataIndex:"error_message",key:"error_message",filterable:!1,customRender:t=>t.record.error_message||"-"}],Yt=n("p",{class:"text-sm text-gray-500 mb-4"}," اتوماسیونهای پیامکی کدوبلو. متن و فعال بودن را میتوانید تغییر دهید؛ شرط ارسال در سیستم ثابت است. ",-1),Zt={class:"gap-2 flex justify-center"},ea=n("span",null,"ویرایش",-1),ta=n("span",null,"آمار ارسال",-1),aa=n("span",null,"ارسال تست",-1),na={class:"space-y-4"},sa=n("div",{class:"mb-1 text-sm text-gray-600"},"نام",-1),la={class:"font-medium"},ia=n("div",{class:"mb-1 text-sm text-gray-600"},"شرط ارسال",-1),oa={class:"text-sm text-gray-700 whitespace-pre-wrap"},ra=n("div",{class:"mb-1 text-sm text-gray-600"},"متن پیامک *",-1),ca={class:"space-y-3"},ua={class:"text-sm text-gray-600"},da={class:"text-green-600"},ma={class:"text-red-600"},pa={class:"text-gray-500"},_a=n("span",{class:"text-xs text-gray-400 mr-2"},"(موفق / ناموفق / لغو)",-1),va={class:"whitespace-pre-wrap text-sm"},fa={class:"flex flex-wrap gap-2 items-center mb-3"},ga=n("span",{class:"text-sm text-gray-600"},"فیلتر وضعیت:",-1),ha=fe({__name:"AutomationsPanel",setup(t,{expose:o}){const{TextArea:x}=he,[R,F]=ce(),[v,b]=ce(),L=u({columns:Qt,api:et,defaultPageLimit:20,height:"55vh",showOptionHeader:!1}),y=u(!1),O=u(null),i=Ke({message:"",is_active:!0}),S=u(!1),A=u(null),B=u(""),K=u(!1),I=u(!1),C=u(null),N=u(null),j=u(),V=u(""),G=u({columns:Xt,api:W,defaultPageLimit:20,height:"40vh",showOptionHeader:!1});async function me(l,m){if(l.is_active===m)return;const $=l.is_active;l.is_active=m;try{await Ce(l.id,{is_active:m}),h.success(m?"اتوماسیون فعال شد":"اتوماسیون غیرفعال شد")}catch{l.is_active=$,h.error("تغییر وضعیت ناموفق بود")}}function ee(l){O.value=l,i.message=l.message||"",i.is_active=l.is_active!==!1,y.value=!0}function Q(){y.value=!1,O.value=null}async function te(){if(O.value){if(!i.message.trim()){h.error("متن پیامک الزامی است");return}try{await Ce(O.value.id,{message:i.message.trim(),is_active:i.is_active}),h.success("اتوماسیون ذخیره شد"),Q(),await F()}catch{h.error("ذخیره ناموفق بود")}}}function ae(l){A.value=l,B.value="",S.value=!0}function X(){S.value=!1,A.value=null,B.value=""}async function ne(){if(!A.value)return;const l=B.value.trim();if(!l){h.error("شماره موبایل الزامی است");return}try{await tt(A.value.id,l),h.success("پیامک تست ارسال شد"),X()}catch{h.error("ارسال تست ناموفق بود")}}async function W(l){if(!N.value)return{rows:[],total:0,query:{...l,total:0}};const m=await Te(N.value,{page:l.page,limit:l.limit,status:j.value,search:V.value||l.search||void 0});C.value=m;const $=l.page||1,_=l.limit||20,z=($-1)*_;return{rows:m.sends.rows.map((e,c)=>({...e,index:z+c})),total:m.sends.total,query:{...l,total:m.sends.total,page:$,limit:_}}}async function se(l){I.value=!0;try{N.value=l,C.value=await Te(l,{page:1,limit:20,status:j.value,search:V.value||void 0}),await b()}finally{I.value=!1}}function le(l){j.value=void 0,V.value="",K.value=!0,se(l.id)}function f(){K.value=!1,C.value=null,N.value=null}function r(){b()}return o({reload:F}),(l,m)=>{const $=He,_=xe,z=ye,e=Je,c=Ae,g=Be,D=De,E=Ue,P=Me,ie=Le,oe=Pe;return k(),T("div",null,[Yt,a(_,ue(L.value,{onRegister:M(R)}),{is_active:s(({record:w})=>[a($,{checked:w.is_active,onChange:H=>me(w,H)},null,8,["checked","onChange"])]),action:s(({record:w})=>[n("div",Zt,[a(M(Z),{class:"cursor-pointer"},{title:s(()=>[ea]),default:s(()=>[a(Y,{icon:"vuesax-linear:edit",color:"#1D4ED8",onClick:H=>ee(w)},null,8,["onClick"])]),_:2},1024),a(M(Z),{class:"cursor-pointer"},{title:s(()=>[ta]),default:s(()=>[a(Y,{icon:"vuesax-linear:eye",color:"#059669",onClick:H=>le(w)},null,8,["onClick"])]),_:2},1024),a(M(Z),{class:"cursor-pointer"},{title:s(()=>[aa]),default:s(()=>[a(Y,{icon:"vuesax-linear:sms",color:"#7C3AED",onClick:H=>ae(w)},null,8,["onClick"])]),_:2},1024)])]),_:1},16,["onRegister"]),a(z,{visible:y.value,"onUpdate:visible":m[2]||(m[2]=w=>y.value=w),title:"ویرایش اتوماسیون",width:"640px",onOk:te,onCancel:Q},{default:s(()=>{var w,H;return[n("div",na,[n("div",null,[sa,n("div",la,p((w=O.value)==null?void 0:w.name),1)]),n("div",null,[ia,n("div",oa,p((H=O.value)==null?void 0:H.trigger_summary),1)]),n("div",null,[ra,a(M(x),{value:i.message,"onUpdate:value":m[0]||(m[0]=re=>i.message=re),rows:5,placeholder:"متن پیامک"},null,8,["value"])]),n("div",null,[a(M(ge),{checked:i.is_active,"onUpdate:checked":m[1]||(m[1]=re=>i.is_active=re)},{default:s(()=>[d("فعال")]),_:1},8,["checked"])])])]}),_:1},8,["visible"]),a(z,{visible:S.value,"onUpdate:visible":m[4]||(m[4]=w=>S.value=w),title:"ارسال تست اتوماسیون",width:"480px",onOk:ne,onCancel:X},{default:s(()=>{var w;return[n("div",ca,[n("div",ua," متن فعلی «"+p((w=A.value)==null?void 0:w.name)+"» به شماره زیر ارسال میشود. ",1),a(e,{value:B.value,"onUpdate:value":m[3]||(m[3]=H=>B.value=H),placeholder:"09xxxxxxxxx"},null,8,["value"])])]}),_:1},8,["visible"]),a(z,{visible:K.value,"onUpdate:visible":m[7]||(m[7]=w=>K.value=w),title:"آمار ارسال اتوماسیون","custom-footer":"",width:"90%",onClose:f},{footer:s(()=>[a(c,{onClick:f},{default:s(()=>[d("بستن")]),_:1})]),default:s(()=>[a(oe,{spinning:I.value},{default:s(()=>[C.value?(k(),T(be,{key:0},[a(D,{bordered:"",column:2,size:"small",class:"mb-4"},{default:s(()=>[a(g,{label:"نام"},{default:s(()=>[d(p(C.value.automation.name),1)]),_:1}),a(g,{label:"کد"},{default:s(()=>[d(p(C.value.automation.code),1)]),_:1}),a(g,{label:"وضعیت"},{default:s(()=>[d(p(C.value.automation.is_active?"فعال":"غیرفعال"),1)]),_:1}),a(g,{label:"آمار کلی"},{default:s(()=>[n("span",da,p(C.value.automation.sent_count),1),d(" / "),n("span",ma,p(C.value.automation.failed_count),1),d(" / "),n("span",pa,p(C.value.automation.cancelled_count),1),_a]),_:1}),a(g,{label:"شرط",span:2},{default:s(()=>[d(p(C.value.automation.trigger_summary),1)]),_:1}),a(g,{label:"متن پیام",span:2},{default:s(()=>[n("div",va,p(C.value.automation.message),1)]),_:1})]),_:1}),n("div",fa,[ga,a(P,{value:j.value,"onUpdate:value":m[5]||(m[5]=w=>j.value=w),"allow-clear":"",placeholder:"همه",style:{width:"160px"},onChange:r},{default:s(()=>[a(E,{value:"sent"},{default:s(()=>[d("ارسال شده")]),_:1}),a(E,{value:"failed"},{default:s(()=>[d("ناموفق")]),_:1}),a(E,{value:"pending"},{default:s(()=>[d("در انتظار")]),_:1}),a(E,{value:"skipped"},{default:s(()=>[d("رد شده")]),_:1}),a(E,{value:"cancelled"},{default:s(()=>[d("لغو شده")]),_:1})]),_:1},8,["value"]),a(ie,{value:V.value,"onUpdate:value":m[6]||(m[6]=w=>V.value=w),placeholder:"جستجو شماره",style:{width:"220px"},onSearch:r},null,8,["value"])]),a(_,ue(G.value,{onRegister:M(v)}),null,16,["onRegister"])],64)):q("",!0)]),_:1},8,["spinning"])]),_:1},8,["visible"])])}}}),ya=n("div",{class:"flex justify-between items-center mb-4"},[n("h2",null,"پنل پیامکی")],-1),xn=fe({__name:"index",setup(t){const o=u("send"),x=u(null),R=u(null);function F(){var v;o.value="campaigns",(v=x.value)==null||v.reload()}return(v,b)=>{const L=Ge,y=Qe,O=Oe;return k(),T("div",null,[a(O,null,{default:s(()=>[ya,a(y,{activeKey:o.value,"onUpdate:activeKey":b[0]||(b[0]=i=>o.value=i)},{default:s(()=>[a(L,{key:"send",tab:"ارسال پیامک"},{default:s(()=>[a(It,{onCampaignStarted:F})]),_:1}),a(L,{key:"campaigns",tab:"کمپینهای ارسالی"},{default:s(()=>[a(Gt,{ref_key:"campaignsPanelRef",ref:x},null,512)]),_:1}),a(L,{key:"automations",tab:"اتوماسیونها"},{default:s(()=>[a(ha,{ref_key:"automationsPanelRef",ref:R},null,512)]),_:1})]),_:1},8,["activeKey"])]),_:1})])}}});export{xn as default};
|