Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
ThinkAdmin
https://github.com/zoujingli/thinkadmin
Admin
基于 ThinkPHP6&8 的极简后台管理系统,内置注解权限、异步多任务、应用插件生态等,支持类 PaaS 更新公共模块和应用插件,插件可本地化定制开发。
Tokens:
34,527
Snippets:
137
Trust Score:
9.4
License:
MIT
Update:
1 year ago
Context
Chat
Benchmark
60.25
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Install ThinkAdmin from Source Source: https://github.com/zoujingli/thinkadmin/blob/v6/readme.md Steps to clone the ThinkAdmin repository and install it from source. This method includes installing project dependencies, configuring the environment, running database migrations, and starting the development server. It's suitable for developers who want to work directly with the source code. ```Shell ### 下载项目( 需要在英文目录下面执行 ) # git clone https://github.com/zoujingli/ThinkAdmin git clone https://gitee.com/zoujingli/ThinkAdmin ### 进入项目根目录 cd ThinkAdmin ### 安装项目依赖组件 composer install --optimize-autoloader ### 数据库初始化安装 ### 系统默认使用 Sqlite 数据库 ### 若使用其他数据库请修改 DB_ 相关的配置 copy .env.example .env vi .env #### 执行数据库初始化安装 php think migrate:run ### 开启PHP内置WEB服务 ### 默认后台登录账号及密码都是 admin php think run --host 127.0.0.1 ``` -------------------------------- ### Install ThinkAdmin via Composer Source: https://github.com/zoujingli/thinkadmin/blob/v6/readme.md Steps to create a new ThinkAdmin project using Composer. This includes project creation, dependency installation, environment configuration, database initialization, and starting the development server. It's recommended for new projects. ```Shell ### 创建项目( 需要在英文目录下面执行 ) composer create-project zoujingli/thinkadmin ### 进入项目根目录 cd thinkadmin ### 数据库初始化安装 ### 系统默认使用 Sqlite 数据库 ### 若使用其他数据库请修改 DB_ 相关的配置 copy .env.example .env vi .env #### 执行数据库初始化安装 php think migrate:run ### 安装微信管理模块 composer require zoujingli/think-plugs-wechat ### 开启PHP内置WEB服务 ### 默认后台登录账号及密码都是 admin php think run --host 127.0.0.1 ``` -------------------------------- ### ThinkAdmin Framework Commands Source: https://github.com/zoujingli/thinkadmin/blob/v6/readme.md Common ThinkAdmin console commands for development and management. These include starting the development server, managing packages, updating menus, and handling asynchronous tasks. ```bash php think run php think xadmin:package php think xadmin:sysmenu php think xadmin:fansall php think xadmin:replace php think xadmin:database php think xadmin:publish --migrate ``` -------------------------------- ### Initialize Oplog Table with Layui Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/oplog/index.html Configures the Oplog data table using Layui, specifying columns, sorting, height, and event handlers. It includes basic table setup and column definitions for operation logs. ```javascript $(function () { $('#OplogTable').layTable({ even: true, height: 'full', sort: {field: 'id', type: 'desc'}, cols: [[ {checkbox: true}, {field: 'id', title: '{:lang("ID")}', width: 80, sort: true, align: 'center'}, {field: 'username', title: '{:lang("操作账号")}', minWidth: 100, width: '8%', sort: true, align: 'center'}, {field: 'node', title: '{:lang("操作节点")}', minWidth: 120}, {field: 'action', title: '{:lang("操作行为")}', minWidth: 120}, {field: 'content', title: '{:lang("操作内容")}', minWidth: 150}, {field: 'geoip', title: '{:lang("访问地址")}', minWidth: 100, width: '10%'}, {field: 'geoisp', title: '{:lang("网络服务商")}', minWidth: 100}, {field: 'create_at', title: '{:lang("创建时间")}', minWidth: 170, align: 'center', sort: true}, {toolbar: '#toolbar', title: '{:lang("操作面板")}', align: 'center', minWidth: 80, width: '8%', fixed: 'right'} ]] }); }); ``` -------------------------------- ### Display Plugin Information Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/index.html This snippet iterates through installed plugins and displays their name, package, version, and license. It's conditional on the existence of plugins and typically visible in development mode. ```php {notempty name='plugins'} **{:lang('应用插件')}**( {:lang('仅开发模式可见')} ) {foreach $plugins as $key=>$plugin} {:lang('应用名称')} {:lang('插件名称')} {:lang('插件包名')} {:lang('插件版本')} {:lang('授权协议')} {$key} {$plugin.name|lang} {if empty($plugin.install.document)}{$plugin.package} {else}[{$plugin.package}]({$plugin.install.document}){/if} {$plugin.install.version|default='unknow'} {if empty($plugin.install.license)} - {elseif is_array($plugin.install.license)}{$plugin.install.license|join='、',###} {else}{$plugin.install.license|default='-'}{/if} {/foreach} {/notempty} ``` -------------------------------- ### Task Queue Management Commands Source: https://github.com/zoujingli/thinkadmin/blob/v6/readme.md Commands for managing asynchronous task queues in ThinkAdmin. This includes starting, stopping, querying, and checking the status of queue listeners and web services. ```bash php think xadmin:queue listen php think xadmin:queue start php think xadmin:queue query php think xadmin:queue status php think xadmin:queue stop php think xadmin:queue webstop php think xadmin:queue webstart php think xadmin:queue webstatus ``` -------------------------------- ### Configure Database Connection Source: https://github.com/zoujingli/thinkadmin/blob/v6/readme.md Example of configuring database connections in ThinkAdmin's `config/database.php` file. It shows how to set the default connection and define parameters for different database types. ```php return [ // 数据库类型 'default' => 'sqlite', // 数据库连接参数 'connections' => [ 'mysql' => [ /* 具体参数省略 */ ], 'sqlite' => [ /* 具体参数省略 */ ] ] ] ``` -------------------------------- ### CSS Styles for Audio Player UI Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/voice.html Provides styling for UI elements, specifically for left-aligned text and an icon used for the audio player controls. It ensures margins are reset and sets text color for left-aligned content, and defines size and margin for icons. ```css .left-text { margin: 0 !important; color: #ccc !important } .icon { color: #666; font-size: 1.5rem; margin-left: 2.5rem; line-height: 1.5rem } ``` -------------------------------- ### ThinkAdmin Template Structure and CSS Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/news.html This snippet outlines the basic structure of a ThinkAdmin template, including extending a base layout and defining content and style blocks. It also contains CSS rules for layout, styling, and responsive design elements. ```thinkphp_template {extend name='api/view/main'} {block name='content'} {:date('H:i')} {notempty name='news.articles'} {foreach $news.articles as $k => $v} {if $k < 1} [{if $v.title}{$v.title}{/if}]({:url('api.view/item')}?id={$v.id}) {else} [{$v.title}]({:url('api.view/item')}?id={$v.id}) {/if} {/foreach} {else} ### 404 访问资源不存在哦! {/notempty} document.querySelectorAll('\\[data-lazy-src\\]').forEach(function (elem) { elem.style.backgroundImage = 'url(' + elem.dataset.lazySrc + ')'; }); {/block} {block name='style'} html { width: 100%; height: 100%; display: block; background: #f0f0f0; } .header { margin-top: 15px; text-align: center; } .header span { padding: 1px 5px; font-size: 12px; line-height: 12px; background: #aaa; box-shadow: 0 0 1px #666; } .container { width: 90%; display: block; margin: 5vw auto; position: relative; border-radius: 5px; background: white; box-shadow: 0 0 2px rgba(0, 0, 0, .5); } .container a.item { height: 50vw; display: block; position: relative; background: no-repeat center center; background-size: cover; } .container a.item:first-child { border-top-left-radius: 5px; border-top-right-radius: 5px; } .container a.item:last-child, .container a.item:last-child span { border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } .container a span { left: -1px; right: -1px; bottom: 0; color: #fff; padding: 2vw; font-size: 2vw; max-height: 5em; overflow: hidden; position: absolute; line-height: 2em; white-space: nowrap; text-overflow: ellipsis; background: rgba(0, 0, 0, .7); } .container a.other { height: 15vw; display: block; padding: 1vw 2vw; position: relative; } .container a.other span:first-child { color: #333; float: left; width: 60vw; height: 10vw; overflow: hidden; max-height: none; position: relative; background: 0 0; text-overflow: ellipsis; } .container a.other span:last-child { width: 16vw; height: 10vw; float: right; max-height: none; position: relative; background-size: cover; background-position: center center; } .info { color: #666; padding: 2rem; font-size: .5rem; text-align: center; letter-spacing: 1px; } .info h3 { color: #333; font-size: 5vw; margin-bottom: 1rem; } .hr-line-dashed { color: #fff; height: 1px; margin: 3px 0; border-top: 1px dashed #e7eaec; } .hr-line-dashed:last-child { display: none; } {/block} ``` -------------------------------- ### Content and Layout Styling Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/item.html This CSS block defines the visual presentation for the content elements within the template. It styles containers, headings, text, images, and read counts to create a structured and readable layout. ```css {block name='style'} html { width: 100%; height: 100%; display: block; background: white; } .container { width: 90%; color: #333; display: block; margin: .2rem auto; position: relative } .container h2 { font-size: .8rem; font-weight: 400; line-height: 1.5rem } .container h3 { color: #999; font-size: .6rem; font-weight: 400; line-height: 1.5rem; margin-bottom: .3rem } .container .content-read { color: #999; font-size: 0.6rem; text-align: right; margin-top: 0.5rem; line-height: 2rem; padding-bottom: 1rem; } .container .content-text { font-size: .7rem; line-height: 1.3rem } .container .content-text img { max-width: 100%; height: auto !important } {/block} ``` -------------------------------- ### JavaScript Lazy Load Background Image Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/news.html This JavaScript code iterates through elements with a 'data-lazy-src' attribute and sets their background image using the provided URL. It's a common pattern for optimizing image loading. ```javascript document.querySelectorAll('[data-lazy-src]').forEach(function (elem) { elem.style.backgroundImage = 'url(' + elem.dataset.lazySrc + ')'; }); ``` -------------------------------- ### ThinkPHP Template View Logic Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/item.html This snippet shows the core logic of a ThinkPHP template view. It handles conditional rendering of article details or a 404 error based on the 'info' variable, utilizing template inheritance and data display directives. ```php-template {extend name='api/view/main'} {block name='title'}{/block} {block name='content'} {notempty name='info'} {$info.title|default=''} ------------------------ ### {$info.author} {:date('Y年m月d日',strtotime($info.create_at))} {if $info.show_cover_pic and $info.local_url}{/if} {$info.content|raw} 阅读 {$info.read_num} {else} ### 404 访问资源不存在哦! {/notempty} {/block} ``` -------------------------------- ### Export Data to Excel with Formatting Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/payment/record/index_search.html This snippet shows how to use the 'excel' module to export data. It binds a function to handle data processing, transforming raw data into a structured array suitable for Excel. The data is mapped to specific columns, including translating a boolean payment status to '已支付' or '未支付', and a header row is prepended. The output file is named dynamically. ```javascript window.form.render(); require(['excel'], function (excel) { excel.bind(function (data) { data.forEach(function (item, index) { data[index] = [ item.id || 0, item.order_name || '', item.order_code || '', item.order_amount || '', item.payment_status ? '已支付' : '未支付', item.type || '', item.payment_time || '', item.create_time || '', ]; }); data.unshift([ 'ID', '订单名称', '订单编号', '订单金额', '支付状态', '支付类型', '支付时间', '创建时间' ]); return this.withStyle(data, {G: 160}); }, '支付行为数据' + layui.util.toDateString(Date.now(), '_yyyyMMdd_HHmmss')); }); ``` -------------------------------- ### API: Get Queue Status Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/queue/index.html Endpoint to retrieve the current status and statistics of the task queue system. This is called via AJAX to update the dashboard display. ```APIDOC GET /admin/api.queue/status Description: Retrieves the current status and statistics of the task queue. Returns: JSON object containing queue status and task counts. Example: { "status": "running", "pending_tasks": 10, "processing_tasks": 5, "completed_tasks": 100, "failed_tasks": 2 } ``` -------------------------------- ### Initialize File Table with Layui Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/file/index.html Configures and initializes a Layui data table for displaying file information. It sets up table columns, sorting, height, and event handlers for file display and actions. Requires jQuery and Layui framework. ```javascript $(function () { $('#FileTable').layTable({ even: true, height: 'full', sort: {field: 'id', type: 'desc'}, cols: [[ {checkbox: true, fixed: true}, {field: 'id', title: 'ID', width: 80, align: 'center', sort: true}, {field: 'name', title: '{:lang("文件名称")}', width: '12%', align: 'center'}, {field: 'hash', title: '{:lang("文件哈希")}', width: '15%', align: 'center', templet: '<div><code>{{d.hash}}</code></div>'}, {field: 'size', title: '{:lang("文件大小")}', align: 'center', width: '7%', sort: true, templet: '<div>{{-$.formatFileSize(d.size)}}</div>'}, {field: 'xext', title: '{:lang("文件后缀")}', align: 'center', width: '7%', sort: true}, { field: 'xurl', title: '{:lang("查看文件")}', width: '7%', align: 'center', templet: function (d) { if (typeof d.mime === 'string' && /^image\//.test(d.mime)) { return laytpl('<div><a target="_blank" data-tips-hover data-tips-image="{{d.xurl}}"><i class="layui-icon layui-icon-picture"></i></a></div>').render(d) } if (typeof d.mime === 'string' && /^video\//.test(d.mime)) { return laytpl('<div><a target="_blank" data-video-player="{{d.xurl}}" data-tips-text="{:lang(\'播放视频\')}"><i class="layui-icon layui-icon-video"></i></a></div>').render(d); } if (typeof d.mime === 'string' && /^audio\//.test(d.mime)) { return laytpl('<div><a target="_blank" data-video-player="{{d.xurl}}" data-tips-text="{:lang(\'播放音频\')}"><i class="layui-icon layui-icon-headset"></i></a></div>').render(d); } return laytpl('<div><a target="_blank" href="{{d.xurl}}" data-tips-text="{:lang(\'查看下载\')}"><i class="layui-icon layui-icon-file"></i></a></div>').render(d); } }, { field: 'isfast', title: '{:lang("上传方式")}', align: 'center', width: '8%', templet: function (d) { return d.isfast ? '<b class="color-green">{:lang("秒传")}</b>' : '<b class="color-blue">{:lang("普通")}</b>'; } }, {field: 'ctype', title: '{:lang("存储方式")}', align: 'center', width: '10%'}, {field: 'create_at', title: '{:lang("创建时间")}', align: 'center', width: '15%', sort: true}, {toolbar: '#toolbar', title: '{:lang("操作面板")}', align: 'center', minWidth: 150, fixed: 'right'} ]] }); }); ``` -------------------------------- ### PHP Template: Display System Info and Links Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/login/index.html This PHP template code displays system configuration values such as application name, version, and login name. It also includes conditional rendering for Gitee links and browser recommendations, along with site copyright and ICP备案 information. ```PHP {extend name="index/index"} {block name='style'} if (location.href.indexOf('#') > -1) location.replace(location.href.split('#')[0]) {/block} {block name="body"} [{:sysconf('app\_name')}{:sysconf('app\_version')}]({:url('@')}) {notempty name='runtimeMode'} [ ](https://gitee.com/zoujingli/ThinkAdmin){/notempty} {:sysconf('login\_name')?:'系统管理'} --------------------------------- * * * * 正在载入 推荐使用 [Google Chrome](https://www.google.cn/chrome) 或 [Microsoft Edge](https://www.microsoft.com/zh-cn/edge#platform) 浏览器访问 {:sysconf('site\_copy')} {if sysconf('beian')}|[{:sysconf('beian')}](https://www.beian.gov.cn/portal/registerSystemInfo){/if} {if sysconf('miitbeian')}|[{:sysconf('miitbeian')}](https://beian.miit.gov.cn/){/if} {/block} {block name='script'} {/block} ``` -------------------------------- ### Alibaba Cloud OSS Configuration Settings Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/storage-alioss.html This section outlines the key configuration parameters required for Alibaba Cloud OSS storage. It includes settings for access protocol, storage region, bucket name, access domain, access key, and secret key. The provided template snippets demonstrate how these configurations are dynamically rendered and applied. ```template Configuration for Alibaba Cloud OSS Storage: Access Protocol: - Description: Specifies the protocol for accessing OSS files (HTTP, HTTPS, AUTO). - Default Handling: If not set, defaults to 'http'. - Example Logic: {if !sysconf('storage.alioss_http_protocol')} {php}sysconf('storage.alioss_http_protocol','http');{/php} {/if} {foreach ['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark} {if sysconf('storage.alioss_http_protocol') eq $protocol} {$remark} {else} {$remark} {/if} {/foreach} Storage Region: - Description: The region where the OSS bucket is located. Must match the actual storage region. - Example Logic: {foreach $points as $point => $title} {if sysconf('storage.alioss_point') eq $point} {$title}( {$point} ) {else} {$title}( {$point} ) {/if} {/foreach} Bucket Name: - Description: The name of the Alibaba Cloud OSS storage bucket. It must be globally unique and will be automatically created if it doesn't exist. Access Domain: - Description: The external access domain for the OSS bucket. Do not include the protocol (e.g., static.alioss.thinkadmin.top). Access Key: - Description: The AccessKey obtained from the Alibaba Cloud console. Secret Key: - Description: The SecretKey obtained from the Alibaba Cloud console. ``` -------------------------------- ### Render Status Options Conditionally Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/auto/index_search.html This snippet renders status options, conditionally highlighting the selected status based on the 'status' GET parameter. It's used for creating filterable lists or dropdowns. ```template {foreach ['显示已禁止的消息','显示已激活的消息'] as $k=>$v}{ if isset($get.status) and $get.status eq $k."") {$v} {else} {$v} {/if} {/foreach} ``` -------------------------------- ### ThinkAdmin Local Storage Access Domain Configuration Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/storage-local.html This snippet describes the configuration for the access domain used for locally stored files. It explains that the protocol should not be included in the domain and provides an example. ```php 填写上传后的访问域名(不指定时根据当前访问地址自动计算),不需要填写访问协议,如:static.thinkadmin.top ``` -------------------------------- ### Initialize Queue Task Table with Layui Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/queue/index.html Configures a data table using the Layui framework to display queue tasks. It includes sorting, height adjustment, custom data filtering, and detailed column definitions with templating for rich display of task information and status. ```JavaScript $(function () { $('#QueueTable').layTable({ even: true, height: 'full', sort: {field: 'loops_time desc,id', type: 'desc'}, filter: function (items, result) { return result && result.extra && $("[data-extra]").map(function () { this.innerHTML = result.extra[this.dataset.extra] || 0; }), items; }, cols: [[ {checkbox: true, fixed: 'left'}, { field: 'id', title: '{:lang("任务名称")}', width: '25%', sort: true, templet: function (d) { if (d.loops_time > 0) { d.one = '<span class="layui-badge think-bg-blue">循</span>'; } else { d.one = '<span class="layui-badge think-bg-red">次</span>'; } if (parseInt(d.rscript) === 1) { d.two = '<span class="layui-badge layui-bg-green">复</span>'; } else { d.two = '<span class="layui-badge think-bg-violet">单</span>'; } return laytpl('{{-d.one}}任务编号:<b>{{d.code}}</b><br>{{-d.two}}任务名称:{{d.title}}').render(d); } }, { field: 'exec_time', title: '{:lang("任务计划")}', width: '25%', templet: function (d) { d.html = '执行指令:' + d.command + '<br>计划执行:' + d.exec_time; if (d.loops_time > 0) { return d.html + ' ( 每 <b class="color-blue">' + d.loops_time + '</b> 秒 ) '; } else { return d.html + ' <span class="color-desc">( 单次任务 )</span> '; } } }, { field: 'loops_time', title: '{:lang("任务状态")}', width: '30%', templet: function (d) { d.html = ([ '<span class="pull-left layui-badge layui-badge-middle layui-bg-gray">未知</span>', '<span class="pull-left layui-badge layui-badge-middle layui-bg-black">等待</span>', '<span class="pull-left layui-badge layui-badge-middle layui-bg-blue">执行</span>', '<span class="pull-left layui-badge layui-badge-middle layui-bg-green">完成</span>', '<span class="pull-left layui-badge layui-badge-middle layui-bg-red">失败</span>', ][d.status] || '') + '执行时间:'; d.enter_time = d.enter_time || ''; d.outer_time = d.outer_time || '0.0000'; if (d.enter_time.length > 12) { d.html += d.enter_time.substring(12) + '<span class="color-desc"> ( ' + d.outer_time + ' ) </span>'; d.html += ' 已执行 <b class="color-blue">' + (d.attempts || 0) + '</b> 次'; } else { d.html += '<span class="color-desc">任务未执行</span>' } return d.html + '<br>执行结果:<span class="color-blue">' + (d.exec_desc || '<span class="color-desc">未获取到执行结果</span>') + '</span>'; } }, {toolbar: '#toolbar', title: '{:lang("操作面板")}', align: 'center', minWidth: 210, fixed: 'right'} ]] }); }); ``` -------------------------------- ### JavaScript for News List Initialization and Interaction Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/news/select.html Initializes a Masonry layout for news items, handles hover effects for item highlighting, and sets up click event listeners for selecting news items and navigating pagination. It uses jQuery and the Masonry library. ```javascript require(['jquery.masonry'], function (Masonry) { $('.news-container.layui-hide').removeClass('layui-hide'); var msnry = new Masonry($('.news-container').get(0), { itemSelector: '.news-item', columnWidth: 0 }); msnry.layout(); /*! 事件处理 */ $('.news-item').on('mouseenter', '.news-container', function () { $(this).addClass('active'); }).on('mouseleave', '.news-container', function () { $(this).removeClass('active'); }); /*! 外部选择器 */ var seletor = '[name="{:decode(input("get.field","0"))}"]'; $(' [data-news-id]').on('click', function () { window.top.$(seletor).val($(this).attr('data-news-id')).trigger('change'); parent.layer.close(parent.layer.getFrameIndex(window.name)) }); /*! 分页事件处理 */ $('body').off('change', '.pagination-trigger select').on('change', '.pagination-trigger select', function () { var urls = this.options[this.selectedIndex].getAttribute('data-url').split('#'); urls.shift(), window.location.href = urls.join('#'); }).off('click', '[data-open]').on('click', '[data-open]', function () { window.location.href = this.getAttribute('data-open'); }); }); ``` -------------------------------- ### Application Name and Version Configuration Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/system.html Configures the application name and version, which are displayed in the top-left corner of the backend interface. ```APIDOC 后台程序名称 App Name 管理程序名称显示在后台左上标题处 ~ 后台程序版本 App Version 管理程序版本显示在后台左上标题处 ~ ``` -------------------------------- ### Filter Data by Status Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/base/index_search.html This snippet illustrates how to iterate through status options (e.g., 'Disabled', 'Active') and conditionally display them, often used in dropdowns or status indicators in web applications. It uses PHP's foreach loop and conditional statements. ```php -- {lang('All')} -- { foreach ([lang('Disabled Record'), lang('Activated Record')] as $k => $v) { if (isset($get.status) && $get.status == $k . "") { {$v} } else { {$v} } } } ``` -------------------------------- ### Image Upload Initialization Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/system.html Initializes the upload functionality for elements with the name 'login_image' using a JavaScript plugin. ```javascript $('[name=login_image]').uploadMultipleImage(); ``` -------------------------------- ### Conditional Status Filter Logic Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/auth/index_search.html This snippet demonstrates how to conditionally display status options (e.g., 'Disabled', 'Active') based on a GET parameter. It iterates through predefined status labels and applies a 'selected' attribute if the current status matches the loop key. ```PHP <?php // Assuming $get is an array containing GET parameters // Assuming lang() is a function that returns translated strings $statusOptions = [ lang('已禁用记录'), // Disabled record lang('已激活记录') // Activated record ]; $currentStatus = isset($get['status']) ? $get['status'] : null; ?> <label for="status-filter">{:lang('使用状态')}:</label> <select id="status-filter" name="status"> <option value="">{:lang('全部')}</option> <!-- All --> <?php foreach ($statusOptions as $k => $v): ?> <option value="<?php echo $k; ?>" <?php echo ($currentStatus !== null && (string)$currentStatus === (string)$k) ? 'selected' : ''; ?>><?php echo $v; ?></option> <?php endforeach; ?> </select> ``` -------------------------------- ### Display System Information Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/index.html This section displays core system information, including framework versions, operating system, runtime environment, and database type. It's typically visible only in development mode. ```php {:lang('核心框架')} [ThinkPHP Version {$framework.version|default='None'}](https://www.thinkphp.cn) {:lang('平台框架')} [ThinkAdmin Version {$thinkadmin.version|default='6.0.0'}](https://thinkadmin.top) {:lang('操作系统')} {:php_uname()} {:lang('运行环境')} {:ucfirst($request->server('SERVER_SOFTWARE',php_sapi_name()))} & PHP {$Think.const.PHP_VERSION} & {:ucfirst(app()->db->connect()->getConfig('type'))} {:lang('系统序号')} {$systemid|default=''} ``` -------------------------------- ### Initiate WeChat JSAPI Payment with wx.chooseWXPay Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/test/jsapi.html This snippet demonstrates how to configure WeChat's JSAPI and initiate a payment using `wx.chooseWXPay`. It requires the WeChat JS SDK and payment configuration parameters. The function handles the payment process and provides success callbacks. ```JavaScript wx.config(JSON.parse('{$configJson|raw}')); document.getElementById('paytest').onclick = function () { let options = JSON.parse('{$optionJson|raw}'); options.success = function () { alert('支付成功'); }; console.log("OPTIONS:", options); wx.chooseWXPay(options); } ``` -------------------------------- ### JavaScript Audio Player Control Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/api/view/voice.html Controls the play/pause state of an audio element and updates a button's class to reflect the state. It attaches an error handler and an onclick handler to the button, and uses setInterval to periodically update the button's appearance. ```javascript (function (audio, button) { audio.onerror = function () { button.className = 'icon icon-play'; }; button.onclick = function () { audio.paused ? audio.play() : audio.pause() }; button.onapply = function () { button.className = audio.paused ? 'icon icon-play' : 'icon icon-pause'; }; setInterval(button.onapply, 500), button.onapply(); })(document.getElementById('AudioSrc'), document.getElementById('AudioBtn')); ``` -------------------------------- ### Initialize Menu Table with Layui Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/menu/index.html Initializes the '#MenuTable' using Layui's data table component. Configures table features like even row styling, full height, pagination, default sorting, and dynamic filtering based on 'type' and 'pid' where clauses. It also defines column configurations including checkboxes, sortable fields, icons, menu titles, URLs, status switches, and action toolbars. ```JavaScript $(function () { $('#MenuTable').layTable({ even: true, height: 'full', page: false, sort: { field: 'sort desc,id', type: 'asc' }, where: { type: '{$type|default="index"}', pid: '{$pid|default=""}' }, filter: function (items) { var type = this.where.type; return items.filter(function (item) { return !(type === 'index' && parseInt(item.status) === 0); }); }, cols: [[ {checkbox: true, field: 'sps'}, {field: 'sort', title: '{:lang("排序权重")}', width: 100, align: 'center', templet: '#SortInputTpl'}, {field: 'icon', title: '{:lang("图 标")}', width: 80, align: 'center', templet: '<div><i class="{{d.icon}} font-s18"></i></div>'}, {field: 'title', title: '{:lang("菜单名称")}', minWidth: 220, templet: '<div><span class="color-desc">{{d.spl}}</span>{{d.title}}</div>'}, {field: 'url', title: '{:lang("跳转链接")}', minWidth: 200}, {field: 'status', title: '{:lang("使用状态")}', minWidth: 120, align: 'center', templet: '#StatusSwitchTpl'}, {toolbar: '#toolbar', title: '{:lang("操作面板")}', minWidth: 150, align: 'center', fixed: 'right'} ]] }); }); ``` -------------------------------- ### Masonry Layout Initialization and Event Handling Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/news/index.html Initializes a masonry layout for article items using jQuery Masonry and Layui. It attaches hover event listeners to show/hide action tools, handles AJAX form submissions for deletion, and re-initializes the layout after item removal. Includes confirmation dialogs for deletion. ```javascript $.msg.loading(); require(['jquery.masonry'], function (Masonry) { layui.layer.closeAll(); $('#news-box').removeClass('layui-hide'); var newsbox = document.querySelector('#news-box'); var msnry = new Masonry(newsbox, { itemSelector: '.news-item', columnWidth: 0 }); msnry.layout(); $('body').on('click', '["data-news-del"]', function (event) { $.msg.confirm('确定要删除图文吗?', function (index) { $.msg.close(index); $.form.load('{:url("remove")}', {value: 0, field: 'delete', id: $(event.target).data('news-del')}, 'post', function (ret) { if (ret.code) { $(event.target).parents('.news-item').remove(); msnry = new Masonry(newsbox, { itemSelector: '.news-item', columnWidth: 0 }); return msnry.layout(), (msnry.items.length < 1 && $.form.open('{:url("index")}')), $.msg.success(ret.info), false; } else { return $.msg.error(ret.info), false; } }); }); }); }); ``` -------------------------------- ### ThinkAdmin Storage Configuration - General Notes Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/storage-local.html Provides essential information regarding local file storage, including the default directory, naming convention, and critical requirements for file system permissions and disk space. ```APIDOC ThinkAdmin Local File Storage: - Storage Location: Files are stored locally, defaulting to the `public/upload` directory. - Naming Convention: Files are named using a HASH value. - Permissions: The storage directory requires read and write permissions. - Disk Space: Sufficient disk space must be available. - Limitation: Local storage does NOT support image compression. ``` -------------------------------- ### Layui Table Initialization and Event Handling Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/base/index.html Initializes a Layui table with specific column configurations, sorting, and filtering. It also includes event listeners for status switches and data operations like edit and delete, using ThinkPHP's URL generation and authorization checks. ```javascript $(function () { // Initialize table component $('#BaseTable').layTable({ even: true, height: 'full', sort: {field: 'sort desc,id', type: 'asc'}, where: {type: '{$type|default=""}'}, cols: [[ {checkbox: true, fixed: true}, {field: 'sort', title: '{:lang("排序权重")}', width: 100, align: 'center', sort: true, templet: '#SortInputTpl'}, // {field: 'type', title: '数据类型', minWidth: 140, align: 'center'}, {field: 'code', title: '数据编码', width: '20%', align: 'left'}, {field: 'name', title: '数据名称', width: '30%', align: 'left'}, {field: 'status', title: '数据状态', minWidth: 110, align: 'center', templet: '#StatusSwitchTpl'}, {field: 'create_at', title: '创建时间', minWidth: 170, align: 'center', sort: true}, {toolbar: '#toolbar', align: 'center', minWidth: 150, title: '数据操作', fixed: 'right'}, ]] }); // Data status switch operation layui.form.on('switch(StatusSwitch)', function (obj) { var data = {id: obj.value, status: obj.elem.checked > 0 ? 1 : 0}; $.form.load("{:url('state')}", data, 'post', function (ret) { if (ret.code < 1) $.msg.error(ret.info, 3, function () { $('#BaseTable').trigger('reload'); }); return false; }, false); }); }); ``` -------------------------------- ### Display Alist Access Protocol Options Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/config/storage-alist.html Renders selectable options for the Alist storage access protocol (HTTP, HTTPS, AUTO). It dynamically displays the currently selected protocol. ```html {foreach \['http'=>'HTTP','https'=>'HTTPS','auto'=>"AUTO"] as $protocol=>$remark} {if sysconf('storage.alist_http_protocol') eq $protocol} {$remark} {else} {$remark} {/if} {/foreach} ``` -------------------------------- ### Initialize User Table with Layui Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/admin/view/user/index.html Configures and initializes a Layui data table for displaying user information. It defines columns, sorting, filtering, and includes event handlers for status switches and toolbar actions. ```javascript $(function () { $('#UserTable').layTable({ even: true, height: 'full', sort: {field: 'sort desc,id', type: 'desc'}, where: {type: '{$type|default="index"}'}, cols: [[ {checkbox: true, fixed: true}, {field: 'sort', title: '{:lang("排序权重")}', width: 100, align: 'center', sort: true, templet: '#SortInputTpl'}, { field: 'headimg', title: '{:lang("头像")}', width: 60, align: 'center', templet: function (d) { if (!d.headimg) return '-'; return layui.laytpl('<div class="headimg headimg-ss shadow-inset margin-0" data-tips-image data-tips-hover data-lazy-src="{{d.headimg}}"></div>').render(d); } }, {field: 'username', title: '{:lang("登录账号")}', minWidth: 100, align: 'center', templet: '<div>{{d.username||"-"}}</div>'}, {field: 'nickname', title: '{:lang("用户名称")}', minWidth: 100, align: 'center', templet: '<div>{{d.nickname||"-"}}</div>'}, /* {notempty name='bases'} */ { field: 'usertype', title: '{:lang("角色身份")}', minWidth: 100, align: 'center', templet: function (d) { d.userinfo = d.userinfo || {}; return d.userinfo.code ? (d.userinfo.name + ' ( ' + d.userinfo.code + ' ) ') : '-'; } }, /* {/notempty} */ // {field: 'contact_mail', title: '联系邮箱', minWidth: 80, templet: '<div>{{d.contact_mail||"-"}}</div>'}, // {field: 'contact_phone', title: '联系电话', minWidth: 80, templet: '<div>{{d.contact_phone||"-"}}</div>'}, {field: 'status', title: '{:lang("使用状态")}', align: 'center', minWidth: 110, templet: '#StatusSwitchTpl'}, {field: 'login_num', title: '{:lang("登录次数")}', align: 'center', minWidth: 100, sort: true}, {field: 'login_at', title: '{:lang("最后登录")}', align: 'center', minWidth: 170, sort: true}, {field: 'create_at', title: '{:lang("创建时间")}', align: 'center', minWidth: 170, sort: true}, {toolbar: '#toolbar', title: '{:lang("操作面板")}', align: 'center', minWidth: 180, fixed: 'right'} ]] }); // 数据状态切换操作 layui.form.on('switch(StatusSwitch)', function (obj) { var data = {id: obj.value, status: obj.elem.checked > 0 ? 1 : 0}; $.form.load("{:url('state')}", data, 'post', function (ret) { if (ret.code < 1) $.msg.error(ret.info, 3, function () { $('#UserTable').trigger('reload'); }); else { $('#UserTable').trigger('reload') } return false; }, false); }); }); ``` -------------------------------- ### Template Engine: Displaying Content with Defaults Source: https://github.com/zoujingli/thinkadmin/blob/v6/app/wechat/view/auto/form.html Renders content from a variable, applying raw HTML processing and a default message if the content is empty. ```php {$vo.content|raw|default='说点什么吧'} ```