تخطي إلى المحتوى

الإجراءات (Actions)

هذه الصفحة مترجمة من الإنجليزية. اقرأ الصفحة الإنجليزية

الإجراء (action) هو كود على الخادم يمكن لشاشة أو شبكة أو نموذج أو أمر أو واجهة JSON API أو وكيل ذكاء اصطناعي أن يستدعيه. يعلن #[action] من يحق له الاستدعاء، ويتحقق الإطار من ذلك قبل تشغيل الكود.

إعلان إجراء

#[action(permission = "stock.product.read")]
pub async fn search_products(q: DataQuery, store: ProductStore) -> Result<Page<Product>> {
    Ok(q.apply(store.all()?))
}

#[action(permission = "stock.product.write", audit)]
pub async fn save_product(product: Valid<Product>, store: ProductStore) -> Result<Product> {
    store.save(product.into_inner())
}
  • الوسيط الأول هو المدخل. يأتي من العميل، ولذلك يقرؤه الإطار على أنه JSON غير موثوق.
  • كل وسيط آخر يُحقن: Ctx أو Service مسجلة.
  • نوع الإرجاع هو Result<T>.

الوصول

كل إجراء يعلن واحدًا فقط مما يلي:

الخيارالمعنى
permission = "feature.resource.verb"تحتاج الهوية إلى هذه الصلاحية
publicأي شخص، بمن فيهم من لم يسجلوا الدخول

الإجراء بلا وصول لا يُترجم (لا يُصرَّف). أسماء الصلاحيات بأحرف صغيرة ومفصولة بنقاط، مثل sales.order.write.

خيارات أخرى:

الخيارالمعنى
auditيكتب سجل تدقيق عن كل استدعاء
reauthيجب أن يكون المستخدم قد سجل الدخول حديثًا (App::reauth_within)

الأخطاء

الخطأالحالةالاستخدام
Error::NotFound404السجل غير موجود أو لا يحق للمستخدم أن يعرف بوجوده
Error::Forbidden403الوصول مرفوض
Error::Denied(t!("..."))403مرفوض مع سبب يستطيع المستخدم قراءته
Error::Conflict409تغير إصدار الصف منذ تحميل النموذج
Error::Validation(errors)422أخطاء الحقول، تظهر بجوار الحقول
Error::Internal("detail")500تذهب التفاصيل إلى سجل الخادم فقط

خطأ في حقل من الكود:

let mut errors = ValidationErrors::default();
errors.add(Product::code, t!("stock.code_taken", code = product.code));
return Err(errors.into());

القوائم

تأخذ القوائم DataQuery وتعيد Page<M>. إجراء القائمة لا يعيد كل الصفوف أبدًا؛ فالشبكة تطلب صفحات، ويضع الخادم حدًا أعلى لحجم الصفحة مهما أرسل العميل.

السياق

Ctx هو الطلب: ctx.identity() وctx.locale() وctx.time_zone() وctx.now() وctx.today() وctx.tenant() وctx.license() وctx.config() وctx.theme() وctx.t(&text). استخدم ctx.now() وctx.today() بدل ساعة النظام، حتى تتمكن الاختبارات من تثبيت الوقت بـ App::fixed_now.

أين تُستخدم الإجراءات

  • DataGrid::of(action) يحمّل الصفوف؛ و.edit_with(action) و.row_action(...) و.bulk_action(...) تغيّرها.
  • Form::submit(label, action) يحفظ نموذجًا.
  • ActionButton::new(label, action, input) يشغّل إجراءً من زر.
  • Command::action(...) يشغّل إجراءً من لوحة الأوامر أو من اختصار.
  • Feature::api(action) ينشره بصيغة JSON (راجع API وOpenAPI).
  • Feature::search(action) يضيف بحثًا على الخادم إلى لوحة الأوامر.

كل مسار يجري الفحوص نفسها: CSRF لاستدعاءات المتصفح، ثم الحراس (guards) الخاصة بالميزة، ثم وصول الإجراء، ثم المعترضات (interceptors).