浏览代码

first commit

liuhairui 4 周之前
父节点
当前提交
9149adbb1e

+ 2 - 2
application/api/controller/WorkOrder.php

@@ -160,7 +160,7 @@ class WorkOrder extends Api{
 
         // 正常的视频生成请求处理
         $apiUrl = 'https://chatapi.onechats.ai/v1/videos';
-        $apiKey = 'sk-sWW1GFlnjbrDRb1DkMEzePIxgdvLK6cZt0Qg93yDMVP2z1yN';
+        $apiKey = 'sk-ABO93U8p7u6Sin4yxnAHI8Z8K9hX8YjRO9rfTC0y3Ftv4mNm';
 
         $postData = [
             'prompt' => $params['prompt'],
@@ -326,7 +326,7 @@ class WorkOrder extends Api{
         }
 
         $apiUrl = 'https://chatapi.onechats.ai/v1/videos/' . $videoId;
-        $apiKey = 'sk-sWW1GFlnjbrDRb1DkMEzePIxgdvLK6cZt0Qg93yDMVP2z1yN';
+        $apiKey = 'sk-ABO93U8p7u6Sin4yxnAHI8Z8K9hX8YjRO9rfTC0y3Ftv4mNm';
 
         // 先检查本地是否已经有该视频
         $localVideoPath = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'videos' . DS . date('Ymd') . DS . $videoId . '.mp4';

+ 2 - 19
application/index/controller/Index.php

@@ -8,29 +8,12 @@ use think\Queue;
 use  think\Db;
 class Index extends Frontend
 {
-
     protected $noNeedLogin = '*';
     protected $noNeedRight = '*';
     protected $layout = '';
-
     public function index(){
-         // // 查询模版表
-        // $products = Db::name('product_template')->select();
-
-        // $http_url = Db::name('http_url')->field('baseUrl,port')->find();
-        // if ($products && $http_url) {
-        //     $base_url = !empty($http_url['baseUrl']) && !empty($http_url['port'])
-        //         ? 'http://' . $http_url['baseUrl'] . ':' . $http_url['port']: '';
-
-        //     if ($base_url) {
-        //         foreach ($products as &$val) {
-        //             $val['template_image_url'] = $base_url . $val['template_image_url'];
-        //         }
-        //     }
-        // }
-        // $this->assign('products', $products);
-        // $this->assign('http_url', $http_url);
-        return $this->view->fetch();
+        $this->redirect('index/user/login');
+//        return $this->view->fetch();
     }
 
 }

+ 145 - 3
application/index/controller/User.php

@@ -57,6 +57,16 @@ class User extends Frontend
      */
     public function index()
     {
+        // // 打印用户信息到页面(调试用)
+        // $userInfo = $this->auth->getUser();
+        // echo '<pre>';
+        // echo '用户ID: ' . $this->auth->id . '<br>';
+        // echo '用户信息(通过auth->getUser()获取): <br>';
+        // print_r($userInfo->toArray());
+        // echo '<br>用户信息(通过auth->getUserinfo()获取): <br>';
+        // print_r($this->auth->getUserinfo());
+        // echo '</pre>';
+
         $this->view->assign('title', __('User center'));
         return $this->view->fetch();
     }
@@ -68,7 +78,7 @@ class User extends Frontend
     {
         $url = $this->request->request('url', '', 'url_clean');
         if ($this->auth->id) {
-            $this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/index'));
+            $this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/template'));
         }
         if ($this->request->isPost()) {
             $username = $this->request->post('username');
@@ -123,7 +133,7 @@ class User extends Frontend
                 $this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
             }
             if ($this->auth->register($username, $password, $email, $mobile)) {
-                $this->success(__('Sign up successful'), $url ? $url : url('user/index'));
+                $this->success(__('Sign up successful'), $url ? $url : url('user/template'));
             } else {
                 $this->error($this->auth->getError(), null, ['token' => $this->request->token()]);
             }
@@ -348,7 +358,7 @@ class User extends Frontend
         }
 
         // 查询模版表
-        $products = Db::name('product_template')->where($where)->order('id desc')->select();
+        $products = Db::name('product_template')->where($where)->order('id desc')->where('mod_rq', null)->select();
 
         // // 检查并修正图片URL
         // foreach ($products as &$val) {
@@ -376,7 +386,139 @@ class User extends Frontend
         return $this->view->fetch();
     }
 
+    public function text_to_image(){
+        return $this->view->fetch();
+    }
+
     public function text_to_video(){
         return $this->view->fetch();
     }
+
+    public function diagrams_list(){
+        // 获取作品ID
+        $id = input('param.id', 0, 'intval');
+
+        if (empty($id)) {
+            $this->error(__('Invalid parameter'));
+        }
+        //获取用户信息
+        $user = $this->auth->getUserinfo();
+        $user_info = Db::name('user')->where('id',$user['id'])->find();
+
+        // 根据ID查询作品信息,允许查询已删除的作品(mod_rq不为null)
+        $product = Db::name('product_template')->where('id', $id)->find();
+
+        if (empty($product)) {
+            $this->error(__('Product not found'));
+        }
+
+        // 将作品信息传递给视图
+        $this->view->assign('user_info', $user_info);
+        $this->view->assign('product', $product);
+        return $this->view->fetch();
+    }
+
+    public function diagrams(){
+        $user = $this->auth->getUserinfo();
+        //获取用户信息
+//        $user_info = Db::name('user')->where('id',$user['id'])->find();
+
+        // 构建查询条件
+        $where = [];
+        if (!empty($keyword)) {
+            $where['template_name|type'] = ['like', '%' . $keyword . '%'];
+        }
+        if (!empty($type)) {
+            $where['type'] = ['like', '%' . $type . '%'];
+        }
+
+        // 查询模糊的模版信息
+        $products = Db::name('product_template')
+            ->where('user_id',$user['id'])
+            ->where('mod_rq', null)
+            ->order('id desc')->select();
+        $this->view->assign('products', $products);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 软删除 保留数据
+     * 只修改 mod_rq
+     * */
+    public function diagrams_del(){
+        $params = $this->request->param();
+        $updata_products = Db::name('product_template')
+            ->where('id',$params['id'])
+            ->update(['mod_rq' => date('Y-m-d H:i:s')]);
+
+        if ($updata_products) {
+            return json(['code' => 0, 'msg' => '删除成功,可在回收站恢复']);
+        } else {
+            return json(['code' => 1, 'msg' => '删除失败']);
+        }
+    }
+
+    /**
+     * 真删除 删除回收站
+     * */
+    public function diagrams_delete(){
+        $params = $this->request->param();
+        $user = $this->auth->getUserinfo();
+
+        // 检查权限
+        $product = Db::name('product_template')->where('id', $params['id'])->where('user_id', $user['id'])->find();
+        if (!$product) {
+            return json(['code' => 1, 'msg' => '无权限操作此作品']);
+        }
+
+        $delete_result = Db::name('product_template')
+            ->where('id', $params['id'])
+            ->where('user_id', $user['id'])
+            ->delete();
+
+        if ($delete_result) {
+            return json(['code' => 0, 'msg' => '彻底删除成功']);
+        } else {
+            return json(['code' => 1, 'msg' => '删除失败']);
+        }
+    }
+
+    /**
+     * 查询回收站数据
+     * */
+    public function recycle(){
+        $user = $this->auth->getUserinfo();
+        $products = Db::name('product_template')
+            ->where('user_id',$user['id'])
+            ->whereNotNull('mod_rq')
+            ->order('id desc')->select();
+        $this->view->assign('products', $products);
+        return $this->view->fetch();
+    }
+
+    /**
+     * 恢复回收站数据
+     * */
+    public function diagrams_restore(){
+        $params = $this->request->param();
+        $user = $this->auth->getUserinfo();
+
+        // 检查权限
+        $product = Db::name('product_template')->where('id', $params['id'])->where('user_id', $user['id'])->find();
+       
+        if (!$product) {
+            return json(['code' => 1, 'msg' => '无权限操作此作品']);
+        }
+
+        $update_result = Db::name('product_template')
+            ->where('id', $params['id'])
+            ->where('user_id', $user['id'])
+            ->update(['mod_rq' => null]);
+
+        if ($update_result) {
+            return json(['code' => 0, 'msg' => '恢复成功']);
+        } else {
+            return json(['code' => 1, 'msg' => '恢复失败']);
+        }
+    }
 }

+ 3 - 2
application/index/view/layout/default.html

@@ -13,8 +13,9 @@
                 </div>
                 <div class="collapse navbar-collapse" id="header-navbar">
                     <ul class="nav navbar-nav">
-                        <li><a href="{:url('user/index')}">AI设计</a></li>
+                        <li><a href="{:url('user/text_to_image')}">AI设计</a></li>
                         <li><a href="{:url('user/template')}">模板</a></li>
+                        <li><a href="{:url('user/diagrams')}">个人</a></li>
                     </ul>
                     <ul class="nav navbar-nav navbar-right">
                         <!-- <li><a href="{:url('/')}">{:__('Home')}</a></li> -->
@@ -29,7 +30,7 @@
                             {/if}
                             <ul class="dropdown-menu">
                                 {if $user}
-                                <!-- <li><a href="{:url('user/index')}"><i class="fa fa-user-circle fa-fw"></i>AI设计</a></li> -->
+                                <li><a href="{:url('user/index')}"><i class="fa fa-user-circle fa-fw"></i>个人中心</a></li>
                                 <li><a href="{:url('user/profile')}"><i class="fa fa-user-o fa-fw"></i>个人资料</a></li>
                                 <li><a href="{:url('user/changepwd')}"><i class="fa fa-key fa-fw"></i>修改密码</a></li>
                                 <li><a href="{:url('user/logout')}"><i class="fa fa-sign-out fa-fw"></i>退出登录</a></li>

+ 588 - 0
application/index/view/user/diagrams.html

@@ -0,0 +1,588 @@
+<style>
+        /* 主容器 - 左右布局 */
+        .user-diagrams-container {
+            display: flex;
+            min-height: calc(100vh - 120px); /* 减去导航栏和页脚高度 */
+        }
+
+        /* 左侧菜单样式 */
+        .sidebar {
+            width: 200px;
+            background-color: #fff;
+            border-right: 1px solid #e8e8e8;
+            flex-shrink: 0;
+        }
+
+        .menu {
+            padding: 20px 0;
+        }
+
+        .menu-item {
+            list-style: none;
+        }
+
+        .menu-item a {
+            display: block;
+            padding: 15px 20px;
+            text-decoration: none;
+            color: #000000;
+            font-size: 16px;
+            transition: all 0.3s ease;
+        }
+
+        .menu-item.active a {
+            background-color: #f0f7ff;
+            color: #1890ff;
+            font-weight: 500;
+        }
+
+        .menu-item:hover a {
+            background-color: #f5f5f5;
+            color: #1890ff;
+        }
+
+        /* 右侧内容区域样式 */
+        .diagrams-content {
+            flex: 1;
+            background-color: #fff;
+            padding: 20px;
+        }
+
+        /* 标签页样式 */
+        .tabs {
+            margin-bottom: 20px;
+        }
+
+        .tab-item {
+            display: inline-block;
+            margin-right: 20px;
+            padding: 10px 0;
+            font-size: 16px;
+            color: #1890ff;
+            cursor: pointer;
+            border-bottom: 2px solid transparent;
+            transition: all 0.3s ease;
+        }
+
+        .tab-item.active {
+            font-weight: 500;
+            border-bottom-color: #1890ff;
+        }
+
+        .tab-item:hover {
+            color: #40a9ff;
+        }
+
+        /* 内容区域 */
+        .tab-content {
+            min-height: 400px;
+            border: 1px solid #e8e8e8;
+            border-radius: 4px;
+            padding: 20px;
+        }
+
+        /* 模板网格样式 */
+        .template-grid {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+            gap: 20px;
+        }
+
+        .template-card {
+            border: 1px solid #e8e8e8;
+            border-radius: 8px;
+            overflow: hidden;
+            transition: all 0.3s ease;
+            cursor: pointer;
+        }
+
+        .template-card:hover {
+            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+            transform: translateY(-2px);
+        }
+
+        .template-thumbnail {
+            width: 100%;
+            height: 160px;
+            overflow: hidden;
+            background-color: #f5f5f5;
+            position: relative;
+        }
+
+        /* 审核状态标识样式 */
+        .examine-status {
+            position: absolute;
+            top: 8px;
+            right: 8px;
+            padding: 4px 12px;
+            border-radius: 4px;
+            font-size: 12px;
+            font-weight: 500;
+            color: #fff;
+            z-index: 10;
+        }
+
+        .examine-status.passed {
+            background-color: #52c41a;
+        }
+
+        .examine-status.failed {
+            background-color: #ff4d4f;
+        }
+
+        .examine-status.pending {
+            background-color: #faad14;
+        }
+
+        .template-thumbnail img,
+        .template-thumbnail video {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+            transition: transform 0.3s ease;
+        }
+
+        .template-card:hover .template-thumbnail img,
+        .template-card:hover .template-thumbnail video {
+            transform: scale(1.05);
+        }
+
+        .template-info {
+            padding: 15px;
+        }
+
+        .template-name {
+            font-size: 16px;
+            font-weight: 500;
+            margin-bottom: 8px;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+        }
+
+        .template-meta {
+            font-size: 14px;
+            color: #666;
+        }
+
+        .template-meta span {
+            margin-right: 15px;
+        }
+
+        /* 删除按钮样式 */
+        .delete-btn {
+            color: #ff4d4f;
+            cursor: pointer;
+            transition: color 0.3s ease;
+        }
+
+        .delete-btn:hover {
+            color: #ff7875;
+            text-decoration: underline;
+        }
+
+        /* 空提示样式 */
+        .empty-tip {
+            grid-column: 1 / -1;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            min-height: 400px;
+            text-align: center;
+            padding: 40px 20px;
+            color: #999;
+        }
+
+        .empty-icon {
+            font-size: 64px;
+            margin-bottom: 20px;
+            opacity: 0.5;
+        }
+
+        .empty-text {
+            font-size: 20px;
+            font-weight: 500;
+            margin-bottom: 10px;
+            color: #666;
+        }
+
+        .empty-subtext {
+            font-size: 14px;
+            color: #999;
+        }
+
+        /* 响应式设计 */
+        @media (max-width: 768px) {
+            .user-diagrams-container {
+                flex-direction: column;
+            }
+
+            .sidebar {
+                width: 100%;
+                border-right: none;
+                border-bottom: 1px solid #e8e8e8;
+            }
+
+            .menu {
+                padding: 0;
+            }
+
+            .menu-item {
+                display: inline-block;
+            }
+
+            .menu-item a {
+                padding: 12px 15px;
+            }
+        }
+    </style>
+
+    <div class="user-diagrams-container">
+        <!-- 左侧菜单 -->
+        <div class="sidebar">
+            <ul class="menu">
+                <li class="menu-item active">
+                    <a href="{:url('user/diagrams')}">我的作品</a>
+                </li>
+                <li class="menu-item">
+                    <a href="{:url('user/recycle')}">收回站</a>
+                </li>
+            </ul>
+        </div>
+
+        <!-- 右侧内容区域 -->
+        <div class="diagrams-content">
+            <!-- 标签页 -->
+            <div class="tabs">
+                <div class="tab-item active">全部作品</div>
+            </div>
+
+            <!-- 内容区域 -->
+            <div class="tab-content">
+                <div class="template-grid" id="templateGrid">
+                    <!-- 使用volist标签循环显示模板 -->
+                    {volist name="products" id="template"}
+                    <div class="template-card">
+                        <div class="template-thumbnail">
+                            <!-- 审核状态标识 -->
+                            <div class="examine-status {if condition="$template.toexamine eq '审核通过'"}passed{elseif condition="$template.toexamine eq '未通过'"}failed{else}pending{/if}">
+                                {$template.toexamine}
+                            </div>
+                            {if condition="$template.type eq '文生图'"}
+                                <a href="{:url('user/diagrams_list', ['id' => $template.id])}">
+                                    <img src="{$template.template_image_url}" alt="{$template.template_name}" onerror="this.src=''; this.alt='图片加载失败';">
+                                </a>
+                            {elseif condition="$template.type eq '文生视频'"}
+                                <a href="{:url('user/diagrams_list', ['id' => $template.id])}">
+                                    <video src="{$template.template_image_url}" alt="{$template.template_name}" controls muted></video>
+                                </a>
+                            {/if}
+                        </div>
+                        <div class="template-info">
+                            <div class="template-name">{$template.template_name}</div>
+                            <div class="template-meta">
+                                <span class="delete-btn" onclick="deleteDiagram({$template.id})">删除</span>
+                            </div>
+                        </div>
+                    </div>
+                    {/volist}
+
+                    <!-- 作品为空时的提示 -->
+                    {empty name="products"}
+                    <div class="empty-tip">
+                        <div class="empty-icon">📄</div>
+                        <div class="empty-text">您还没有作品</div>
+                        <div class="empty-subtext">快去发布您的第一个作品吧!</div>
+                    </div>
+                    {/empty}
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <script>
+        // 标签页切换事件
+        document.querySelectorAll('.tab-item').forEach(item => {
+            item.addEventListener('click', function() {
+                // 移除所有active类
+                document.querySelectorAll('.tab-item').forEach(tab => {
+                    tab.classList.remove('active');
+                });
+
+                // 为当前点击的标签页添加active类
+                this.classList.add('active');
+
+                // 这里可以添加切换标签页内容的逻辑
+                const tabText = this.textContent;
+                console.log('切换到:', tabText);
+            });
+        });
+
+        // 菜单点击事件处理
+    document.querySelectorAll('.menu-item a').forEach(item => {
+        item.addEventListener('click', function() {
+            // 移除所有active类
+            document.querySelectorAll('.menu-item').forEach(menu => {
+                menu.classList.remove('active');
+            });
+
+            // 为当前点击的菜单项添加active类
+            this.parentNode.classList.add('active');
+        });
+    });
+
+        // 媒体显示函数
+        function showMedia(url, type) {
+            // 这里可以根据需要实现媒体预览功能
+            // 例如:打开一个模态框显示大图或视频
+            console.log('显示媒体:', url, '类型:', type);
+
+            // 示例:创建一个简单的模态框
+            const modal = document.createElement('div');
+            modal.style.position = 'fixed';
+            modal.style.top = '0';
+            modal.style.left = '0';
+            modal.style.width = '100%';
+            modal.style.height = '100%';
+            modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
+            modal.style.display = 'flex';
+            modal.style.justifyContent = 'center';
+            modal.style.alignItems = 'center';
+            modal.style.zIndex = '10000';
+
+            if (type === '文生图') {
+                const img = document.createElement('img');
+                img.src = url;
+                img.style.maxWidth = '90%';
+                img.style.maxHeight = '90%';
+                modal.appendChild(img);
+            } else if (type === '文生视频') {
+                const video = document.createElement('video');
+                video.src = url;
+                video.controls = true;
+                video.style.maxWidth = '90%';
+                video.style.maxHeight = '90%';
+                modal.appendChild(video);
+            }
+
+            // 点击模态框关闭
+            modal.addEventListener('click', function() {
+                document.body.removeChild(modal);
+            });
+
+            document.body.appendChild(modal);
+        }
+
+        // 创建并显示自定义确认弹窗
+        function showConfirmDialog(message, onConfirm, onCancel) {
+            // 检查是否已存在弹窗,如果存在则移除
+            let existingDialog = document.getElementById('customConfirmDialog');
+            if (existingDialog) {
+                existingDialog.remove();
+            }
+
+            // 创建弹窗容器
+            const dialog = document.createElement('div');
+            dialog.id = 'customConfirmDialog';
+            dialog.style.cssText = `
+                position: fixed;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                background-color: rgba(0, 0, 0, 0.5);
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                z-index: 10000;
+            `;
+
+            // 创建弹窗内容
+            const dialogContent = document.createElement('div');
+            dialogContent.style.cssText = `
+                background-color: white;
+                border-radius: 8px;
+                padding: 24px;
+                min-width: 300px;
+                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+            `;
+
+            // 创建消息文本
+            const dialogMessage = document.createElement('div');
+            dialogMessage.textContent = message;
+            dialogMessage.style.cssText = `
+                font-size: 16px;
+                color: #333;
+                margin-bottom: 24px;
+                text-align: center;
+            `;
+
+            // 创建按钮容器
+            const dialogButtons = document.createElement('div');
+            dialogButtons.style.cssText = `
+                display: flex;
+                justify-content: center;
+                gap: 16px;
+            `;
+
+            // 创建取消按钮
+            const cancelBtn = document.createElement('button');
+            cancelBtn.textContent = '取消';
+            cancelBtn.style.cssText = `
+                padding: 8px 16px;
+                border: 1px solid #d9d9d9;
+                background-color: white;
+                color: #333;
+                border-radius: 4px;
+                cursor: pointer;
+                font-size: 14px;
+                transition: all 0.3s;
+            `;
+            cancelBtn.onmouseover = function() {
+                this.style.borderColor = '#40a9ff';
+                this.style.color = '#40a9ff';
+            };
+            cancelBtn.onmouseout = function() {
+                this.style.borderColor = '#d9d9d9';
+                this.style.color = '#333';
+            };
+            cancelBtn.onclick = function() {
+                dialog.remove();
+                if (onCancel) onCancel();
+            };
+
+            // 创建确认按钮
+            const confirmBtn = document.createElement('button');
+            confirmBtn.textContent = '确定';
+            confirmBtn.style.cssText = `
+                padding: 8px 16px;
+                border: 1px solid #ff4d4f;
+                background-color: #ff4d4f;
+                color: white;
+                border-radius: 4px;
+                cursor: pointer;
+                font-size: 14px;
+                transition: all 0.3s;
+            `;
+            confirmBtn.onmouseover = function() {
+                this.style.backgroundColor = '#ff7875';
+                this.style.borderColor = '#ff7875';
+            };
+            confirmBtn.onmouseout = function() {
+                this.style.backgroundColor = '#ff4d4f';
+                this.style.borderColor = '#ff4d4f';
+            };
+            confirmBtn.onclick = function() {
+                dialog.remove();
+                if (onConfirm) onConfirm();
+            };
+
+            // 组装弹窗
+            dialogButtons.appendChild(cancelBtn);
+            dialogButtons.appendChild(confirmBtn);
+            dialogContent.appendChild(dialogMessage);
+            dialogContent.appendChild(dialogButtons);
+            dialog.appendChild(dialogContent);
+
+            // 添加到页面
+            document.body.appendChild(dialog);
+
+            // 点击弹窗外部关闭
+            dialog.onclick = function(e) {
+                if (e.target === dialog) {
+                    dialog.remove();
+                    if (onCancel) onCancel();
+                }
+            };
+        }
+
+        // 创建并显示自定义提示框
+        function showAlert(message, type = 'info', duration = 3000) {
+            // 检查是否已存在提示框容器,如果不存在则创建
+            let alertElement = document.getElementById('customAlert');
+            if (alertElement) {
+                alertElement.remove();
+            }
+
+            // 创建提示框元素
+            alertElement = document.createElement('div');
+            alertElement.id = 'customAlert';
+
+            // 设置不同类型的样式
+            let backgroundColor;
+            switch (type) {
+                case 'success':
+                    backgroundColor = '#52c41a';
+                    break;
+                case 'error':
+                    backgroundColor = '#ff4d4f';
+                    break;
+                case 'warning':
+                    backgroundColor = '#faad14';
+                    break;
+                default:
+                    backgroundColor = '#1890ff';
+            }
+
+            // 设置样式
+            alertElement.style.cssText = `
+                position: fixed;
+                top: 20px;
+                left: 50%;
+                transform: translateX(-50%);
+                padding: 12px 20px;
+                background-color: ${backgroundColor};
+                color: white;
+                border-radius: 4px;
+                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+                z-index: 10001;
+                font-size: 14px;
+                max-width: 80%;
+                text-align: center;
+            `;
+
+            // 设置文本内容
+            alertElement.textContent = message;
+
+            // 添加到页面
+            document.body.appendChild(alertElement);
+
+            // 自动关闭
+            setTimeout(() => {
+                if (alertElement.parentNode) {
+                    alertElement.remove();
+                }
+            }, duration);
+        }
+
+        // 删除作品函数
+        function deleteDiagram(id) {
+            showConfirmDialog('确定要删除该作品吗?', function() {
+                // 发送Ajax请求到删除接口
+                fetch('{:url("user/diagrams_del")}', {
+                    method: 'POST',
+                    headers: {
+                        'Content-Type': 'application/x-www-form-urlencoded',
+                    },
+                    body: 'id=' + id
+                })
+                .then(response => response.json())
+                .then(data => {
+                    if (data.code === 0) {
+                        // 删除成功后显示提示并刷新页面
+                        showAlert('删除成功', 'success', 1500);
+                        setTimeout(() => {
+                            location.reload();
+                        }, 1500);
+                    } else {
+                        showAlert('删除失败: ' + data.msg, 'error');
+                    }
+                })
+                .catch(error => {
+                    console.error('删除请求失败:', error);
+                    showAlert('删除请求失败,请重试', 'error');
+                });
+            });
+        }
+    </script>

+ 276 - 0
application/index/view/user/diagrams_list.html

@@ -0,0 +1,276 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <title>作品明细 - 我的作品</title>
+    <style>
+        /* 主容器 - 左右布局 */
+        .user-diagrams-container {
+            display: flex;
+            min-height: calc(100vh - 120px); /* 减去导航栏和页脚高度 */
+        }
+
+        /* 左侧菜单样式 */
+        .sidebar {
+            width: 200px;
+            background-color: #fff;
+            border-right: 1px solid #e8e8e8;
+            flex-shrink: 0;
+        }
+
+        .menu {
+            padding: 20px 0;
+        }
+
+        .menu-item {
+            list-style: none;
+        }
+
+        .menu-item a {
+            display: block;
+            padding: 15px 20px;
+            text-decoration: none;
+            color: #000000;
+            font-size: 16px;
+            transition: all 0.3s ease;
+        }
+
+        .menu-item.active a {
+            background-color: #f0f7ff;
+            color: #1890ff;
+            font-weight: 500;
+        }
+
+        .menu-item:hover a {
+            background-color: #f5f5f5;
+            color: #1890ff;
+        }
+
+        /* 右侧内容区域样式 */
+        .diagrams-content {
+            flex: 1;
+            background-color: #fff;
+            padding: 20px;
+        }
+
+        /* 内容区域 */
+        .detail-content {
+            min-height: 500px;
+            border: 1px solid #e8e8e8;
+            border-radius: 4px;
+            padding: 20px;
+            display: flex;
+            gap: 20px;
+        }
+
+        /* 左侧媒体展示区域 */
+        .media-section {
+            flex: 1;
+            border: 1px solid #e8e8e8;
+            border-radius: 8px;
+            overflow: hidden;
+            background-color: #fafafa;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            padding: 20px;
+        }
+
+        .media-section img {
+            max-width: 100%;
+            max-height: 500px;
+            object-fit: contain;
+            border-radius: 4px;
+        }
+
+        .media-section video {
+            max-width: 100%;
+            max-height: 500px;
+            border-radius: 4px;
+        }
+
+        /* 右侧信息区域 */
+        .info-section {
+            width: 400px;
+            border: 1px solid #e8e8e8;
+            border-radius: 8px;
+            padding: 20px;
+            background-color: #fafafa;
+        }
+
+        .info-title {
+            font-size: 20px;
+            font-weight: 500;
+            margin-bottom: 20px;
+            padding-bottom: 10px;
+            border-bottom: 1px solid #e8e8e8;
+        }
+
+        .info-item {
+            margin-bottom: 15px;
+            display: flex;
+            align-items: center;
+        }
+
+        .info-label {
+            display: inline-block;
+            width: 80px;
+            font-weight: 500;
+            color: #333;
+            margin-right: 10px;
+        }
+
+        .info-value {
+            display: inline-block;
+            color: #666;
+            line-height: 1.5;
+            flex: 1;
+        }
+
+        /* 审核状态标识样式 - 与主页保持一致 */
+        .examine-status {
+            padding: 4px 12px;
+            border-radius: 4px;
+            font-size: 12px;
+            font-weight: 500;
+            color: #fff;
+            display: inline-block;
+        }
+
+        .examine-status.passed {
+            background-color: #52c41a;
+        }
+
+        .examine-status.failed {
+            background-color: #ff4d4f;
+        }
+
+        .examine-status.pending {
+            background-color: #faad14;
+        }
+
+        .chinese-description {
+            white-space: pre-wrap;
+            background-color: #fff;
+            border: 1px solid #e8e8e8;
+            border-radius: 4px;
+            padding: 15px;
+            min-height: 260px;
+            margin-top: 5px;
+        }
+
+        /* 返回按钮 */
+        .back-btn {
+            display: inline-block;
+            margin-bottom: 20px;
+            padding: 8px 16px;
+            background-color: #1890ff;
+            color: #fff;
+            border-radius: 4px;
+            text-decoration: none;
+            transition: all 0.3s ease;
+        }
+
+        .back-btn:hover {
+            background-color: #40a9ff;
+        }
+
+        /* 响应式设计 */
+        @media (max-width: 768px) {
+            .user-diagrams-container {
+                flex-direction: column;
+            }
+
+            .sidebar {
+                width: 100%;
+                border-right: none;
+                border-bottom: 1px solid #e8e8e8;
+            }
+
+            .menu {
+                padding: 0;
+            }
+
+            .menu-item {
+                display: inline-block;
+            }
+
+            .menu-item a {
+                padding: 12px 15px;
+            }
+
+            .detail-content {
+                flex-direction: column;
+            }
+
+            .info-section {
+                width: 100%;
+            }
+        }
+    </style>
+</head>
+<body>
+    <div class="user-diagrams-container">
+        <!-- 左侧菜单 -->
+        <div class="sidebar">
+            <ul class="menu">
+                <li class="menu-item">
+                    <a href="{:url('user/diagrams')}">我的作品</a>
+                </li>
+                <li class="menu-item">
+                    <a href="{:url('user/recycle')}">收回站</a>
+                </li>
+            </ul>
+        </div>
+
+        <!-- 右侧内容区域 -->
+        <div class="diagrams-content">
+            <!-- 返回按钮 -->
+            <a href="javascript:history.back()" class="back-btn">返回</a>
+
+            <!-- 内容区域 -->
+            <div class="detail-content">
+                <!-- 左侧媒体展示区域 -->
+                <div class="media-section">
+                    {if condition="$product.type eq '文生图'"}
+                        <img src="{$product.template_image_url}" alt="{$product.template_name}">
+                    {elseif condition="$product.type eq '文生视频'"}
+                        <video src="{$product.template_image_url}" controls></video>
+                    {/if}
+                </div>
+
+                <!-- 右侧信息区域 -->
+                <div class="info-section">
+                    <div class="info-title">模版信息</div>
+                    <div class="info-item">
+                        <span class="info-label">用户</span>
+                        <span class="info-value">{$user_info.nickname}</span>
+                    </div>
+                    <div class="info-item">
+                        <span class="info-label">模版名称</span>
+                        <span class="info-value">{$product.template_name}</span>
+                    </div>
+                    <div class="info-item">
+                        <span class="info-label">创建时间</span>
+                        <span class="info-value">{$product.create_time}</span>
+                    </div>
+                    <div class="info-item">
+                        <span class="info-label">审核状态</span>
+                        <span class="info-value">
+                            <span class="examine-status {if condition="$product.toexamine eq '审核通过'"}passed{elseif condition="$product.toexamine eq '未通过'"}failed{else}pending{/if}">
+                                {$product.toexamine}
+                            </span>
+                        </span>
+                    </div>
+                    <div class="info-item">
+                        <span class="info-label">提示词</span>
+                        <div class="info-value">
+                            <div class="chinese-description">{$product.chinese_description}</div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</body>
+</html>

+ 57 - 762
application/index/view/user/index.html

@@ -1,771 +1,66 @@
-<!doctype html>
-<html lang="zh-CN">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
-    <meta http-equiv="X-UA-Compatible" content="ie=edge">
-    <title>生成模板 - 文生图</title>
-    <!-- 引入Font Awesome图标 -->
-    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
-    <!-- 引入自定义CSS -->
-    <link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico"/>
-    <style>
-        /* 自定义提示框样式 */
-        .custom-alert {
-            position: fixed;
-            top: 10%;
-            left: 50%;
-            transform: translate(-50%, -50%);
-            padding: 15px 25px;
-            border-radius: 8px;
-            color: white;
-            font-size: 14px;
-            font-weight: 500;
-            z-index: 10000;
-            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
-            opacity: 0;
-            visibility: hidden;
-            transition: all 0.3s ease;
-            max-width: 80%;
-            text-align: center;
-        }
-        .custom-alert.show {
-            opacity: 1;
-            visibility: visible;
-        }
-        .custom-alert.error {
-            background-color: #e74c3c;
-        }
-        .custom-alert.success {
-            background-color: #28a745;
-        }
-        .custom-alert.warning {
-            background-color: #ffc107;
-            color: #333;
-        }
-        .custom-alert.info {
-            background-color: #17a2b8;
-        }
-
-        * {
-            margin: 0;
-            padding: 0;
-            box-sizing: border-box;
-        }
-        /* 标题样式 */
-        .page-title {
-            font-size: 24px;
-            font-weight: bold;
-            margin-bottom: 25px;
-            color: #333;
-        }
-        /* 内容区域 */
-        .content-area {
-            display: grid;
-            grid-template-columns: 1fr 1fr;
-            gap: 30px;
-        }
-        /* 左侧输入区域 */
-        .input-section {
-            background-color: #fff;
-            border-radius: 8px;
-            padding: 20px;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-        }
-        /* 右侧预览区域 */
-        .preview-section {
-            background-color: #fff;
-            border-radius: 8px;
-            padding: 20px;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-        }
-        /* 表单组样式 */
-        .form-group {
-            margin-bottom: 20px;
-        }
-        .form-group label {
-            display: block;
-            font-size: 14px;
-            font-weight: bold;
-            color: #333;
-            margin-bottom: 8px;
-        }
-        /* 文本输入区域 */
-        .prompt-textarea {
-            width: 100%;
-            height: 150px;
-            padding: 12px;
-            border: 1px solid #ddd;
-            border-radius: 8px;
-            resize: vertical;
-            font-size: 14px;
-            line-height: 1.5;
-        }
-        /* 参数设置区域 */
-        .params-grid {
-            display: grid;
-            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
-            gap: 15px;
-        }
-        .param-item {
-            margin-bottom: 15px;
-        }
-        .param-item label {
-            display: block;
-            font-size: 13px;
-            font-weight: bold;
-            color: #333;
-            margin-bottom: 5px;
-        }
-        .param-item select, .param-item input[type="number"] {
-            width: 100%;
-            padding: 8px 12px;
-            border: 1px solid #ddd;
-            border-radius: 4px;
-            font-size: 14px;
-        }
-        /* 提示词示例 */
-        .prompt-examples {
-            background-color: #f8f9fa;
-            border-radius: 8px;
-            padding: 15px;
-            margin-bottom: 20px;
-        }
-        .prompt-examples h4 {
-            font-size: 14px;
-            font-weight: bold;
-            margin-bottom: 10px;
-            color: #333;
-        }
-        .example-list {
-            display: flex;
-            flex-wrap: wrap;
-            gap: 8px;
-        }
-        .example-tag {
-            font-size: 12px;
-            background-color: #e9ecef;
-            color: #666;
-            padding: 4px 10px;
-            border-radius: 4px;
-            cursor: pointer;
-            transition: background-color 0.2s;
-        }
-        .example-tag:hover {
-            background-color: #dee2e6;
-        }
-        /* 按钮样式 */
-        .button-group {
-            display: flex;
-            gap: 10px;
-        }
-        .btn {
-            padding: 12px 24px;
-            border: none;
-            border-radius: 8px;
-            font-size: 14px;
-            cursor: pointer;
-            transition: background-color 0.2s;
-        }
-        .btn-primary {
-            background-color: #007bff;
-            color: #fff;
-        }
-        .btn-primary:hover {
-            background-color: #0056b3;
-        }
-        .btn-secondary {
-            background-color: #6c757d;
-            color: #fff;
-        }
-        .btn-secondary:hover {
-            background-color: #545b62;
-        }
-        /* 预览区域 */
-        .preview-container {
-            width: 100%;
-            min-height: 300px;
-            background-color: #f8f9fa;
-            border-radius: 8px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin-bottom: 20px;
-            overflow: hidden;
-        }
-        .preview-image {
-            max-width: 100%;
-            max-height: 100%;
-            object-fit: contain;
-        }
-        .preview-placeholder {
-            font-size: 14px;
-            color: #666;
-            text-align: center;
-        }
-        /* 模板信息 */
-        .template-info {
-            margin-bottom: 20px;
-        }
-        .template-info h4 {
-            font-size: 14px;
-            font-weight: bold;
-            margin-bottom: 10px;
-            color: #333;
-        }
-        .template-form input {
-            width: 100%;
-            padding: 10px 12px;
-            border: 1px solid #ddd;
-            border-radius: 8px;
-            font-size: 14px;
-            margin-bottom: 10px;
-        }
-        /* 响应式设计 */
-        @media (max-width: 768px) {
-            .content-area {
-                grid-template-columns: 1fr;
-            }
-            .clear-btn, .optimize-btn, .arrow-btn {
-                flex: 1;
-            }
-        }
-        .optimize-btn {
-            background-color: #ffffff;
-            color: #4b5563;
-            padding: 10px 18px;
-            border: 1px solid #d1d5db;
-            border-radius: 8px;
-            font-size: 14px;
-            font-weight: 500;
-            cursor: pointer;
-            transition: all 0.3s ease;
-            display: flex;
-            align-items: center;
-            gap: 6px;
-        }
-
-        .optimize-btn:hover {
-            background-color: #f9fafb;
-            border-color: #9ca3af;
-            transform: translateY(-1px);
-        }
-        .clear-btn {
-            background-color: #ffffff;
-            color: #dc3545;
-            border: 1px solid #f87171;
-            border-radius: 8px;
-            font-size: 14px;
-            font-weight: 500;
-            cursor: pointer;
-            transition: all 0.3s ease;
-            display: flex;
-            align-items: center;
-            gap: 6px;
-        }
-
-        .clear-btn:hover {
-            background-color: #fee2e2;
-            border-color: #ef4444;
-            transform: translateY(-1px);
-        }
-        /* 操作按钮 */
-            .prompt-actions {
-                gap: 8px;
-            }
-
-            .clear-btn, .optimize-btn {
-                padding: 8px 12px;
-                font-size: 13px;
-            }
-
-        /* 菜单样式 */
-        .menu-container {
-            background-color: #f5f7fa;
-            border-radius: 8px;
-            padding: 10px;
-            margin-bottom: 20px;
-            display: flex;
-            gap: 10px;
-        }
-
-        .menu-item {
-            flex: 1;
-        }
-
-        .menu-item a {
-            display: block;
-            padding: 12px;
-            background-color: white;
-            border: 1px solid #e1e8ed;
-            border-radius: 6px;
-            text-align: center;
-            text-decoration: none;
-            color: #657786;
-            font-size: 14px;
-            font-weight: 500;
-            transition: all 0.3s ease;
-        }
-
-        .menu-item a:hover {
-            background-color: #e8f0fe;
-            border-color: #1da1f2;
-            color: #1da1f2;
-        }
-
-        .menu-item.active a {
-            background-color: #1da1f2;
-            border-color: #1da1f2;
-            color: white;
-        }
-
-        .menu-item i {
-            margin-right: 6px;
-            font-size: 16px;
-        }
-    </style>
-</head>
-<body>
-    <div class="container">
-        <!-- 菜单功能区 -->
-        <div class="menu-container">
-            <div class="menu-item active">
-                <a href="{:url('user/index')}">
-                    <i class="fas fa-image"></i>
-                    文生图
-                </a>
-            </div>
-            <div class="menu-item">
-                <a href="{:url('user/text_to_video')}">
-                    <i class="fas fa-video"></i>
-                    文生视频
-                </a>
-            </div>
-
-        </div>
-
-        <div class="content-area">
-            <!-- 左侧输入区域 -->
-            <div class="input-section">
-                    <h3 style="font-size: 18px; font-weight: bold; margin-bottom: 15px; color: #333;">文生图生成参数设置</h3>
-
-                    <!-- 提示词示例 -->
-                    <div class="prompt-examples">
-                     <label for="prompt">提示词</label>
-                        <textarea id="prompt" class="prompt-textarea" placeholder="请输入您想要生成的图像描述,越详细越好..."></textarea>
-                    </div>
-
-                    <!-- 生成参数 -->
-                    <div class="form-group">
-                        <label>生成参数</label>
-                        <div class="params-grid">
-                            <div class="param-item">
-                                <label for="style">风格</label>
-                                <select id="style">
-                                    <option value="">默认</option>
-                                    <option value="anime">动漫</option>
-                                    <option value="oil">油画</option>
-                                    <option value="landscape">风景</option>
-                                    <option value="portrait">人像</option>
-                                </select>
-                            </div>
-                            <div class="param-item">
-                                <label for="imageSize">尺寸</label>
-                                <select id="imageSize">
-                                    <option value="1:1">1:1</option>
-                                    <option value="4:3">4:3</option>
-                                    <option value="3:4">3:4</option>
-                                    <option value="16:9">16:9</option>
-                                    <option value="9:16">9:16</option>
-                                </select>
+<style>
+    .basicinfo {
+        margin: 15px 0;
+    }
+
+    .basicinfo .row > .col-xs-4 {
+        padding-right: 0;
+    }
+
+    .basicinfo .row > div {
+        margin: 5px 0;
+    }
+</style>
+<div id="content-container" class="container">
+    <div class="row">
+        <div class="col-md-9">
+            <div class="panel panel-default">
+                <div class="panel-body">
+                    <h2 class="page-header">
+                        {:__('Member center')}
+                        <a href="{:url('user/profile')}" class="btn btn-primary pull-right"><i class="fa fa-pencil"></i> {:__('Profile')}</a>
+                    </h2>
+                    <div class="row user-baseinfo">
+                        <div class="col-md-3 col-sm-3 col-xs-3 text-center user-center">
+                            <a href="{:url('user/profile')}" title="{:__('Click to edit')}">
+                                <span class="avatar-img"><img src="{$user.avatar|htmlentities|cdnurl}" alt=""></span>
+                            </a>
+                        </div>
+                        <div class="col-md-9 col-sm-9 col-xs-9">
+                            <div class="ui-content">
+                                <h4><a href="{:url('user/profile')}">{$user.nickname|htmlentities}</a></h4>
+                                <p class="text-muted">
+                                    {$user.bio|default=__("This guy hasn't written anything yet")|htmlentities}
+                                </p>
                             </div>
                         </div>
-                    </div>
-
-                    <div class="button-group">
-                          <button class="clear-btn" onclick="clearPrompt()">
-                                <i class="fas fa-trash"></i>
-                                清空
-                            </button>
-                        <button class="optimize-btn" onclick="optimizePrompt()">
-                                <i class="fas fa-magic"></i>
-                                一键优化
-                            </button>
-                        <button class="btn btn-primary" id="generateBtn" onclick="generateImage()">
-                            <i class="fas fa-arrow-up"></i>
-                            生成图像
-                        </button>
-                    </div>
-            </div>
 
-            <!-- 右侧预览区域 -->
-            <div class="preview-section">
-                <h3 style="font-size: 18px; font-weight: bold; margin-bottom: 15px; color: #333;">图像预览</h3>
-
-                <!-- 预览容器 -->
-                <div id="imageResult" class="preview-container">
-                    <div class="preview-placeholder">
-                        <p>点击"生成图像"按钮开始创建您的模板</p>
-                        <p style="font-size: 12px; margin-top: 10px; color: #999;">生成时间可能需要几秒到几十秒不等</p>
-                    </div>
-                </div>
+                        <div class="col-md-9 col-sm-9 col-xs-12">
+                            <div class="ui-content">
+                                <div class="basicinfo">
+                                    <div class="row">
+                                        <div class="col-xs-4 col-md-2">{:__('Money')}</div>
+                                        <div class="col-xs-8 col-md-4">
+                                            <a href="javascript:;" class="viewmoney">{$user.money}</a>
+                                        </div>
+                                        <div class="col-xs-4 col-md-2">{:__('Score')}</div>
+                                        <div class="col-xs-8 col-md-4">
+                                            <a href="javascript:;" class="viewscore">{$user.score}</a>
+                                        </div>
+                                    </div>
+                                    <div class="row">
+                                        <div class="col-xs-4 col-md-2">{:__('Logintime')}</div>
+                                        <div class="col-xs-8 col-md-4">{$user.logintime|date="Y-m-d H:i:s",###}</div>
+                                        <div class="col-xs-4 col-md-2">{:__('Prevtime')}</div>
+                                        <div class="col-xs-8 col-md-4">{$user.prevtime|date="Y-m-d H:i:s",###}</div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
 
-                <!-- 模板信息 -->
-                <div class="template-info">
-                    <h4>模板信息</h4>
-                    <div class="template-form">
-                        <input type="text" id="templateName" placeholder="请输入模板名称">
                     </div>
                 </div>
-
-                <!-- 保存按钮 -->
-                <div class="button-group">
-                    <button class="btn btn-primary" id="saveBtn" disabled onclick="saveTemplate()">保存为模板</button>
-                    <button class="btn btn-secondary" id="downloadBtn" disabled onclick="downloadImage()">下载图像</button>
-                </div>
             </div>
         </div>
     </div>
-
-    <script>
-        // 自定义提示框函数
-        function showAlert(message, type = 'info', duration = 3000) {
-            // 检查是否已存在提示框容器,如果不存在则创建
-            let alertElement = document.getElementById('customAlert');
-            if (!alertElement) {
-                alertElement = document.createElement('div');
-                alertElement.id = 'customAlert';
-                alertElement.className = 'custom-alert';
-                document.body.appendChild(alertElement);
-            }
-            alertElement.textContent = message;
-            alertElement.className = `custom-alert ${type}`;
-            // 显示提示框
-            alertElement.classList.add('show');
-            // 自动隐藏
-            setTimeout(() => {
-                alertElement.classList.remove('show');
-            }, duration);
-        }
-
-        // 生成图片函数
-        function generateImage() {
-            const promptText = document.querySelector('.prompt-textarea').value.trim();
-            const imageStyle = document.getElementById('style').value;
-            const imageSize = document.getElementById('imageSize').value;
-            const imageResultDiv = document.getElementById('imageResult');
-
-            // 检查是否有提示词
-            if (!promptText) {
-                showAlert('请先输入图片描述', 'warning');
-                return;
-            }
-
-            // 显示加载状态
-            imageResultDiv.innerHTML = `
-                <div class="image-loading">
-                    <i class="fas fa-spinner fa-spin"></i>
-                    <p>正在生成图片,请稍候...</p>
-                    <p style="font-size: 12px; margin-top: 10px; color: #999;">生成时间可能需要几秒到几十秒不等</p>
-                </div>
-            `;
-
-            // 拼接风格和尺寸到提示词末尾
-            let fullPrompt = promptText;
-            if (imageStyle) {
-                fullPrompt += '风格:' + imageStyle;
-            }
-            if (imageSize) {
-                fullPrompt += '尺寸比例:' + imageSize;
-            }
-
-            // 发送请求到文生图接口
-            $.ajax({
-                url: '/index.php/api/work_order/GetTxtToImg',
-                type: 'POST',
-                dataType: 'json',
-                data: {
-                    status_val: '文生图',
-                    prompt: fullPrompt,
-                    model: 'gemini-3-pro-image-preview',
-                    style: imageStyle,
-                    size: imageSize
-                },
-                success: function(response) {
-                    // 处理成功响应
-                    if (response.code === 0 && response.data && response.data.url) {
-                        // 显示生成的图片
-                        imageResultDiv.innerHTML = `
-                            <div class="image-container">
-                                <img src="${response.data.url}" alt="生成的图片" class="generated-image" id="previewImage" style="max-width: 100%; height: auto; max-height: 600px; cursor: pointer;">
-                            </div>
-                        `;
-
-                        // 启用下载和保存按钮
-                        document.getElementById('downloadBtn').disabled = false;
-                        document.getElementById('saveBtn').disabled = false;
-
-                        // 添加图片放大模态框(如果还不存在)
-                        if (!document.getElementById('imageModal')) {
-                            const modal = document.createElement('div');
-                            modal.id = 'imageModal';
-                            modal.style.cssText = `
-                                display: none;
-                                position: fixed;
-                                z-index: 9999;
-                                left: 0;
-                                top: 0;
-                                width: 100%;
-                                height: 100%;
-                                overflow: auto;
-                                background-color: rgba(0, 0, 0, 0.9);
-                                justify-content: center;
-                                align-items: center;
-                            `;
-                            modal.style.display = 'flex';
-                            modal.style.display = 'none';
-
-                            const modalContent = document.createElement('img');
-                            modalContent.id = 'modalImage';
-                            modalContent.style.cssText = `
-                                max-width: 90%;
-                                max-height: 90%;
-                                margin: auto;
-                            `;
-
-                            const closeBtn = document.createElement('span');
-                            closeBtn.innerHTML = '&times;';
-                            closeBtn.style.cssText = `
-                                position: absolute;
-                                top: 20px;
-                                right: 35px;
-                                color: #f1f1f1;
-                                font-size: 40px;
-                                font-weight: bold;
-                                transition: 0.3s;
-                                cursor: pointer;
-                            `;
-
-                            closeBtn.onclick = function() {
-                                modal.style.display = 'none';
-                            };
-
-                            modal.appendChild(closeBtn);
-                            modal.appendChild(modalContent);
-                            document.body.appendChild(modal);
-
-                            // 点击模态框背景关闭
-                            modal.onclick = function(event) {
-                                if (event.target.id === 'imageModal') {
-                                    this.style.display = 'none';
-                                }
-                            };
-                        }
-
-                        // 为生成的图片添加点击事件
-                        const generatedImage = imageResultDiv.querySelector('.generated-image');
-                        generatedImage.onclick = function() {
-                            const modal = document.getElementById('imageModal');
-                            const modalImage = document.getElementById('modalImage');
-                            modalImage.src = this.src;
-                            modal.style.display = 'flex';
-                        };
-
-                        // 键盘ESC键关闭
-                        document.addEventListener('keydown', function(event) {
-                            if (event.key === 'Escape') {
-                                const modal = document.getElementById('imageModal');
-                                if (modal && modal.style.display === 'flex') {
-                                    modal.style.display = 'none';
-                                }
-                            }
-                        });
-                    } else {
-                        // 显示错误信息
-                        imageResultDiv.innerHTML = `
-                            <div class="image-error">
-                                <i class="fas fa-exclamation-triangle"></i>
-                                <p>图片生成失败:${response.msg || '未知错误'}</p>
-                            </div>
-                        `;
-                    }
-                },
-                error: function(xhr, status, error) {
-                    // 处理网络错误
-                    imageResultDiv.innerHTML = `
-                        <div class="image-error">
-                            <i class="fas fa-exclamation-triangle"></i>
-                            <p>图像生成失败</p>
-                        </div>
-                    `;
-                }
-            });
-        }
-
-         // 一键优化提示词功能
-        function optimizePrompt() {
-            const textarea = document.querySelector('.prompt-textarea');
-            const optimizeBtn = document.querySelector('.optimize-btn');
-
-            if (textarea && textarea.value.trim() !== '') {
-                // 显示加载状态
-                const originalBtnText = optimizeBtn.innerHTML;
-                optimizeBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 优化中...';
-                optimizeBtn.disabled = true;
-
-                // 构造请求参数
-                const params = {
-                    status_val: '文生文',
-                    prompt: textarea.value,
-                    model: 'gemini-2.0-flash'
-                };
-
-                // 发送AJAX请求
-                $.ajax({
-                    url: '/index.php/api/work_order/GetTxtToTxt',
-                    type: 'POST',
-                    data: params,
-                    dataType: 'json',
-                    success: function(data) {
-                        console.log(data);
-                        // 恢复按钮状态
-                        optimizeBtn.innerHTML = originalBtnText;
-                        optimizeBtn.disabled = false;
-
-                        // 优化成功,更新文本框内容
-                        textarea.value = data.content;
-                        textarea.scrollTop = textarea.scrollHeight;
-                        updateCharCount();
-
-                        // 显示优化成功提示
-                        const alert = document.createElement('div');
-                        alert.className = 'alert alert-success';
-                        alert.innerHTML = '提示词已优化!';
-                        alert.style.position = 'fixed';
-                        alert.style.top = '20px';
-                        alert.style.right = '20px';
-                        alert.style.zIndex = '9999';
-                        document.body.appendChild(alert);
-
-                        // 3秒后移除提示
-                        setTimeout(() => {
-                            alert.remove();
-                        }, 3000);
-
-                    }
-                });
-            } else {
-                showAlert('请先输入提示词!', 'warning');
-            }
-        }
-
-        // 清空提示词功能
-        function clearPrompt() {
-            const textarea = document.querySelector('.prompt-textarea');
-            if (textarea) {
-                textarea.value = '';
-                textarea.focus();
-            }
-        }
-
-
-        // 保存模板函数
-        function saveTemplate() {
-            // 获取所有需要的参数
-            const templateName = document.getElementById('templateName').value;
-            const prompt = document.getElementById('prompt').value.trim();
-            const style = document.getElementById('style').value;
-            const imageSize = document.getElementById('imageSize').value;
-            const previewImage = document.getElementById('previewImage');
-            
-            // 验证必填项
-            if (!templateName.trim()) {
-                showAlert('请输入模板名称', 'error');
-                return;
-            }
-            
-            if (!prompt) {
-                showAlert('请输入提示词', 'error');
-                return;
-            }
-            
-            if (!previewImage || !previewImage.src) {
-                showAlert('请先生成图片', 'error');
-                return;
-            }
-            
-            // 准备请求参数
-            // 将完整URL转换为相对路径
-            let imageUrl = previewImage.src;
-            try {
-                const url = new URL(imageUrl);
-                imageUrl = url.pathname;
-            } catch (e) {
-                // 如果已经是相对路径,直接使用
-            }
-            
-            const params = {
-                chinese_description: prompt,
-                template_image_url: imageUrl,
-                template_name: templateName,
-                style: style,
-                size: imageSize,
-                type: '文生图' // 固定为文生图类型
-            };
-            
-            // 显示加载状态
-            const saveBtn = document.getElementById('saveBtn');
-            const originalText = saveBtn.innerHTML;
-            saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 保存中...';
-            saveBtn.disabled = true;
-            
-            // 发送AJAX请求
-            $.ajax({
-                url: '/index.php/api/work_order/Add_Product_Template',
-                type: 'POST',
-                dataType: 'json',
-                data: params,
-                success: function(response) {
-                    if (response.code === 0) {
-                        showAlert('模板保存成功!', 'success');
-                        // 清空模板名称输入框
-                        document.getElementById('templateName').value = '';
-                    } else {
-                        showAlert('模板保存失败:' + (response.msg || '未知错误'), 'error');
-                    }
-                },
-                error: function(xhr, status, error) {
-                    console.error('AJAX请求失败:', error);
-                    showAlert('网络错误,模板保存失败', 'error');
-                },
-                complete: function() {
-                    // 恢复按钮状态
-                    saveBtn.innerHTML = originalText;
-                    saveBtn.disabled = false;
-                }
-            });
-        }
-
-        // 下载图像函数
-        function downloadImage() {
-            const previewImage = document.getElementById('previewImage');
-            if (previewImage && previewImage.src) {
-                // 创建临时链接下载图片
-                const link = document.createElement('a');
-                link.href = previewImage.src;
-
-                // 生成更有意义的文件名
-                const timestamp = new Date().getTime();
-                const promptText = document.querySelector('.prompt-textarea').value.trim();
-                // 从提示词中提取前20个字符作为文件名的一部分
-                const promptPart = promptText.substring(0, 20).replace(/[^\w\u4e00-\u9fa5]/g, '') || 'image';
-                // 组合文件名:提示词部分_时间戳.jpg
-                const fileName = `${promptPart}_${timestamp}.jpg`;
-
-                link.download = fileName;
-                link.click();
-            }
-        }
-    </script>
-</body>
-</html>
+</div>

+ 634 - 0
application/index/view/user/recycle.html

@@ -0,0 +1,634 @@
+<style>
+    /* 主容器 - 左右布局 */
+    .user-diagrams-container {
+        display: flex;
+        min-height: calc(100vh - 120px); /* 减去导航栏和页脚高度 */
+    }
+
+    /* 左侧菜单样式 */
+    .sidebar {
+        width: 200px;
+        background-color: #fff;
+        border-right: 1px solid #e8e8e8;
+        flex-shrink: 0;
+    }
+
+    .menu {
+        padding: 20px 0;
+    }
+
+    .menu-item {
+        list-style: none;
+    }
+
+    .menu-item a {
+        display: block;
+        padding: 15px 20px;
+        text-decoration: none;
+        color: #000000;
+        font-size: 16px;
+        transition: all 0.3s ease;
+    }
+
+    .menu-item.active a {
+        background-color: #f0f7ff;
+        color: #1890ff;
+        font-weight: 500;
+    }
+
+    .menu-item:hover a {
+        background-color: #f5f5f5;
+        color: #1890ff;
+    }
+
+    /* 右侧内容区域样式 */
+    .diagrams-content {
+        flex: 1;
+        background-color: #fff;
+        padding: 20px;
+    }
+
+    /* 标签页样式 */
+    .tabs {
+        margin-bottom: 20px;
+    }
+
+    .tab-item {
+        display: inline-block;
+        margin-right: 20px;
+        padding: 10px 0;
+        font-size: 16px;
+        color: #1890ff;
+        cursor: pointer;
+        border-bottom: 2px solid transparent;
+        transition: all 0.3s ease;
+    }
+
+    .tab-item.active {
+        font-weight: 500;
+        border-bottom-color: #1890ff;
+    }
+
+    .tab-item:hover {
+        color: #40a9ff;
+    }
+
+    /* 内容区域 */
+    .tab-content {
+        min-height: 400px;
+        border: 1px solid #e8e8e8;
+        border-radius: 4px;
+        padding: 20px;
+    }
+
+    /* 模板网格样式 */
+    .template-grid {
+        display: grid;
+        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+        gap: 20px;
+    }
+
+    .template-card {
+        border: 1px solid #e8e8e8;
+        border-radius: 8px;
+        overflow: hidden;
+        transition: all 0.3s ease;
+        cursor: pointer;
+    }
+
+    .template-card:hover {
+        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+        transform: translateY(-2px);
+    }
+
+    .template-thumbnail {
+        width: 100%;
+        height: 160px;
+        overflow: hidden;
+        background-color: #f5f5f5;
+        position: relative;
+    }
+
+    /* 审核状态标识样式 */
+    .examine-status {
+        position: absolute;
+        top: 8px;
+        right: 8px;
+        padding: 4px 12px;
+        border-radius: 4px;
+        font-size: 12px;
+        font-weight: 500;
+        color: #fff;
+        z-index: 10;
+    }
+
+    .examine-status.passed {
+        background-color: #52c41a;
+    }
+
+    .examine-status.failed {
+        background-color: #ff4d4f;
+    }
+
+    .examine-status.pending {
+        background-color: #faad14;
+    }
+
+    .template-thumbnail img,
+    .template-thumbnail video {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+        transition: transform 0.3s ease;
+    }
+
+    .template-card:hover .template-thumbnail img,
+    .template-card:hover .template-thumbnail video {
+        transform: scale(1.05);
+    }
+
+    .template-info {
+        padding: 15px;
+    }
+
+    .template-name {
+        font-size: 16px;
+        font-weight: 500;
+        margin-bottom: 8px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+
+    .template-meta {
+        font-size: 14px;
+        color: #666;
+    }
+
+    .template-meta span {
+        margin-right: 15px;
+    }
+
+    /* 删除按钮样式 */
+    .delete-btn {
+        color: #ff4d4f;
+        cursor: pointer;
+        transition: color 0.3s ease;
+        margin-left: 10px;
+    }
+
+    .delete-btn:hover {
+        color: #ff7875;
+        text-decoration: underline;
+    }
+    
+    /* 恢复按钮样式 */
+    .restore-btn {
+        color: #52c41a;
+        cursor: pointer;
+        transition: color 0.3s ease;
+    }
+
+    .restore-btn:hover {
+        color: #73d13d;
+        text-decoration: underline;
+    }
+
+    /* 空提示样式 */
+    .empty-tip {
+        grid-column: 1 / -1;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        min-height: 400px;
+        text-align: center;
+        padding: 40px 20px;
+        color: #999;
+    }
+
+    .empty-icon {
+        font-size: 64px;
+        margin-bottom: 20px;
+        opacity: 0.5;
+    }
+
+    .empty-text {
+        font-size: 20px;
+        font-weight: 500;
+        margin-bottom: 10px;
+        color: #666;
+    }
+
+    .empty-subtext {
+        font-size: 14px;
+        color: #999;
+    }
+
+    /* 响应式设计 */
+    @media (max-width: 768px) {
+        .user-diagrams-container {
+            flex-direction: column;
+        }
+
+        .sidebar {
+            width: 100%;
+            border-right: none;
+            border-bottom: 1px solid #e8e8e8;
+        }
+
+        .menu {
+            padding: 0;
+        }
+
+        .menu-item {
+            display: inline-block;
+        }
+
+        .menu-item a {
+            padding: 12px 15px;
+        }
+    }
+</style>
+
+<div class="user-diagrams-container">
+    <!-- 左侧菜单 -->
+    <div class="sidebar">
+        <ul class="menu">
+            <li class="menu-item">
+                <a href="{:url('user/diagrams')}">我的作品</a>
+            </li>
+            <li class="menu-item active">
+                <a href="{:url('user/recycle')}">收回站</a>
+            </li>
+        </ul>
+    </div>
+
+    <!-- 右侧内容区域 -->
+    <div class="diagrams-content">
+        <!-- 标签页 -->
+        <div class="tabs">
+            <div class="tab-item active">回收站</div>
+        </div>
+
+        <!-- 内容区域 -->
+        <div class="tab-content">
+            <div class="template-grid" id="templateGrid">
+                <!-- 使用volist标签循环显示模板 -->
+                {volist name="products" id="template"}
+                <div class="template-card">
+                    <div class="template-thumbnail">
+                        <!-- 审核状态标识 -->
+                        <div class="examine-status {if condition="$template.toexamine eq '审核通过'"}passed{elseif condition="$template.toexamine eq '未通过'"}failed{else}pending{/if}">
+                        {$template.toexamine}
+                    </div>
+                    {if condition="$template.type eq '文生图'"}
+                    <a href="{:url('user/diagrams_list', ['id' => $template.id])}">
+                        <img src="{$template.template_image_url}" alt="{$template.template_name}" onerror="this.src=''; this.alt='图片加载失败';">
+                    </a>
+                    {elseif condition="$template.type eq '文生视频'"}
+                    <a href="{:url('user/diagrams_list', ['id' => $template.id])}">
+                        <video src="{$template.template_image_url}" alt="{$template.template_name}" controls muted></video>
+                    </a>
+                    {/if}
+                </div>
+                <div class="template-info">
+                    <div class="template-name">{$template.template_name}</div>
+                    <div class="template-meta">
+                        <span class="restore-btn" onclick="restoreDiagram({$template.id})">恢复</span>
+                        <span class="delete-btn" onclick="deleteDiagram({$template.id})">彻底删除</span>
+                    </div>
+                </div>
+            </div>
+            {/volist}
+
+            <!-- 作品为空时的提示 -->
+            {empty name="products"}
+            <div class="empty-tip">
+                <div class="empty-icon">📄</div>
+                <div class="empty-text">回收站空的</div>
+            </div>
+            {/empty}
+        </div>
+    </div>
+</div>
+
+<script>
+    // 标签页切换事件
+    document.querySelectorAll('.tab-item').forEach(item => {
+        item.addEventListener('click', function() {
+            // 移除所有active类
+            document.querySelectorAll('.tab-item').forEach(tab => {
+                tab.classList.remove('active');
+            });
+
+            // 为当前点击的标签页添加active类
+            this.classList.add('active');
+
+            // 这里可以添加切换标签页内容的逻辑
+            const tabText = this.textContent;
+            console.log('切换到:', tabText);
+        });
+    });
+
+    // 菜单点击切换事件
+    document.querySelectorAll('.menu-item a').forEach(item => {
+        item.addEventListener('click', function(e) {
+            // 移除所有active类
+            document.querySelectorAll('.menu-item').forEach(menu => {
+                menu.classList.remove('active');
+            });
+
+            // 为当前点击的菜单项添加active类
+            this.parentNode.classList.add('active');
+
+            // 这里可以添加切换菜单内容的逻辑
+            const menuText = this.textContent;
+            console.log('切换到:', menuText);
+        });
+    });
+
+    // 媒体显示函数
+    function showMedia(url, type) {
+        // 这里可以根据需要实现媒体预览功能
+        // 例如:打开一个模态框显示大图或视频
+        console.log('显示媒体:', url, '类型:', type);
+
+        // 示例:创建一个简单的模态框
+        const modal = document.createElement('div');
+        modal.style.position = 'fixed';
+        modal.style.top = '0';
+        modal.style.left = '0';
+        modal.style.width = '100%';
+        modal.style.height = '100%';
+        modal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
+        modal.style.display = 'flex';
+        modal.style.justifyContent = 'center';
+        modal.style.alignItems = 'center';
+        modal.style.zIndex = '10000';
+
+        if (type === '文生图') {
+            const img = document.createElement('img');
+            img.src = url;
+            img.style.maxWidth = '90%';
+            img.style.maxHeight = '90%';
+            modal.appendChild(img);
+        } else if (type === '文生视频') {
+            const video = document.createElement('video');
+            video.src = url;
+            video.controls = true;
+            video.style.maxWidth = '90%';
+            video.style.maxHeight = '90%';
+            modal.appendChild(video);
+        }
+
+        // 点击模态框关闭
+        modal.addEventListener('click', function() {
+            document.body.removeChild(modal);
+        });
+
+        document.body.appendChild(modal);
+    }
+
+    // 创建并显示自定义确认弹窗
+    function showConfirmDialog(message, onConfirm, onCancel) {
+        // 检查是否已存在弹窗,如果存在则移除
+        let existingDialog = document.getElementById('customConfirmDialog');
+        if (existingDialog) {
+            existingDialog.remove();
+        }
+
+        // 创建弹窗容器
+        const dialog = document.createElement('div');
+        dialog.id = 'customConfirmDialog';
+        dialog.style.cssText = `
+                position: fixed;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                background-color: rgba(0, 0, 0, 0.5);
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                z-index: 10000;
+            `;
+
+        // 创建弹窗内容
+        const dialogContent = document.createElement('div');
+        dialogContent.style.cssText = `
+                background-color: white;
+                border-radius: 8px;
+                padding: 24px;
+                min-width: 300px;
+                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+            `;
+
+        // 创建消息文本
+        const dialogMessage = document.createElement('div');
+        dialogMessage.textContent = message;
+        dialogMessage.style.cssText = `
+                font-size: 16px;
+                color: #333;
+                margin-bottom: 24px;
+                text-align: center;
+            `;
+
+        // 创建按钮容器
+        const dialogButtons = document.createElement('div');
+        dialogButtons.style.cssText = `
+                display: flex;
+                justify-content: center;
+                gap: 16px;
+            `;
+
+        // 创建取消按钮
+        const cancelBtn = document.createElement('button');
+        cancelBtn.textContent = '取消';
+        cancelBtn.style.cssText = `
+                padding: 8px 16px;
+                border: 1px solid #d9d9d9;
+                background-color: white;
+                color: #333;
+                border-radius: 4px;
+                cursor: pointer;
+                font-size: 14px;
+                transition: all 0.3s;
+            `;
+        cancelBtn.onmouseover = function() {
+            this.style.borderColor = '#40a9ff';
+            this.style.color = '#40a9ff';
+        };
+        cancelBtn.onmouseout = function() {
+            this.style.borderColor = '#d9d9d9';
+            this.style.color = '#333';
+        };
+        cancelBtn.onclick = function() {
+            dialog.remove();
+            if (onCancel) onCancel();
+        };
+
+        // 创建确认按钮
+        const confirmBtn = document.createElement('button');
+        confirmBtn.textContent = '确定';
+        confirmBtn.style.cssText = `
+                padding: 8px 16px;
+                border: 1px solid #ff4d4f;
+                background-color: #ff4d4f;
+                color: white;
+                border-radius: 4px;
+                cursor: pointer;
+                font-size: 14px;
+                transition: all 0.3s;
+            `;
+        confirmBtn.onmouseover = function() {
+            this.style.backgroundColor = '#ff7875';
+            this.style.borderColor = '#ff7875';
+        };
+        confirmBtn.onmouseout = function() {
+            this.style.backgroundColor = '#ff4d4f';
+            this.style.borderColor = '#ff4d4f';
+        };
+        confirmBtn.onclick = function() {
+            dialog.remove();
+            if (onConfirm) onConfirm();
+        };
+
+        // 组装弹窗
+        dialogButtons.appendChild(cancelBtn);
+        dialogButtons.appendChild(confirmBtn);
+        dialogContent.appendChild(dialogMessage);
+        dialogContent.appendChild(dialogButtons);
+        dialog.appendChild(dialogContent);
+
+        // 添加到页面
+        document.body.appendChild(dialog);
+
+        // 点击弹窗外部关闭
+        dialog.onclick = function(e) {
+            if (e.target === dialog) {
+                dialog.remove();
+                if (onCancel) onCancel();
+            }
+        };
+    }
+
+    // 创建并显示自定义提示框
+    function showAlert(message, type = 'info', duration = 3000) {
+        // 检查是否已存在提示框容器,如果不存在则创建
+        let alertElement = document.getElementById('customAlert');
+        if (alertElement) {
+            alertElement.remove();
+        }
+
+        // 创建提示框元素
+        alertElement = document.createElement('div');
+        alertElement.id = 'customAlert';
+
+        // 设置不同类型的样式
+        let backgroundColor;
+        switch (type) {
+            case 'success':
+                backgroundColor = '#52c41a';
+                break;
+            case 'error':
+                backgroundColor = '#ff4d4f';
+                break;
+            case 'warning':
+                backgroundColor = '#faad14';
+                break;
+            default:
+                backgroundColor = '#1890ff';
+        }
+
+        // 设置样式
+        alertElement.style.cssText = `
+                position: fixed;
+                top: 20px;
+                left: 50%;
+                transform: translateX(-50%);
+                padding: 12px 20px;
+                background-color: ${backgroundColor};
+                color: white;
+                border-radius: 4px;
+                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+                z-index: 10001;
+                font-size: 14px;
+                max-width: 80%;
+                text-align: center;
+            `;
+
+        // 设置文本内容
+        alertElement.textContent = message;
+
+        // 添加到页面
+        document.body.appendChild(alertElement);
+
+        // 自动关闭
+        setTimeout(() => {
+            if (alertElement.parentNode) {
+                alertElement.remove();
+            }
+        }, duration);
+    }
+
+    // 恢复作品函数
+    function restoreDiagram(id) {
+        showConfirmDialog('确定要恢复该作品吗?', function() {
+            // 发送Ajax请求到恢复接口
+            fetch('{:url("user/diagrams_restore")}', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/x-www-form-urlencoded',
+                },
+                body: 'id=' + id
+            })
+                .then(response => response.json())
+                .then(data => {
+                    if (data.code === 0) {
+                        // 恢复成功后显示提示并刷新页面
+                        showAlert('恢复成功', 'success', 1500);
+                        setTimeout(() => {
+                            location.reload();
+                        }, 1500);
+                    } else {
+                        showAlert('恢复失败: ' + data.msg, 'error');
+                    }
+                })
+                .catch(error => {
+                    console.error('恢复请求失败:', error);
+                    showAlert('恢复请求失败,请重试', 'error');
+                });
+        });
+    }
+    
+    // 删除作品函数 - 彻底删除
+    function deleteDiagram(id) {
+        showConfirmDialog('确定要彻底删除该作品吗?删除后将无法恢复!', function() {
+            // 发送Ajax请求到删除接口
+            fetch('{:url("user/diagrams_delete")}', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/x-www-form-urlencoded',
+                },
+                body: 'id=' + id
+            })
+                .then(response => response.json())
+                .then(data => {
+                    if (data.code === 0) {
+                        // 删除成功后显示提示并刷新页面
+                        showAlert('删除成功', 'success', 1500);
+                        setTimeout(() => {
+                            location.reload();
+                        }, 1500);
+                    } else {
+                        showAlert('删除失败: ' + data.msg, 'error');
+                    }
+                })
+                .catch(error => {
+                    console.error('删除请求失败:', error);
+                    showAlert('删除请求失败,请重试', 'error');
+                });
+        });
+    }
+</script>

+ 62 - 50
application/index/view/user/template.html

@@ -159,38 +159,47 @@
             color: #999;
         }
         
-        /* 放大模态框样式 */
-        .modal {
+        /* 图片放大样式 */
+        .template-thumbnail {
+            position: relative;
+            overflow: hidden;
+        }
+        .template-thumbnail img,
+        .template-thumbnail video {
+            width: 100%;
+            height: auto;
+            cursor: pointer;
+        }
+        /* 放大查看容器 */
+        #largeViewContainer {
             display: none;
             position: fixed;
-            z-index: 9999;
-            left: 0;
             top: 0;
-            width: 100%;
-            height: 100%;
-            background-color: rgba(0, 0, 0, 0.8);
-            overflow: auto;
+            left: 0;
+            width: 100vw;
+            height: 100vh;
+            background-color: rgba(0, 0, 0, 0.9);
+            z-index: 9999;
+            justify-content: center;
+            align-items: center;
+            overflow: hidden;
         }
-        .modal-content {
-            position: relative;
-            margin: 5% auto;
-            max-width: 90%;
-            max-height: 90%;
+        #largeViewContainer img,
+        #largeViewContainer video {
+            max-width: 90vw;
+            max-height: 90vh;
+            object-fit: contain;
         }
-        .modal-content img,
-        .modal-content video {
+        /* 背景遮罩 */
+        .overlay {
+            display: none;
+            position: fixed;
+            top: 0;
+            left: 0;
             width: 100%;
             height: 100%;
-            object-fit: contain;
-        }
-        .close-modal {
-            position: absolute;
-            top: -40px;
-            right: 0;
-            color: white;
-            font-size: 35px;
-            font-weight: bold;
-            cursor: pointer;
+            background-color: rgba(0, 0, 0, 0.7);
+            z-index: 9998;
         }
     </style>
 </head>
@@ -248,12 +257,9 @@
         </div>
     </section>
     
-    <!-- 放大模态框 -->
-    <div id="mediaModal" class="modal">
-        <span class="close-modal" onclick="closeModal()">&times;</span>
-        <div class="modal-content">
-            <div id="modalMediaContainer"></div>
-        </div>
+    <!-- 大图查看容器 -->
+    <div id="largeViewContainer">
+        <div id="largeMediaContent"></div>
     </div>
     
     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
@@ -380,44 +386,50 @@
             searchTimer = setTimeout(searchTemplates, 300);
         });
         
-        // 显示媒体放大模态框
+        // 图片/视频放大查看功能
         function showMedia(url, type) {
-            const modal = document.getElementById('mediaModal');
-            const container = document.getElementById('modalMediaContainer');
+            const container = document.getElementById('largeViewContainer');
+            const content = document.getElementById('largeMediaContent');
             
             // 清空容器
-            container.innerHTML = '';
+            content.innerHTML = '';
             
             // 创建媒体元素
             if (type === '文生图') {
                 const img = document.createElement('img');
                 img.src = url;
-                img.alt = '放大图片';
-                container.appendChild(img);
+                img.alt = '大图查看';
+                content.appendChild(img);
             } else if (type === '文生视频') {
                 const video = document.createElement('video');
                 video.src = url;
                 video.controls = true;
-                container.appendChild(video);
+                content.appendChild(video);
             }
             
-            // 显示模态框
-            modal.style.display = 'block';
+            // 显示大图查看容器
+            container.style.display = 'flex';
         }
         
-        // 关闭模态框
-        function closeModal() {
-            const modal = document.getElementById('mediaModal');
-            modal.style.display = 'none';
+        // 关闭大图查看
+        function closeLargeView() {
+            document.getElementById('largeViewContainer').style.display = 'none';
         }
         
-        // 点击模态框外部关闭
-        window.onclick = function(event) {
-            const modal = document.getElementById('mediaModal');
-            if (event.target === modal) {
-                closeModal();
+        // 点击大图容器关闭
+        document.getElementById('largeViewContainer').addEventListener('click', function(event) {
+            // 只有点击容器本身才关闭,避免点击媒体元素也关闭
+            if (event.target === this) {
+                closeLargeView();
             }
-        }
+        });
+        
+        // 按ESC键关闭大图查看
+        document.addEventListener('keydown', function(event) {
+            if (event.key === 'Escape') {
+                closeLargeView();
+            }
+        });
     </script>
 </body>
 </html>

+ 771 - 0
application/index/view/user/text_to_image.html

@@ -0,0 +1,771 @@
+<!doctype html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>生成模板 - 文生图</title>
+    <!-- 引入Font Awesome图标 -->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
+    <!-- 引入自定义CSS -->
+    <link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico"/>
+    <style>
+        /* 自定义提示框样式 */
+        .custom-alert {
+            position: fixed;
+            top: 10%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+            padding: 15px 25px;
+            border-radius: 8px;
+            color: white;
+            font-size: 14px;
+            font-weight: 500;
+            z-index: 10000;
+            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
+            opacity: 0;
+            visibility: hidden;
+            transition: all 0.3s ease;
+            max-width: 80%;
+            text-align: center;
+        }
+        .custom-alert.show {
+            opacity: 1;
+            visibility: visible;
+        }
+        .custom-alert.error {
+            background-color: #e74c3c;
+        }
+        .custom-alert.success {
+            background-color: #28a745;
+        }
+        .custom-alert.warning {
+            background-color: #ffc107;
+            color: #333;
+        }
+        .custom-alert.info {
+            background-color: #17a2b8;
+        }
+
+        * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+        }
+        /* 标题样式 */
+        .page-title {
+            font-size: 24px;
+            font-weight: bold;
+            margin-bottom: 25px;
+            color: #333;
+        }
+        /* 内容区域 */
+        .content-area {
+            display: grid;
+            grid-template-columns: 1fr 1fr;
+            gap: 30px;
+        }
+        /* 左侧输入区域 */
+        .input-section {
+            background-color: #fff;
+            border-radius: 8px;
+            padding: 20px;
+            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+        }
+        /* 右侧预览区域 */
+        .preview-section {
+            background-color: #fff;
+            border-radius: 8px;
+            padding: 20px;
+            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+        }
+        /* 表单组样式 */
+        .form-group {
+            margin-bottom: 20px;
+        }
+        .form-group label {
+            display: block;
+            font-size: 14px;
+            font-weight: bold;
+            color: #333;
+            margin-bottom: 8px;
+        }
+        /* 文本输入区域 */
+        .prompt-textarea {
+            width: 100%;
+            height: 150px;
+            padding: 12px;
+            border: 1px solid #ddd;
+            border-radius: 8px;
+            resize: vertical;
+            font-size: 14px;
+            line-height: 1.5;
+        }
+        /* 参数设置区域 */
+        .params-grid {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+            gap: 15px;
+        }
+        .param-item {
+            margin-bottom: 15px;
+        }
+        .param-item label {
+            display: block;
+            font-size: 13px;
+            font-weight: bold;
+            color: #333;
+            margin-bottom: 5px;
+        }
+        .param-item select, .param-item input[type="number"] {
+            width: 100%;
+            padding: 8px 12px;
+            border: 1px solid #ddd;
+            border-radius: 4px;
+            font-size: 14px;
+        }
+        /* 提示词示例 */
+        .prompt-examples {
+            background-color: #f8f9fa;
+            border-radius: 8px;
+            padding: 15px;
+            margin-bottom: 20px;
+        }
+        .prompt-examples h4 {
+            font-size: 14px;
+            font-weight: bold;
+            margin-bottom: 10px;
+            color: #333;
+        }
+        .example-list {
+            display: flex;
+            flex-wrap: wrap;
+            gap: 8px;
+        }
+        .example-tag {
+            font-size: 12px;
+            background-color: #e9ecef;
+            color: #666;
+            padding: 4px 10px;
+            border-radius: 4px;
+            cursor: pointer;
+            transition: background-color 0.2s;
+        }
+        .example-tag:hover {
+            background-color: #dee2e6;
+        }
+        /* 按钮样式 */
+        .button-group {
+            display: flex;
+            gap: 10px;
+        }
+        .btn {
+            padding: 12px 24px;
+            border: none;
+            border-radius: 8px;
+            font-size: 14px;
+            cursor: pointer;
+            transition: background-color 0.2s;
+        }
+        .btn-primary {
+            background-color: #007bff;
+            color: #fff;
+        }
+        .btn-primary:hover {
+            background-color: #0056b3;
+        }
+        .btn-secondary {
+            background-color: #6c757d;
+            color: #fff;
+        }
+        .btn-secondary:hover {
+            background-color: #545b62;
+        }
+        /* 预览区域 */
+        .preview-container {
+            width: 100%;
+            min-height: 300px;
+            background-color: #f8f9fa;
+            border-radius: 8px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-bottom: 20px;
+            overflow: hidden;
+        }
+        .preview-image {
+            max-width: 100%;
+            max-height: 100%;
+            object-fit: contain;
+        }
+        .preview-placeholder {
+            font-size: 14px;
+            color: #666;
+            text-align: center;
+        }
+        /* 模板信息 */
+        .template-info {
+            margin-bottom: 20px;
+        }
+        .template-info h4 {
+            font-size: 14px;
+            font-weight: bold;
+            margin-bottom: 10px;
+            color: #333;
+        }
+        .template-form input {
+            width: 100%;
+            padding: 10px 12px;
+            border: 1px solid #ddd;
+            border-radius: 8px;
+            font-size: 14px;
+            margin-bottom: 10px;
+        }
+        /* 响应式设计 */
+        @media (max-width: 768px) {
+            .content-area {
+                grid-template-columns: 1fr;
+            }
+            .clear-btn, .optimize-btn, .arrow-btn {
+                flex: 1;
+            }
+        }
+        .optimize-btn {
+            background-color: #ffffff;
+            color: #4b5563;
+            padding: 10px 18px;
+            border: 1px solid #d1d5db;
+            border-radius: 8px;
+            font-size: 14px;
+            font-weight: 500;
+            cursor: pointer;
+            transition: all 0.3s ease;
+            display: flex;
+            align-items: center;
+            gap: 6px;
+        }
+
+        .optimize-btn:hover {
+            background-color: #f9fafb;
+            border-color: #9ca3af;
+            transform: translateY(-1px);
+        }
+        .clear-btn {
+            background-color: #ffffff;
+            color: #dc3545;
+            border: 1px solid #f87171;
+            border-radius: 8px;
+            font-size: 14px;
+            font-weight: 500;
+            cursor: pointer;
+            transition: all 0.3s ease;
+            display: flex;
+            align-items: center;
+            gap: 6px;
+        }
+
+        .clear-btn:hover {
+            background-color: #fee2e2;
+            border-color: #ef4444;
+            transform: translateY(-1px);
+        }
+        /* 操作按钮 */
+        .prompt-actions {
+            gap: 8px;
+        }
+
+        .clear-btn, .optimize-btn {
+            padding: 8px 12px;
+            font-size: 13px;
+        }
+
+        /* 菜单样式 */
+        .menu-container {
+            background-color: #f5f7fa;
+            border-radius: 8px;
+            padding: 10px;
+            margin-bottom: 20px;
+            display: flex;
+            gap: 10px;
+        }
+
+        .menu-item {
+            flex: 1;
+        }
+
+        .menu-item a {
+            display: block;
+            padding: 12px;
+            background-color: white;
+            border: 1px solid #e1e8ed;
+            border-radius: 6px;
+            text-align: center;
+            text-decoration: none;
+            color: #657786;
+            font-size: 14px;
+            font-weight: 500;
+            transition: all 0.3s ease;
+        }
+
+        .menu-item a:hover {
+            background-color: #e8f0fe;
+            border-color: #1da1f2;
+            color: #1da1f2;
+        }
+
+        .menu-item.active a {
+            background-color: #1da1f2;
+            border-color: #1da1f2;
+            color: white;
+        }
+
+        .menu-item i {
+            margin-right: 6px;
+            font-size: 16px;
+        }
+    </style>
+</head>
+<body>
+<div class="container">
+    <!-- 菜单功能区 -->
+    <div class="menu-container">
+        <div class="menu-item active">
+            <a href="{:url('user/index')}">
+                <i class="fas fa-image"></i>
+                文生图
+            </a>
+        </div>
+        <div class="menu-item">
+            <a href="{:url('user/text_to_video')}">
+                <i class="fas fa-video"></i>
+                文生视频
+            </a>
+        </div>
+
+    </div>
+
+    <div class="content-area">
+        <!-- 左侧输入区域 -->
+        <div class="input-section">
+            <h3 style="font-size: 18px; font-weight: bold; margin-bottom: 15px; color: #333;">文生图生成参数设置</h3>
+
+            <!-- 提示词示例 -->
+            <div class="prompt-examples">
+                <label for="prompt">提示词</label>
+                <textarea id="prompt" class="prompt-textarea" placeholder="请输入您想要生成的图像描述,越详细越好..."></textarea>
+            </div>
+
+            <!-- 生成参数 -->
+            <div class="form-group">
+                <label>生成参数</label>
+                <div class="params-grid">
+                    <div class="param-item">
+                        <label for="style">风格</label>
+                        <select id="style">
+                            <option value="">默认</option>
+                            <option value="anime">动漫</option>
+                            <option value="oil">油画</option>
+                            <option value="landscape">风景</option>
+                            <option value="portrait">人像</option>
+                        </select>
+                    </div>
+                    <div class="param-item">
+                        <label for="imageSize">尺寸</label>
+                        <select id="imageSize">
+                            <option value="1:1">1:1</option>
+                            <option value="4:3">4:3</option>
+                            <option value="3:4">3:4</option>
+                            <option value="16:9">16:9</option>
+                            <option value="9:16">9:16</option>
+                        </select>
+                    </div>
+                </div>
+            </div>
+
+            <div class="button-group">
+                <button class="clear-btn" onclick="clearPrompt()">
+                    <i class="fas fa-trash"></i>
+                    清空
+                </button>
+                <button class="optimize-btn" onclick="optimizePrompt()">
+                    <i class="fas fa-magic"></i>
+                    一键优化
+                </button>
+                <button class="btn btn-primary" id="generateBtn" onclick="generateImage()">
+                    <i class="fas fa-arrow-up"></i>
+                    生成图像
+                </button>
+            </div>
+        </div>
+
+        <!-- 右侧预览区域 -->
+        <div class="preview-section">
+            <h3 style="font-size: 18px; font-weight: bold; margin-bottom: 15px; color: #333;">图像预览</h3>
+
+            <!-- 预览容器 -->
+            <div id="imageResult" class="preview-container">
+                <div class="preview-placeholder">
+                    <p>点击"生成图像"按钮开始创建您的模板</p>
+                    <p style="font-size: 12px; margin-top: 10px; color: #999;">生成时间可能需要几秒到几十秒不等</p>
+                </div>
+            </div>
+
+            <!-- 模板信息 -->
+            <div class="template-info">
+                <h4>模板信息</h4>
+                <div class="template-form">
+                    <input type="text" id="templateName" placeholder="请输入模板名称">
+                </div>
+            </div>
+
+            <!-- 保存按钮 -->
+            <div class="button-group">
+                <button class="btn btn-primary" id="saveBtn" disabled onclick="saveTemplate()">保存为模板</button>
+                <button class="btn btn-secondary" id="downloadBtn" disabled onclick="downloadImage()">下载图像</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    // 自定义提示框函数
+    function showAlert(message, type = 'info', duration = 3000) {
+        // 检查是否已存在提示框容器,如果不存在则创建
+        let alertElement = document.getElementById('customAlert');
+        if (!alertElement) {
+            alertElement = document.createElement('div');
+            alertElement.id = 'customAlert';
+            alertElement.className = 'custom-alert';
+            document.body.appendChild(alertElement);
+        }
+        alertElement.textContent = message;
+        alertElement.className = `custom-alert ${type}`;
+        // 显示提示框
+        alertElement.classList.add('show');
+        // 自动隐藏
+        setTimeout(() => {
+            alertElement.classList.remove('show');
+        }, duration);
+    }
+
+    // 生成图片函数
+    function generateImage() {
+        const promptText = document.querySelector('.prompt-textarea').value.trim();
+        const imageStyle = document.getElementById('style').value;
+        const imageSize = document.getElementById('imageSize').value;
+        const imageResultDiv = document.getElementById('imageResult');
+
+        // 检查是否有提示词
+        if (!promptText) {
+            showAlert('请先输入图片描述', 'warning');
+            return;
+        }
+
+        // 显示加载状态
+        imageResultDiv.innerHTML = `
+                <div class="image-loading">
+                    <i class="fas fa-spinner fa-spin"></i>
+                    <p>正在生成图片,请稍候...</p>
+                    <p style="font-size: 12px; margin-top: 10px; color: #999;">生成时间可能需要几秒到几十秒不等</p>
+                </div>
+            `;
+
+        // 拼接风格和尺寸到提示词末尾
+        let fullPrompt = promptText;
+        if (imageStyle) {
+            fullPrompt += '风格:' + imageStyle;
+        }
+        if (imageSize) {
+            fullPrompt += '尺寸比例:' + imageSize;
+        }
+
+        // 发送请求到文生图接口
+        $.ajax({
+            url: '/index.php/api/work_order/GetTxtToImg',
+            type: 'POST',
+            dataType: 'json',
+            data: {
+                status_val: '文生图',
+                prompt: fullPrompt,
+                model: 'gemini-3-pro-image-preview',
+                style: imageStyle,
+                size: imageSize
+            },
+            success: function(response) {
+                // 处理成功响应
+                if (response.code === 0 && response.data && response.data.url) {
+                    // 显示生成的图片
+                    imageResultDiv.innerHTML = `
+                            <div class="image-container">
+                                <img src="${response.data.url}" alt="生成的图片" class="generated-image" id="previewImage" style="max-width: 100%; height: auto; max-height: 600px; cursor: pointer;">
+                            </div>
+                        `;
+
+                    // 启用下载和保存按钮
+                    document.getElementById('downloadBtn').disabled = false;
+                    document.getElementById('saveBtn').disabled = false;
+
+                    // 添加图片放大模态框(如果还不存在)
+                    if (!document.getElementById('imageModal')) {
+                        const modal = document.createElement('div');
+                        modal.id = 'imageModal';
+                        modal.style.cssText = `
+                                display: none;
+                                position: fixed;
+                                z-index: 9999;
+                                left: 0;
+                                top: 0;
+                                width: 100%;
+                                height: 100%;
+                                overflow: auto;
+                                background-color: rgba(0, 0, 0, 0.9);
+                                justify-content: center;
+                                align-items: center;
+                            `;
+                        modal.style.display = 'flex';
+                        modal.style.display = 'none';
+
+                        const modalContent = document.createElement('img');
+                        modalContent.id = 'modalImage';
+                        modalContent.style.cssText = `
+                                max-width: 90%;
+                                max-height: 90%;
+                                margin: auto;
+                            `;
+
+                        const closeBtn = document.createElement('span');
+                        closeBtn.innerHTML = '&times;';
+                        closeBtn.style.cssText = `
+                                position: absolute;
+                                top: 20px;
+                                right: 35px;
+                                color: #f1f1f1;
+                                font-size: 40px;
+                                font-weight: bold;
+                                transition: 0.3s;
+                                cursor: pointer;
+                            `;
+
+                        closeBtn.onclick = function() {
+                            modal.style.display = 'none';
+                        };
+
+                        modal.appendChild(closeBtn);
+                        modal.appendChild(modalContent);
+                        document.body.appendChild(modal);
+
+                        // 点击模态框背景关闭
+                        modal.onclick = function(event) {
+                            if (event.target.id === 'imageModal') {
+                                this.style.display = 'none';
+                            }
+                        };
+                    }
+
+                    // 为生成的图片添加点击事件
+                    const generatedImage = imageResultDiv.querySelector('.generated-image');
+                    generatedImage.onclick = function() {
+                        const modal = document.getElementById('imageModal');
+                        const modalImage = document.getElementById('modalImage');
+                        modalImage.src = this.src;
+                        modal.style.display = 'flex';
+                    };
+
+                    // 键盘ESC键关闭
+                    document.addEventListener('keydown', function(event) {
+                        if (event.key === 'Escape') {
+                            const modal = document.getElementById('imageModal');
+                            if (modal && modal.style.display === 'flex') {
+                                modal.style.display = 'none';
+                            }
+                        }
+                    });
+                } else {
+                    // 显示错误信息
+                    imageResultDiv.innerHTML = `
+                            <div class="image-error">
+                                <i class="fas fa-exclamation-triangle"></i>
+                                <p>图片生成失败:${response.msg || '未知错误'}</p>
+                            </div>
+                        `;
+                }
+            },
+            error: function(xhr, status, error) {
+                // 处理网络错误
+                imageResultDiv.innerHTML = `
+                        <div class="image-error">
+                            <i class="fas fa-exclamation-triangle"></i>
+                            <p>图像生成失败</p>
+                        </div>
+                    `;
+            }
+        });
+    }
+
+    // 一键优化提示词功能
+    function optimizePrompt() {
+        const textarea = document.querySelector('.prompt-textarea');
+        const optimizeBtn = document.querySelector('.optimize-btn');
+
+        if (textarea && textarea.value.trim() !== '') {
+            // 显示加载状态
+            const originalBtnText = optimizeBtn.innerHTML;
+            optimizeBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 优化中...';
+            optimizeBtn.disabled = true;
+
+            // 构造请求参数
+            const params = {
+                status_val: '文生文',
+                prompt: textarea.value,
+                model: 'gemini-2.0-flash'
+            };
+
+            // 发送AJAX请求
+            $.ajax({
+                url: '/index.php/api/work_order/GetTxtToTxt',
+                type: 'POST',
+                data: params,
+                dataType: 'json',
+                success: function(data) {
+                    console.log(data);
+                    // 恢复按钮状态
+                    optimizeBtn.innerHTML = originalBtnText;
+                    optimizeBtn.disabled = false;
+
+                    // 优化成功,更新文本框内容
+                    textarea.value = data.content;
+                    textarea.scrollTop = textarea.scrollHeight;
+                    updateCharCount();
+
+                    // 显示优化成功提示
+                    const alert = document.createElement('div');
+                    alert.className = 'alert alert-success';
+                    alert.innerHTML = '提示词已优化!';
+                    alert.style.position = 'fixed';
+                    alert.style.top = '20px';
+                    alert.style.right = '20px';
+                    alert.style.zIndex = '9999';
+                    document.body.appendChild(alert);
+
+                    // 3秒后移除提示
+                    setTimeout(() => {
+                        alert.remove();
+                    }, 3000);
+
+                }
+            });
+        } else {
+            showAlert('请先输入提示词!', 'warning');
+        }
+    }
+
+    // 清空提示词功能
+    function clearPrompt() {
+        const textarea = document.querySelector('.prompt-textarea');
+        if (textarea) {
+            textarea.value = '';
+            textarea.focus();
+        }
+    }
+
+
+    // 保存模板函数
+    function saveTemplate() {
+        // 获取所有需要的参数
+        const templateName = document.getElementById('templateName').value;
+        const prompt = document.getElementById('prompt').value.trim();
+        const style = document.getElementById('style').value;
+        const imageSize = document.getElementById('imageSize').value;
+        const previewImage = document.getElementById('previewImage');
+
+        // 验证必填项
+        if (!templateName.trim()) {
+            showAlert('请输入模板名称', 'error');
+            return;
+        }
+
+        if (!prompt) {
+            showAlert('请输入提示词', 'error');
+            return;
+        }
+
+        if (!previewImage || !previewImage.src) {
+            showAlert('请先生成图片', 'error');
+            return;
+        }
+
+        // 准备请求参数
+        // 将完整URL转换为相对路径
+        let imageUrl = previewImage.src;
+        try {
+            const url = new URL(imageUrl);
+            imageUrl = url.pathname;
+        } catch (e) {
+            // 如果已经是相对路径,直接使用
+        }
+
+        const params = {
+            chinese_description: prompt,
+            template_image_url: imageUrl,
+            template_name: templateName,
+            style: style,
+            size: imageSize,
+            type: '文生图' // 固定为文生图类型
+        };
+
+        // 显示加载状态
+        const saveBtn = document.getElementById('saveBtn');
+        const originalText = saveBtn.innerHTML;
+        saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 保存中...';
+        saveBtn.disabled = true;
+
+        // 发送AJAX请求
+        $.ajax({
+            url: '/index.php/api/work_order/Add_Product_Template',
+            type: 'POST',
+            dataType: 'json',
+            data: params,
+            success: function(response) {
+                if (response.code === 0) {
+                    showAlert('模板保存成功!', 'success');
+                    // 清空模板名称输入框
+                    document.getElementById('templateName').value = '';
+                } else {
+                    showAlert('模板保存失败:' + (response.msg || '未知错误'), 'error');
+                }
+            },
+            error: function(xhr, status, error) {
+                console.error('AJAX请求失败:', error);
+                showAlert('网络错误,模板保存失败', 'error');
+            },
+            complete: function() {
+                // 恢复按钮状态
+                saveBtn.innerHTML = originalText;
+                saveBtn.disabled = false;
+            }
+        });
+    }
+
+    // 下载图像函数
+    function downloadImage() {
+        const previewImage = document.getElementById('previewImage');
+        if (previewImage && previewImage.src) {
+            // 创建临时链接下载图片
+            const link = document.createElement('a');
+            link.href = previewImage.src;
+
+            // 生成更有意义的文件名
+            const timestamp = new Date().getTime();
+            const promptText = document.querySelector('.prompt-textarea').value.trim();
+            // 从提示词中提取前20个字符作为文件名的一部分
+            const promptPart = promptText.substring(0, 20).replace(/[^\w\u4e00-\u9fa5]/g, '') || 'image';
+            // 组合文件名:提示词部分_时间戳.jpg
+            const fileName = `${promptPart}_${timestamp}.jpg`;
+
+            link.download = fileName;
+            link.click();
+        }
+    }
+</script>
+</body>
+</html>

+ 54 - 32
application/service/AIGatewayService.php

@@ -10,39 +10,61 @@ class AIGatewayService{
      * - api_key:API 调用密钥(Token)
      * - api_url:对应功能的服务端地址
      */
-     protected $config = [
-        //图生文 gemini-3-pro-preview
-        'gemini_imgtotxt' => [
-            'api_key' => 'sk-R4O93k4FrJTXMLYZ2eB32WDPHWiDNbeUdlUcsLjgjeDKuzFI',
-            'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-preview:generateContent'
+    // protected $config = [
+    //    //图生文 gemini-3-pro-preview
+    //    'gemini_imgtotxt' => [
+    //        'api_key' => 'sk-R4O93k4FrJTXMLYZ2eB32WDPHWiDNbeUdlUcsLjgjeDKuzFI',
+    //        'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-preview:generateContent'
+    //    ],
+    //     //文生文 gpt-4
+    //     'txttotxtgtp' => [
+    //         'api_key' => 'sk-fxlawqVtbbQbNW0wInR3E4wsLo5JHozDC2XOHzMa711su6ss',
+    //         'api_url' => 'https://chatapi.onechats.top/v1/chat/completions'
+    //     ],
+    //     //文生文 gemini-2.0-flash
+    //     'txttotxtgemini' => [
+    //         'api_key' => 'sk-cqfCZFiiSIdpDjIHLMBbH6uWfeg7iVsASvlubjrNEmfUXbpX',
+    //         'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-2.0-flash:generateContent'
+    //     ],
+    //     //文生图 black-forest-labs/FLUX.1-kontext-pro、dall-e-3、gpt-image-1
+    //     'txttoimg' => [
+    //         'api_key' => 'sk-MB6SR8qNaTjO80U7HJl4ztivX3zQKPgKVka9oyfVSXIkHSYZ',
+    //         'api_url' => 'https://chatapi.onechats.ai/v1/images/generations'
+    //     ],
+    //     //文生图 gemini-3-pro-image-preview
+    //     'gemini_txttoimg' => [
+    //         'api_key' => 'sk-8nTt32NDI6q7klryBehwjEfnGaGrX8m1zI0C4ddfudLtanqP',
+    //         'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-image-preview:streamGenerateContent'
+    //     ],
+    //     //文生图 MID_JOURNEY
+    //     'submitimage' => [
+    //         'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
+    //         'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine'
+    //     ]
+    // ];
+    //自用
+    protected $config = [
+       //图生文 gemini-3-pro-preview
+       'gemini_imgtotxt' => [
+           'api_key' => 'sk-QiakVPhSisJiOh90LQFpjx9MX27mqGGOpOQ8XjKRhekoNCyr',
+           'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-preview:generateContent'
+       ],
+        //文生文 gpt-4 (OpenAI格式)
+        'txttotxtgtp' => [
+            'api_key' => 'sk-pAlJU9xScpzDGvj1rhYKpokYcECETaceCSqDMUtq5N7FnbnA',
+            'api_url' => 'https://chatapi.onechats.top/v1/chat/completions'
         ],
-         //文生文 gpt-4
-         'txttotxtgtp' => [
-             'api_key' => 'sk-fxlawqVtbbQbNW0wInR3E4wsLo5JHozDC2XOHzMa711su6ss',
-             'api_url' => 'https://chatapi.onechats.top/v1/chat/completions'
-         ],
-         //文生文 gemini-2.0-flash
-         'txttotxtgemini' => [
-             'api_key' => 'sk-cqfCZFiiSIdpDjIHLMBbH6uWfeg7iVsASvlubjrNEmfUXbpX',
-             'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-2.0-flash:generateContent'
-         ],
-         //文生图 black-forest-labs/FLUX.1-kontext-pro、dall-e-3、gpt-image-1
-         'txttoimg' => [
-             'api_key' => 'sk-MB6SR8qNaTjO80U7HJl4ztivX3zQKPgKVka9oyfVSXIkHSYZ',
-             'api_url' => 'https://chatapi.onechats.ai/v1/images/generations'
-         ],
-         //文生图 gemini-3-pro-image-preview
-         'gemini_txttoimg' => [
-             'api_key' => 'sk-8nTt32NDI6q7klryBehwjEfnGaGrX8m1zI0C4ddfudLtanqP',
-             'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-image-preview:streamGenerateContent'
-         ],
-         //文生图 MID_JOURNEY
-         'submitimage' => [
-             'api_key' => 'sk-iURfrAgzAjhZ4PpPLwzmWIAhM7zKfrkwDvyxk4RVBQ4ouJNK',
-             'api_url' => 'https://chatapi.onechats.ai/mj/submit/imagine'
-         ]
-     ];
-
+        //文生文 gemini-2.0-flash (Gemini格式)
+        'txttotxtgemini' => [
+            'api_key' => 'sk-pAlJU9xScpzDGvj1rhYKpokYcECETaceCSqDMUtq5N7FnbnA',
+            'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-2.0-flash:generateContent'
+        ],
+        //文生图 gemini-3-pro-image-preview
+        'gemini_txttoimg' => [
+            'api_key' => 'sk-pAlJU9xScpzDGvj1rhYKpokYcECETaceCSqDMUtq5N7FnbnA',
+            'api_url' => 'https://chatapi.onechats.ai/v1beta/models/gemini-3-pro-image-preview:streamGenerateContent'
+        ]
+    ];
 
     /**
      * 图生文