<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ylx.order.mapper.AdminOrderMapper">

    <select id="selectAdminOrderPage" resultType="com.ylx.order.domain.vo.AdminOrderPageVO">
        SELECT
            o.id AS id,
            o.order_no AS orderNo,
            o.create_time AS orderTime,
            COALESCE(p.title, o.project_name) AS projectName,
            o.project_duration AS projectDuration,
            o.appointment_start_time AS appointmentStartTime,
            COALESCE(p.price, o.base_price) AS unitPrice,
            1 AS quantity,
            p.unit_type AS unitType,
            o.final_amount AS orderAmount,
            o.traffic_fee AS trafficFee,
            o.payment_method AS paymentMethod,
            u.c_nick_name AS userNickName,
            o.contact_person_name AS contactPersonName,
            o.contact_phone_number AS contactPhoneNumber,
            o.contact_address_info AS contactAddressInfo,
            o.status AS status,
            o.exec_status AS execStatus,
            COALESCE(mt.te_nick_name, o.merchant_nick_name) AS merchantNickName,
            mt.te_phone AS merchantPhone,
            p.category_id AS categoryId,
            sc.name AS categoryName,
            o.merchant_latitude as merchantLatitude,
            o.merchant_longitude as merchantLongitude,
            u.sex as sex,
            o.start_time as startTime
        FROM t_order o
        LEFT JOIN t_wx_user u ON u.id = CAST(o.user_id AS CHAR) AND u.is_delete = 0
        LEFT JOIN ma_technician mt ON mt.id = o.merchant_id AND mt.is_delete = 0
        LEFT JOIN project p ON p.id = o.project_id AND p.is_delete = 0
        LEFT JOIN service_category sc ON sc.id = p.category_id AND sc.is_delete = 0
        <where>
            o.is_delete = 0
            <if test="dto.orderNo != null and dto.orderNo != ''">
                AND o.order_no LIKE CONCAT('%', #{dto.orderNo}, '%')
            </if>
            <if test="dto.queryStartTime != null">
                AND o.create_time &gt;= #{dto.queryStartTime}
            </if>
            <if test="dto.queryEndTime != null">
                AND o.create_time &lt;= #{dto.queryEndTime}
            </if>
            <if test="dto.userKeyword != null and dto.userKeyword != ''">
                <choose>
                    <when test="dto.userSearchType == 'nickName'">
                        AND u.c_nick_name LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </when>
                    <when test="dto.userSearchType == 'name'">
                        AND o.contact_person_name LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </when>
                    <otherwise>
                        AND u.c_phone LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </otherwise>
                </choose>
            </if>
            <if test="dto.categoryId != null">
                AND p.category_id = #{dto.categoryId}
            </if>
            <if test="dto.projectName != null and dto.projectName != ''">
                AND o.project_name LIKE CONCAT('%', #{dto.projectName}, '%')
            </if>
            <if test="dto.merchantKeyword != null and dto.merchantKeyword != ''">
                <choose>
                    <when test="dto.merchantSearchType == 'phone'">
                        AND mt.te_phone LIKE CONCAT('%', #{dto.merchantKeyword}, '%')
                    </when>
                    <otherwise>
                        AND o.merchant_nick_name LIKE CONCAT('%', #{dto.merchantKeyword}, '%')
                    </otherwise>
                </choose>
            </if>
            <if test="dto.paymentMethod != null">
                AND o.payment_method = #{dto.paymentMethod}
            </if>
            <choose>
                <when test="dto.abnormalOrder != null and dto.abnormalOrder">
                    AND o.status IN (7, 8, 9)
                </when>
                <when test="dto.status != null">
                    AND o.status = #{dto.status}
                </when>
            </choose>
            <if test="dto.merchantType != null">
                AND o.merchant_type = #{dto.merchantType}
            </if>
        </where>
        ORDER BY o.create_time DESC
    </select>

    <!-- 查询回收站订单列表 -->
    <select id="selectAdminOrderRecyclePage" resultType="com.ylx.order.domain.vo.AdminOrderPageVO">
        SELECT
            o.id AS id,
            o.order_no AS orderNo,
            o.create_time AS orderTime,
            COALESCE(p.title, o.project_name) AS projectName,
            o.project_duration AS projectDuration,
            o.appointment_start_time AS appointmentStartTime,
            COALESCE(p.price, o.base_price) AS unitPrice,
            1 AS quantity,
            p.unit_type AS unitType,
            o.final_amount AS orderAmount,
            o.traffic_fee AS trafficFee,
            o.payment_method AS paymentMethod,
            u.c_nick_name AS userNickName,
            o.contact_person_name AS contactPersonName,
            o.contact_phone_number AS contactPhoneNumber,
            o.contact_address_info AS contactAddressInfo,
            o.status AS status,
            o.exec_status AS execStatus,
            COALESCE(mt.te_nick_name, o.merchant_nick_name) AS merchantNickName,
            mt.te_phone AS merchantPhone,
            p.category_id AS categoryId,
            sc.name AS categoryName
        FROM t_order o
        LEFT JOIN t_wx_user u ON u.id = CAST(o.user_id AS CHAR) AND u.is_delete = 0
        LEFT JOIN ma_technician mt ON mt.id = o.merchant_id AND mt.is_delete = 0
        LEFT JOIN project p ON p.id = o.project_id AND p.is_delete = 0
        LEFT JOIN service_category sc ON sc.id = p.category_id AND sc.is_delete = 0
        <where>
            o.is_delete = 1
            <if test="dto.orderNo != null and dto.orderNo != ''">
                AND o.order_no LIKE CONCAT('%', #{dto.orderNo}, '%')
            </if>
            <if test="dto.queryStartTime != null">
                AND o.create_time &gt;= #{dto.queryStartTime}
            </if>
            <if test="dto.queryEndTime != null">
                AND o.create_time &lt;= #{dto.queryEndTime}
            </if>
            <if test="dto.userKeyword != null and dto.userKeyword != ''">
                <choose>
                    <when test="dto.userSearchType == 'nickName'">
                        AND u.c_nick_name LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </when>
                    <when test="dto.userSearchType == 'name'">
                        AND o.contact_person_name LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </when>
                    <otherwise>
                        AND u.c_phone LIKE CONCAT('%', #{dto.userKeyword}, '%')
                    </otherwise>
                </choose>
            </if>
            <if test="dto.categoryId != null">
                AND p.category_id = #{dto.categoryId}
            </if>
            <if test="dto.projectName != null and dto.projectName != ''">
                AND o.project_name LIKE CONCAT('%', #{dto.projectName}, '%')
            </if>
            <if test="dto.merchantKeyword != null and dto.merchantKeyword != ''">
                <choose>
                    <when test="dto.merchantSearchType == 'phone'">
                        AND mt.te_phone LIKE CONCAT('%', #{dto.merchantKeyword}, '%')
                    </when>
                    <otherwise>
                        AND o.merchant_nick_name LIKE CONCAT('%', #{dto.merchantKeyword}, '%')
                    </otherwise>
                </choose>
            </if>
            <if test="dto.paymentMethod != null">
                AND o.payment_method = #{dto.paymentMethod}
            </if>
            <choose>
                <when test="dto.abnormalOrder != null and dto.abnormalOrder">
                    AND o.status IN (7, 8, 9)
                </when>
                <when test="dto.status != null">
                    AND o.status = #{dto.status}
                </when>
            </choose>
            <if test="dto.merchantType != null">
                AND o.merchant_type = #{dto.merchantType}
            </if>
        </where>
        ORDER BY o.create_time DESC
    </select>

    <!-- 查询服务分类选项 -->
    <select id="selectServiceCategoryOptions" resultType="com.ylx.order.domain.vo.AdminOrderServiceCategoryVO">
        SELECT
            id,
            service_tag AS serviceTag,
            name
        FROM service_category
        WHERE is_delete = 0
        ORDER BY sort ASC, id ASC
    </select>

    <!-- 根据订单ID逻辑删除服务订单 -->
    <update id="logicDeleteById">
        UPDATE t_order
        SET is_delete = 1,
            deleted_time = NOW(),
            update_time = NOW()
        WHERE id = #{id}
          AND is_delete = 0
    </update>

    <!-- 根据订单ID恢复回收站服务订单 -->
    <update id="restoreById">
        UPDATE t_order
        SET is_delete = 0,
            deleted_time = NULL,
            update_time = NOW()
        WHERE id = #{id}
          AND is_delete = 1
    </update>

    <select id="selectRefundApplicationOrderById" resultType="com.ylx.massage.domain.CancelOrderApplication">
        SELECT
            o.order_no AS orderNo,
            COALESCE(u.c_openid, CAST(o.user_id AS CHAR)) AS openId,
            COALESCE(o.contact_person_name, u.c_nick_name) AS userName,
            COALESCE(o.contact_phone_number, u.c_phone) AS userPhone,
            CAST(o.merchant_id AS CHAR) AS techId,
            mt.te_name AS techName,
            COALESCE(mt.te_nick_name, o.merchant_nick_name) AS techNickName,
            mt.te_phone AS techPhone,
            COALESCE(p.title, o.project_name) AS projectName,
            CAST(o.project_duration AS CHAR) AS projectDuration,
            CAST(o.project_duration AS CHAR) AS serviceDuration,
            COALESCE(o.final_amount, 0) AS orderAmount,
            COALESCE(o.final_amount, 0) AS refundAmount,
            o.status AS orderStatus
        FROM t_order o
        LEFT JOIN t_wx_user u ON u.id = CAST(o.user_id AS CHAR) AND u.is_delete = 0
        LEFT JOIN ma_technician mt ON mt.id = o.merchant_id AND mt.is_delete = 0
        LEFT JOIN project p ON p.id = o.project_id AND p.is_delete = 0
        WHERE o.id = #{id}
          AND o.is_delete = 0
        LIMIT 1
    </select>

    <select id="countPendingRefundApplicationByOrderNo" resultType="java.lang.Integer">
        SELECT COUNT(1)
        FROM t_cancel_order_application
        WHERE order_no = #{orderNo}
          AND audit_status = 0
          AND is_delete = 0
    </select>

    <insert id="insertRefundApplication">
        INSERT INTO t_cancel_order_application (
            id,
            order_no,
            open_id,
            user_name,
            user_phone,
            tech_id,
            tech_name,
            tech_nick_name,
            tech_phone,
            project_name,
            project_duration,
            service_duration,
            order_amount,
            refund_amount,
            order_status,
            audit_status,
            application_time,
            cancel_order_reason,
            create_time,
            update_time,
            is_delete
        ) VALUES (
            #{application.id},
            #{application.orderNo},
            #{application.openId},
            #{application.userName},
            #{application.userPhone},
            #{application.techId},
            #{application.techName},
            #{application.techNickName},
            #{application.techPhone},
            #{application.projectName},
            #{application.projectDuration},
            #{application.serviceDuration},
            #{application.orderAmount},
            #{application.refundAmount},
            #{application.orderStatus},
            #{application.auditStatus},
            #{application.applicationTime},
            #{application.cancelOrderReason},
            #{application.createTime},
            #{application.updateTime},
            #{application.isDelete}
        )
    </insert>

    <!-- 通过订单ID查询订单详情 -->
    <select id="selectOrderDetailInfoById" resultType="com.ylx.order.domain.vo.AdminOrderDetailVO$OrderInfoVO">
        SELECT
            o.id,
            o.order_no AS orderNo,
            o.status,
            u.c_nick_name AS userNickName,
            o.contact_person_name AS contactPersonName,
            o.contact_phone_number AS contactPhoneNumber,
            o.contact_address_info AS contactAddressInfo,
            COALESCE(mt.te_nick_name, o.merchant_nick_name) AS merchantNickName,
            mt.te_phone AS merchantPhone,
            DATE_FORMAT(o.appointment_start_time, '%Y-%m-%d %H:%i:%s') AS appointmentStartTime,
            DATE_FORMAT(o.start_time, '%Y-%m-%d %H:%i:%s') AS startTime,
            DATE_FORMAT(o.completed_time, '%Y-%m-%d %H:%i:%s') AS completedTime,
            DATE_FORMAT(o.create_time, '%Y-%m-%d %H:%i:%s') AS createTime,
            DATE_FORMAT(o.paid_time, '%Y-%m-%d %H:%i:%s') AS paidTime,
            o.payment_method AS paymentMethod,
            o.project_duration AS projectDuration,
            o.user_latitude AS userLatitude,
            o.user_longitude AS userLongitude,
            o.merchant_latitude AS merchantLatitude,
            o.merchant_longitude AS merchantLongitude,
            o.virtual_latitude AS virtualLatitude,
            o.virtual_longitude AS virtualLongitude,
            o.start_photo AS startPhoto,
            o.platform_income AS platformIncome,
            o.merchant_income AS merchantIncome,
            ass.id AS afterSalesServiceId,
            ass.status AS afterSalesServiceStatus
        FROM t_order o
        LEFT JOIN t_wx_user u ON u.id = CAST(o.user_id AS CHAR) AND u.is_delete = 0
        LEFT JOIN ma_technician mt ON mt.id = o.merchant_id AND mt.is_delete = 0
        LEFT JOIN after_sales_service ass ON ass.id = (
            SELECT ass_inner.id
            FROM after_sales_service ass_inner
            WHERE ass_inner.order_id = o.id
              AND ass_inner.is_delete = 0
            ORDER BY ass_inner.create_time DESC, ass_inner.id DESC
            LIMIT 1
        )
        WHERE o.id = #{id}
          AND o.is_delete = 0
        LIMIT 1
    </select>

    <select id="selectOrderProjectDetailById" resultType="com.ylx.order.domain.vo.AdminOrderDetailVO$ProjectInfoVO">
        SELECT
            COALESCE(p.title, o.project_name) AS projectName,
            COALESCE(p.cover, o.project_cover) AS projectCover,
            p.standard_duration AS standardDuration,
            p.unit_type AS unitType,
            COALESCE(p.price, o.base_price) AS unitPrice,
            p.merchant_share_ratio AS merchantCommission,
            o.final_amount AS finalAmount,
            o.base_price AS basePrice,
            o.traffic_fee AS trafficFee,
            o.coupon_discount AS couponDiscount,
            ass.id AS afterSalesServiceId,
            ass.status AS afterSalesServiceStatus
        FROM t_order o
        LEFT JOIN project p ON p.id = o.project_id AND p.is_delete = 0
        LEFT JOIN after_sales_service ass ON ass.id = (
            SELECT ass_inner.id
            FROM after_sales_service ass_inner
            WHERE ass_inner.order_id = o.id
              AND ass_inner.is_delete = 0
            ORDER BY ass_inner.create_time DESC, ass_inner.id DESC
            LIMIT 1
        )
        WHERE o.id = #{id}
          AND o.is_delete = 0
        LIMIT 1
    </select>

    <!-- 根据订单ID查询订单操作日志 -->
    <select id="selectOrderOperationLogs" resultType="com.ylx.order.domain.vo.AdminOrderDetailVO$OperationLogVO">
        SELECT
            COALESCE(osf.create_by, '系统') AS operator,
            DATE_FORMAT(osf.create_time, '%Y-%m-%d %H:%i:%s') AS operationTime,
            osf.status
        FROM t_order_status_flow osf
        WHERE osf.order_id = #{id}
        ORDER BY osf.create_time ASC
    </select>

    <!-- 根据订单ID查询派单订单 -->
    <select id="selectDispatchOrderById" resultType="com.ylx.order.domain.vo.AdminOrderDispatchOrderVO">
        SELECT
            o.id AS orderId,
            o.order_no AS orderNo,
            o.status AS status,
            o.project_id AS projectId,
            COALESCE(p.title, o.project_name) AS projectName,
            p.category_id AS categoryId,
            o.user_latitude AS userLatitude,
            o.user_longitude AS userLongitude
        FROM t_order o
        LEFT JOIN project p ON p.id = o.project_id AND p.is_delete = 0
        WHERE o.id = #{id}
          AND o.is_delete = 0
        LIMIT 1
    </select>

    <!-- 查询派单商户候选 -->
    <select id="selectDispatchMerchantCandidates" resultType="com.ylx.order.domain.vo.AdminOrderDispatchMerchantVO">
        SELECT
            candidate.*,
            CASE
                WHEN candidate.distance_meters &lt; 1000 THEN CONCAT(ROUND(candidate.distance_meters, 0), 'm')
                ELSE CONCAT(ROUND(candidate.distance_meters / 1000, 1), 'km')
            END AS distanceShow
        FROM (
            SELECT
                t.id AS merchantId,
                t.te_name AS merchantName,
                t.te_nick_name AS merchantNickName,
                t.te_phone AS merchantPhone,
                COALESCE(t.te_avatar, t.avatar) AS merchantAvatar,
                t.tech_type AS merchantType,
                t.post_state AS postState,
                CASE t.post_state
                    WHEN 1 THEN '在线接单'
                    WHEN 0 THEN '休息中'
                    ELSE ''
                END AS postStateName,
                t.service_state AS serviceState,
                CASE t.service_state
                    WHEN 0 THEN '服务中'
                    WHEN 1 THEN '待接单'
                    WHEN 2 THEN '休息中'
                    ELSE ''
                END AS serviceStateName,
                COALESCE(addr.detail_address, addr.address, addr.atlas_add, t.te_address) AS merchantAddress,
                addr.latitude AS merchantLatitude,
                addr.longitude AS merchantLongitude,
                ROUND(ST_Distance_Sphere(POINT(addr.longitude, addr.latitude), POINT(#{order.userLongitude}, #{order.userLatitude})), 2) AS distance_meters
            FROM ma_technician t
            INNER JOIN ma_project mp ON mp.merchant_id = t.id
                AND mp.is_delete = 0
                AND mp.audit_status = 1
                AND mp.project_is_enable = 1
            INNER JOIN project p ON p.id = mp.project_id
                AND p.is_delete = 0
            INNER JOIN t_address addr ON addr.merchant_id = t.id
                AND addr.user_type = 2
                AND addr.type = 1
                AND addr.is_delete = 0
            WHERE t.is_delete = 0
              AND t.audit_status = 2
              AND t.merchant_status = 0
              AND addr.longitude IS NOT NULL
              AND addr.latitude IS NOT NULL
              <choose>
                  <when test="order.categoryId != null">
                      AND p.category_id = #{order.categoryId}
                  </when>
                  <otherwise>
                      AND mp.project_id = #{order.projectId}
                  </otherwise>
              </choose>
              <if test="query.cityCode != null and query.cityCode != ''">
                  AND t.te_area_code = #{query.cityCode}
              </if>
              <if test="query.keyword != null and query.keyword != ''">
                  AND (
                      t.te_name LIKE CONCAT('%', #{query.keyword}, '%')
                      OR t.te_nick_name LIKE CONCAT('%', #{query.keyword}, '%')
                      OR t.te_phone LIKE CONCAT('%', #{query.keyword}, '%')
                  )
              </if>
        ) candidate
        WHERE candidate.distance_meters &lt;= #{query.radiusMeters}
        ORDER BY candidate.distance_meters ASC, candidate.merchantId ASC
    </select>

    <select id="selectDispatchMerchantById" resultType="com.ylx.order.domain.vo.AdminOrderDispatchMerchantVO">
        SELECT
            candidate.*,
            CASE
                WHEN candidate.distance_meters &lt; 1000 THEN CONCAT(ROUND(candidate.distance_meters, 0), 'm')
                ELSE CONCAT(ROUND(candidate.distance_meters / 1000, 1), 'km')
            END AS distanceShow
        FROM (
            SELECT
                t.id AS merchantId,
                t.te_name AS merchantName,
                t.te_nick_name AS merchantNickName,
                t.te_phone AS merchantPhone,
                COALESCE(t.te_avatar, t.avatar) AS merchantAvatar,
                t.tech_type AS merchantType,
                t.post_state AS postState,
                CASE t.post_state
                    WHEN 1 THEN '在线接单'
                    WHEN 0 THEN '休息中'
                    ELSE ''
                END AS postStateName,
                t.service_state AS serviceState,
                CASE t.service_state
                    WHEN 0 THEN '服务中'
                    WHEN 1 THEN '待接单'
                    WHEN 2 THEN '休息中'
                    ELSE ''
                END AS serviceStateName,
                COALESCE(addr.detail_address, addr.address, addr.atlas_add, t.te_address) AS merchantAddress,
                addr.latitude AS merchantLatitude,
                addr.longitude AS merchantLongitude,
                ROUND(ST_Distance_Sphere(POINT(addr.longitude, addr.latitude), POINT(#{order.userLongitude}, #{order.userLatitude})), 2) AS distance_meters
            FROM ma_technician t
            INNER JOIN ma_project mp ON mp.merchant_id = t.id
                AND mp.is_delete = 0
                AND mp.audit_status = 1
                AND mp.project_is_enable = 1
            INNER JOIN project p ON p.id = mp.project_id
                AND p.is_delete = 0
            INNER JOIN t_address addr ON addr.merchant_id = t.id
                AND addr.user_type = 2
                AND addr.type = 1
                AND addr.is_delete = 0
            WHERE t.id = #{merchantId}
              AND t.is_delete = 0
              AND t.audit_status = 2
              AND t.merchant_status =0
              AND addr.longitude IS NOT NULL
              AND addr.latitude IS NOT NULL
              <choose>
                  <when test="order.categoryId != null">
                      AND p.category_id = #{order.categoryId}
                  </when>
                  <otherwise>
                      AND mp.project_id = #{order.projectId}
                  </otherwise>
              </choose>
        ) candidate
        WHERE candidate.distance_meters &lt;= #{radiusMeters}
        ORDER BY candidate.distance_meters ASC
        LIMIT 1
    </select>

    <!-- 查询订单当前派单状态 -->
    <select id="countCurrentDispatchByOrderId" resultType="java.lang.Integer">
        SELECT COUNT(1)
        FROM t_order_dispatch
        WHERE order_id = #{orderId}
          AND current_flag = 1
          AND is_delete = 0
    </select>

    <insert id="insertOrderDispatch" parameterType="com.ylx.order.domain.OrderDispatch">
        INSERT INTO t_order_dispatch (
            order_id,
            order_no,
            merchant_id,
            merchant_name,
            merchant_nick_name,
            merchant_phone,
            merchant_avatar,
            merchant_type,
            project_id,
            project_name,
            category_id,
            city_code,
            user_latitude,
            user_longitude,
            merchant_latitude,
            merchant_longitude,
            distance_meters,
            dispatch_status,
            dispatch_source,
            current_flag,
            order_status_before,
            order_status_after,
            dispatch_time,
            remark,
            operator_id,
            operator_name,
            create_by,
            create_time,
            update_by,
            update_time,
            is_delete
        ) VALUES (
            #{orderId},
            #{orderNo},
            #{merchantId},
            #{merchantName},
            #{merchantNickName},
            #{merchantPhone},
            #{merchantAvatar},
            #{merchantType},
            #{projectId},
            #{projectName},
            #{categoryId},
            #{cityCode},
            #{userLatitude},
            #{userLongitude},
            #{merchantLatitude},
            #{merchantLongitude},
            #{distanceMeters},
            #{dispatchStatus},
            #{dispatchSource},
            #{currentFlag},
            #{orderStatusBefore},
            #{orderStatusAfter},
            #{dispatchTime},
            #{remark},
            #{operatorId},
            #{operatorName},
            #{createBy},
            #{createTime},
            #{updateBy},
            #{updateTime},
            #{isDelete}
        )
    </insert>

    <!-- 更新订单派单状态 -->
    <update id="updateOrderDispatch">
        UPDATE t_order
        SET merchant_id = #{merchant.merchantId},
            merchant_type = #{merchant.merchantType},
            merchant_nick_name = #{merchant.merchantNickName},
            merchant_avatar = #{merchant.merchantAvatar},
            merchant_latitude = #{merchant.merchantLatitude},
            merchant_longitude = #{merchant.merchantLongitude},
            status = #{statusAfter},
            dispatched_status = 1,
            dispatched_time = NOW(),
            update_time = NOW()
        WHERE id = #{orderId}
          AND is_delete = 0
          AND status = #{statusBefore}
    </update>

    <insert id="insertOrderStatusFlow">
        INSERT INTO t_order_status_flow (
            order_id,
            status,
            create_by,
            create_time,
            update_by,
            update_time
        ) VALUES (
            #{orderId},
            #{status},
            #{operator},
            NOW(),
            #{operator},
            NOW()
        )
    </insert>
</mapper>
