<?php namespace Phpcmf\Control\Admin;
/**
 * https://www.besyun.com
 * BESCMS
 * 本文件是框架系统文件，二次开发时不可以修改本文件
 **/

// 附件
class Attachments extends \Phpcmf\Table {

    public function __construct() {
        parent::__construct();
        \Phpcmf\Service::V()->assign([
            'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
                [
                    '附件管理' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
                    '已归档的附件' => [\Phpcmf\Service::L('Router')->class.'/db_index', 'fa fa-folder'],
                    '未归档的附件' => [\Phpcmf\Service::L('Router')->class.'/unused_index', 'fa fa-folder-o'],
                    '变更储存策略' => ['add:'.\Phpcmf\Service::L('Router')->class.'/remote_edit', 'fa fa-edit', '500px', '400px'],
                    'help' => [356],
                ]
            )
        ]);
    }

    // 附件目录（资源管理器）
    public function index() {

        $rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->get('path'));
        $listing = $this->_dir_listing($rel);
        if ($listing === null) {
            $rel = '';
            $listing = $this->_dir_listing($rel);
        }

        $p = [
            'size' => 9999,
            'exts' => '*',
            'count' => 20,
            'attachment' => 0,
            'image_reduce' => 0,
            'chunk' => 10 * 1024 * 1024,
        ];
        $upload = [
            'url' => dr_web_prefix(SELF.'?c='.\Phpcmf\Service::L('Router')->class.'&m=dir_upload')
                .'&siteid='.SITE_ID,
            'param' => $p,
        ];

        $uriprefix = trim(APP_DIR.'/'.\Phpcmf\Service::L('Router')->class, '/');
        $parent_rel = '';
        if ($listing['rel'] !== '') {
            $norm = str_replace('\\', '/', $listing['rel']);
            $d = dirname($norm);
            $parent_rel = ($d === '.' || $d === '') ? '' : str_replace('\\', '/', $d);
        }
        \Phpcmf\Service::V()->assign([
            'dir' => IS_DEV ? SYS_UPLOAD_PATH : dr_safe_replace_path(SYS_UPLOAD_PATH),
            'url' => SYS_UPLOAD_URL,
            'rel' => $listing['rel'],
            'parent_rel' => $parent_rel,
            'dirs' => $listing['dirs'],
            'files' => $listing['files'],
            'breadcrumb' => $this->_dir_breadcrumb($listing['rel']),
            'upload' => $upload,
            'uriprefix' => $uriprefix,
            'dir_delete_url' => dr_url($uriprefix.'/dir_delete'),
            'dir_mkdir_url' => dr_url($uriprefix.'/dir_mkdir'),
            'dir_replace_url' => dr_url($uriprefix.'/dir_replace'),
            'dir_folder_size_url' => dr_url($uriprefix.'/dir_folder_size'),
            'dir_js' => [
                'confirm_del' => addslashes(dr_lang('你确定要删除它们吗？')),
                'mkdir_title' => addslashes(dr_lang('新建文件夹')),
                'name_empty' => addslashes(dr_lang('名称不能为空')),
                'upload_fail' => addslashes(dr_lang('上传失败')),
            ],
            'meta_title' => dr_lang('附件目录'),
        ]);
        \Phpcmf\Service::V()->display('attachment_dir.html');
    }

    /**
     * AJAX：递归统计文件夹及子目录文件总大小
     */
    public function dir_folder_size() {

        if (function_exists('set_time_limit')) {
            @set_time_limit(300);
        }

        $rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->get('path'));
        if ($rel === '') {
            $this->_json(0, dr_lang('参数错误'));
        }

        list($ok, $abs, $r) = $this->_dir_safe($rel);
        if (!$ok || !is_dir($abs)) {
            $this->_json(0, dr_lang('目录不存在'));
        }

        $root = rtrim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, SYS_UPLOAD_PATH), DIRECTORY_SEPARATOR);
        $rootReal = realpath($root);
        if ($rootReal === false) {
            $this->_json(0, dr_lang('目录无效或不存在'));
        }

        $bytes = $this->_dir_tree_size($abs, $rootReal);
        $this->_json(1, 'ok', [
            'size' => $bytes,
            'size_text' => dr_format_file_size($bytes),
        ]);
    }

    /**
     * 递归统计目录下所有文件字节（不跟随符号链接）
     */
    protected function _dir_tree_size($absDir, $rootReal) {

        $total = 0;
        if (!is_dir($absDir)) {
            return 0;
        }
        $absDir = rtrim($absDir, DIRECTORY_SEPARATOR);
        if (is_link($absDir)) {
            return 0;
        }

        if ($fp = @opendir($absDir)) {
            while (($name = readdir($fp)) !== false) {
                if ($name === '.' || $name === '..') {
                    continue;
                }
                $sub = $absDir.DIRECTORY_SEPARATOR.$name;
                if (is_link($sub)) {
                    continue;
                }
                if (is_file($sub)) {
                    $sz = @filesize($sub);
                    if ($sz !== false) {
                        $total += $sz;
                    }
                } elseif (is_dir($sub)) {
                    $rp = realpath($sub);
                    if ($rp !== false && $this->_dir_under_root($rootReal, $rp)) {
                        $total += $this->_dir_tree_size($rp, $rootReal);
                    }
                }
            }
            closedir($fp);
        }

        return $total;
    }

    /**
     * 附件目录内上传（写入当前文件夹，并走附件归档）
     */
    public function dir_upload() {

        if (!IS_POST) {
            $this->_json(0, dr_lang('请求错误'));
        }

        $rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('path'));
        list($ok, $abs, $r) = $this->_dir_safe($rel);
        if (!$ok || !is_dir($abs)) {
            $this->_json(0, dr_lang('目录无效或不存在'));
        }

        $cfg = [
            'form_name' => 'file_data',
            'file_exts' => ['*'],
            'file_size' => 9999 * 1024 * 1024,
            'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info(0),
            'watermark' => 0,
            'save_name' => 'null',
        ];
        if ($r !== '') {
            $cfg['path'] = $r;
        }

        $rt = \Phpcmf\Service::L('upload')->upload_file($cfg);
        if (!$rt['code']) {
            exit(dr_array2string($rt));
        }

        $data = [];
        if (defined('SYS_ATTACHMENT_CF') && SYS_ATTACHMENT_CF && $rt['data']['md5']) {
            $att = \Phpcmf\Service::M()->table('attachment')
                ->where('uid', $this->uid)
                ->where('filemd5', $rt['data']['md5'])
                ->where('fileext', $rt['data']['ext'])
                ->where('filesize', $rt['data']['size'])
                ->getRow();
            if ($att) {
                $storage = new \Phpcmf\Library\Storage($this);
                $storage->delete(\Phpcmf\Service::M('Attachment')->get_attach_info(0), $rt['data']['file']);
                $rt['data'] = $this->get_attachment($att['id']);
                if ($rt['data']) {
                    $rt['data']['name'] = $rt['data']['filename'];
                }
                $data = dr_return_data($att['id'], 'ok');
            }
        }
        if (!$data) {
            $data = \Phpcmf\Service::M('Attachment')->save_data($rt['data']);
            if (!$data['code']) {
                exit(dr_array2string($data));
            }
        }

        exit(dr_array2string(['code' => 1, 'msg' => dr_lang('上传成功'), 'id' => $data['code'], 'info' => $rt['data']]));
    }

    /**
     * 覆盖重传指定文件（扩展名须一致）
     */
    public function dir_replace() {

        if (!IS_POST) {
            $this->_json(0, dr_lang('请求错误'));
        }

        $file = isset($_FILES['file_data']) ? $_FILES['file_data'] : null;
        $maxBytes = 9999 * 1024 * 1024;
        if ($file && !empty($file['size']) && $file['size'] > $maxBytes) {
            $this->_json(0, dr_lang('文件大小超出网站限制'));
        }

        $rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('replace'));
        if ($rel === '') {
            $this->_json(0, dr_lang('参数错误'));
        }

        list($ok, $abs, $r) = $this->_dir_safe($rel);
        if (!$ok || !is_file($abs)) {
            $this->_json(0, dr_lang('文件不存在'));
        }

        $name = basename(str_replace('\\', '/', $abs));
        $oldExt = strpos($name, '.') !== false ? strtolower(trim(strrchr($name, '.'), '.')) : '';

        $cfg = [
            'form_name' => 'file_data',
            'file_exts' => $oldExt !== '' ? [$oldExt] : ['*'],
            'file_name' => $abs,
        ];

        $rt = \Phpcmf\Service::L('upload')->update_file($cfg);
        if (!$rt['code']) {
            exit(dr_array2string($rt));
        }

        exit(dr_array2string(['code' => 1, 'msg' => dr_lang('上传成功')]));
    }

    /**
     * 删除所选文件或空目录
     */
    public function dir_delete() {

        if (!IS_POST) {
            $this->_json(0, dr_lang('请求错误'));
        }

        $paths = \Phpcmf\Service::L('input')->post('paths');
        if (!$paths || !is_array($paths)) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        foreach ($paths as $p) {
            $rel = $this->_dir_rel_path($p);
            if ($rel === '') {
                $this->_json(0, dr_lang('禁止删除附件根目录'));
            }
            list($ok, $abs, $r) = $this->_dir_safe($rel);
            if (!$ok) {
                continue;
            }
            if (is_file($abs)) {
                if (!@unlink($abs)) {
                    $this->_json(0, dr_lang('文件删除失败'));
                }
            } elseif (is_dir($abs)) {
                $items = @scandir($abs);
                $left = $items ? array_diff($items, ['.', '..']) : [];
                if ($left) {
                    $this->_json(0, dr_lang('目录非空，无法删除'));
                }
                if (!@rmdir($abs)) {
                    $this->_json(0, dr_lang('目录删除失败'));
                }
            }
        }

        $this->_json(1, dr_lang('操作成功'));
    }

    /**
     * 在当前目录下新建文件夹
     */
    public function dir_mkdir() {

        if (!IS_POST) {
            $this->_json(0, dr_lang('请求错误'));
        }

        $rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('path'));
        $name = trim((string) \Phpcmf\Service::L('input')->post('name'));
        $name = dr_safe_filename($name);
        if ($name === '' || strpos($name, '.') === 0) {
            $this->_json(0, dr_lang('名称不规范'));
        }

        list($ok, $parentAbs, $r) = $this->_dir_safe($rel);
        if (!$ok || !is_dir($parentAbs)) {
            $this->_json(0, dr_lang('当前目录无效'));
        }

        $newAbs = rtrim($parentAbs, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$name;
        if (file_exists($newAbs)) {
            $this->_json(0, dr_lang('已存在同名文件或目录'));
        }
        if (!dr_mkdirs($newAbs)) {
            $this->_json(0, dr_lang('目录创建失败'));
        }

        $this->_json(1, dr_lang('操作成功'));
    }

    /**
     * 规范化相对路径（相对 SYS_UPLOAD_PATH）
     * 按段解析，禁止路径跳出上传根（..），避免简单替换字符串被绕过
     */
    protected function _dir_rel_path($raw) {

        $raw = (string) $raw;
        if ($raw === '' || strpos($raw, "\0") !== false) {
            return '';
        }
        $raw = str_replace('\\', '/', $raw);
        $raw = str_replace(["\r", "\n", '<', '>', '{', '}'], '', $raw);
        $raw = trim($raw, '/');
        if ($raw === '') {
            return '';
        }
        $parts = explode('/', $raw);
        $out = [];
        foreach ($parts as $p) {
            if ($p === '' || $p === '.') {
                continue;
            }
            if ($p === '..') {
                if (empty($out)) {
                    return '';
                }
                array_pop($out);
                continue;
            }
            $p = trim($p);
            if ($p === '' || $p === '.' || $p === '..') {
                continue;
            }
            $out[] = $p;
        }

        return implode('/', $out);
    }

    /**
     * 是否位于上传根目录之下
     */
    protected function _dir_under_root($rootReal, $candidate) {

        $root = strtolower(str_replace('\\', '/', rtrim($rootReal, '/\\')));
        $path = strtolower(str_replace('\\', '/', $candidate));

        return $path === $root || strpos($path, $root.'/') === 0;
    }

    /**
     * 解析安全绝对路径
     */
    protected function _dir_safe($rel) {

        $rel = $this->_dir_rel_path($rel);
        $root = rtrim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, SYS_UPLOAD_PATH), DIRECTORY_SEPARATOR);
        if (!is_dir($root)) {
            return [false, '', ''];
        }
        $rootReal = realpath($root);
        if ($rootReal === false) {
            return [false, '', ''];
        }
        if ($rel === '') {
            return [true, $rootReal.DIRECTORY_SEPARATOR, ''];
        }
        $sub = str_replace('/', DIRECTORY_SEPARATOR, $rel);
        $full = $rootReal.DIRECTORY_SEPARATOR.$sub;
        if (is_file($full) || is_dir($full)) {
            $rp = realpath($full);
            if ($rp !== false && $this->_dir_under_root($rootReal, $rp)) {
                return [true, $rp, $rel];
            }

            return [false, '', ''];
        }

        return [false, '', ''];
    }

    /**
     * 列出目录内容
     */
    protected function _dir_listing($rel) {

        list($ok, $abs, $r) = $this->_dir_safe($rel);
        if (!$ok || !is_dir($abs)) {
            return null;
        }

        $dirs = [];
        $files = [];
        if ($fp = @opendir($abs)) {
            while (($name = readdir($fp)) !== false) {
                if ($name === '.' || $name === '..' || $name === '.DS_Store') {
                    continue;
                }
                if (strtolower(substr($name, -4)) === '.php') {
                    continue;
                }
                $full = $abs.DIRECTORY_SEPARATOR.$name;
                $childRel = $r === '' ? $name : $r.'/'.$name;
                if (is_dir($full)) {
                    $dirs[] = [
                        'name' => $name,
                        'path' => $childRel,
                        'path_esc' => htmlspecialchars($childRel, ENT_QUOTES, 'UTF-8'),
                        'mtime' => filemtime($full),
                    ];
                } elseif (is_file($full)) {
                    $ext = strtolower(trim(strrchr($name, '.'), '.'));
                    $files[] = [
                        'name' => $name,
                        'path' => $childRel,
                        'path_esc' => htmlspecialchars($childRel, ENT_QUOTES, 'UTF-8'),
                        'size' => filesize($full),
                        'mtime' => filemtime($full),
                        'ext' => $ext,
                        'url' => SYS_UPLOAD_URL.str_replace('\\', '/', $childRel),
                        'is_image' => dr_is_image($ext),
                        'is_mp4' => $ext === 'mp4',
                    ];
                }
            }
            closedir($fp);
        }

        usort($dirs, function ($a, $b) {
            return strcasecmp($a['name'], $b['name']);
        });
        usort($files, function ($a, $b) {
            return strcasecmp($a['name'], $b['name']);
        });

        return [
            'rel' => $r,
            'dirs' => $dirs,
            'files' => $files,
        ];
    }

    /**
     * 面包屑
     */
    protected function _dir_breadcrumb($rel) {

        $crumbs = [['name' => dr_lang('附件根目录'), 'path' => '']];
        if ($rel === '') {
            return $crumbs;
        }
        $parts = explode('/', $rel);
        $acc = '';
        foreach ($parts as $p) {
            if ($p === '') {
                continue;
            }
            $acc = $acc === '' ? $p : $acc.'/'.$p;
            $crumbs[] = ['name' => $p, 'path' => $acc];
        }

        return $crumbs;
    }

    // 已归档管理
    public function db_index() {

        $field = [
            'uid' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'uid',
                'name' => '账号',
            ],
            'related' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'related',
                'name' => dr_lang('附件归属'),
            ],
            'fileext' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'fileext',
                'name' => dr_lang('扩展名'),
            ],
            'filename' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'filename',
                'name' => dr_lang('附件名称'),
            ],
            'attachment' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'attachment',
                'name' => dr_lang('附件路径'),
            ],
        ];

        $remote = (int)$_GET['remote'];
        $where_list = 'id in (select id from '.\Phpcmf\Service::M()->dbprefix('attachment').' where siteid='.SITE_ID.')';
        $remote && $where_list.= ' and `remote`='.$remote;

        $this->_init([
            'table' => 'attachment_data',
            'field' => $field,
            'order_by' => 'id desc',
            'where_list' => $where_list,
            'date_field' => 'inputtime',
        ]);

        $this->_List();

        // 快捷上传字段参数
        $p = [
            'size' => 9999,
            'exts' => '*',
            'count' => 20,
            'attachment' => $remote,
            'image_reduce' => 0,
            'chunk' => 10 * 1024 * 1024,
        ];
        $upload = [
            'url' => dr_web_prefix(SELF.'?c=api&token='.dr_get_csrf_token())
                .'&siteid='.SITE_ID.'&m=upload&p='.dr_authcode($p, 'ENCODE'),
            'param' => $p,
            'back' => dr_now_url(),
        ];

        \Phpcmf\Service::V()->assign([
            'field' => $field,
            'table' => 'data',
            'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
            'upload' => $upload,
        ]);
        \Phpcmf\Service::V()->display('attachment_admin.html');
    }

    // 未归档的附件
    public function unused_index() {

        $field = [
            'author' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'author',
                'name' => dr_lang('账号'),
            ],
            'fileext' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'fileext',
                'name' => dr_lang('扩展名'),
            ],
            'uid' => [
                'ismain' => 1,
                'fieldtype' => 'Text',
                'fieldname' => 'uid',
                'name' => 'uid',
            ],
        ];

        $remote = (int)$_GET['remote'];
        $where_list = 'siteid='.SITE_ID;
        $remote && $where_list.= ' and `remote`='.$remote;

        $this->_init([
            'table' => 'attachment_unused',
            'field' => $field,
            'order_by' => 'id desc',
            'where_list' => $where_list,
            'date_field' => 'inputtime',
        ]);

        $this->_List();

        \Phpcmf\Service::V()->assign([
            'field' => $field,
            'table' => 'unused',
            'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
        ]);
        \Phpcmf\Service::V()->display('attachment_admin.html');
    }

    public function remote_edit() {

        if (IS_POST) {
            $post = \Phpcmf\Service::L('input')->post('data');
            if ($post['o'] == $post['n']) {
                $this->_json(0, dr_lang('储存策略不能相同'));
            }

            \Phpcmf\Service::M()->table('attachment_unused')->where('remote', intval($post['o']))->update(0, [
                'remote' => intval($post['n'])
            ]);

            \Phpcmf\Service::M()->table('attachment_data')->where('remote', intval($post['o']))->update(0, [
                'remote' => intval($post['n'])
            ]);

            dr_dir_delete(WRITEPATH.'attach');
            dr_mkdirs(WRITEPATH.'attach');
            
            $this->_json(1, dr_lang('操作成功'));
        }

        \Phpcmf\Service::V()->assign([
            'form' => dr_form_hidden(),
            'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
        ]);
        \Phpcmf\Service::V()->display('attachment_remote_edit.html');
    }

    public function del() {

        $ids = \Phpcmf\Service::L('input')->get_post_ids();
        if (!$ids) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        $table = \Phpcmf\Service::L('input')->post('table');
        $table != 'data' && $table = 'unused';

        $data = \Phpcmf\Service::M()->db->table('attachment_'.$table)->whereIn('id', $ids)->get()->getResultArray();
        if (!$data) {
            $this->_json(0, dr_lang('所选附件不存在'));
        }

        foreach ($data as $t) {
            $rt = \Phpcmf\Service::M('attachment')->_delete_file($t);
            if (!$rt['code']) {
                return dr_return_data(0, $rt['msg']);
            }
        }

        $this->_json(1, dr_lang('操作成功'));
    }

    // 强制归档
    public function edit() {

        $ids = \Phpcmf\Service::L('input')->get_post_ids();
        if (!$ids) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        $data = \Phpcmf\Service::M()->db->table('attachment_unused')->whereIn('id', $ids)->get()->getResultArray();
        if (!$data) {
            $this->_json(0, dr_lang('所选附件不存在'));
        }

        $related = 'Save';
        foreach ($data as $t) {
            // 更新主索引表
            \Phpcmf\Service::M()->table('attachment')->update($t['id'], array(
                'related' => $related
            ));
            \Phpcmf\Service::M()->table('attachment_data')->insert(array(
                'id' => $t['id'],
                'uid' => $t['uid'],
                'remote' => $t['remote'],
                'author' => $t['author'],
                'related' => $related,
                'fileext' => $t['fileext'],
                'filesize' => $t['filesize'],
                'filename' => $t['filename'],
                'inputtime' => $t['inputtime'],
                'attachment' => $t['attachment'],
                'attachinfo' => '',
            ));
            // 删除未归档附件
            \Phpcmf\Service::M()->table('attachment_unused')->delete($t['id']);
        }

        $this->_json(1, dr_lang('操作成功'));
    }

    // 变更储存策略
    public function type_edit() {

        $ids = \Phpcmf\Service::L('input')->get_post_ids();
        if (!$ids) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        $rid = intval(\Phpcmf\Service::L('input')->post('remote'));
        if ($rid < 0) {
            $this->_json(0, dr_lang('你还没有选择储存策略'));
        }

        $table = \Phpcmf\Service::L('input')->post('table');
        $table != 'data' && $table = 'unused';

        \Phpcmf\Service::M()->table('attachment_'.$table)->where_in('id', $ids)->update(0, [
            'remote' => $rid
        ]);

        dr_dir_delete(WRITEPATH.'attach');
        dr_mkdirs(WRITEPATH.'attach');

        $this->_json(1, dr_lang('操作成功'));
    }

    // 重新上传附件
    public function file_edit() {

        $id = \Phpcmf\Service::L('input')->get('id');
        if (!$id) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        $data = $this->get_attachment($id, true);
        if (!$data) {
            $this->_json(0, dr_lang('附件信息不存在'));
        }

        \Phpcmf\Service::V()->assign([
            'data' => $data,
        ]);
        \Phpcmf\Service::V()->display('attachment_upload.html');
    }

    // 重新上传附件
    public function upload_edit() {

        $id = \Phpcmf\Service::L('input')->get('id');
        if (!$id) {
            $this->_json(0, dr_lang('你还没有选择呢'));
        }

        $data = $this->get_attachment($id, true);
        if (!$data) {
            $this->_json(0, dr_lang('附件信息不存在'));
        }

        $rt = \Phpcmf\Service::L('upload')->upload_file([
            'save_name' => str_replace('.'.$data['fileext'], '', basename($data['attachment'])),
            'path' => dirname($data['attachment']),
            'form_name' => 'file_data',
            'file_exts' => [$data['fileext']],
            'file_size' => 1000 * 1024 * 1024,
            'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info($data['remote']),
        ]);
        if (!$rt['code']) {
            exit(dr_array2string($rt));
        }
        \Phpcmf\Service::M()->table('attachment_data')->update($id, ['filesize' => $rt['data']['size']]);
        \Phpcmf\Service::M()->table('attachment_unused')->update($id, ['filesize' => $rt['data']['size']]);
        $this->_json(1, dr_lang('上传成功'), $rt['data']);
    }
}
