作者归档:admin

自助打印-技术文档

计划任务

php think printer:printer_money  
php think printer:printer_pay 

智能证件照接口

http://dev.id-photo-verify.com/doc.html

配置参数

# 制作并检测证件照	
printer_ai_key = 
# 制作并裁剪换正装
printer_ai_change_dress =  

文档转PDF

https://market.aliyun.com/products/56928005/cmapi00044564.html

身份证去除背景

可在后台配置

https://www.textin.com

pip3 install --upgrade pip
yum install -y rh-python38 which
pip3 install backgroundremover 

配置命令行

backgroundremover = /opt/rh/rh-python38/root/usr/local/bin/backgroundremover

默认为 /opt/rh/rh-python38/root/usr/local/bin/backgroundremover

试卷翻新

https://www.textin.com/experience/text_auto_removal

解压zip、7z、gz、tar、bz2包

yum -y install p7zip unar unzip

PDF 依赖

yum install ImageMagick ImageMagick-devel ghostscript pdftk  poppler-utils  perl-Image-ExifTool.noarch 

安装 libreoffice

doc xls ppt转pdf

yum install libreoffice  

GX

yum install python3
如果提示requests模块不存在
pip install --upgrade pip
pip install requests
如果提示secrets模块不存在
pip install python-secrets -i https://pypi.tuna.tsinghua.edu.cn/simple
如果上面的secrets不能安装可尝试
pip install virtualenv
virtualenv myenv
source myenv/bin/activate 
后再执行 
如果报urllib3错误,说明 urllib3与chardet版本不一致,使用以下方式解决
pip uninstall urllib3 chardet 
pip install --upgrade requests

管理员菜单

当菜单过多时可进行分组显示。

代码

set_menu_group('视频商城',[
    '/a_shop_store/shop/index',
    '/a_shop_store/store/index',
    '/mall/goods',
    '/mall/order/video',
    '/fx/admin', 
    '/enroll/admin', 
    '/video/group',
]);

set_menu_group('管理',[
    '/admin/member',
    '/admin/config',  
    '/admin/user',  
    '/webtool/admin',  
]);

uniapp监听事件

演示代码请根据实际需要进行修改

注:需要在同一域名下

H5的PHP代码

<script type="text/javascript" src="<?=cdn_url()?>/lib/uni.webview.1.5.5.js"></script>  
<?php  
$vue->created(['load_vue()']);
$vue->data('uni',"");
$vue->method("load_vue()","
document.addEventListener('UniAppJSBridgeReady', function() {  
    _this.uni = uni;   
});
"); 
$vue->method("test()"," 
	_this.uni.postMessage({ 
    data:{
       action:'login',  
       data:res.data, 
    }
  });  
"); 
?>

data结构

data:{data:{user_id:'',token:''}}

UNIAPP

<template>
	<view>
		<web-view :src="url" ref="view" @message="message"></web-view>
	</view>
</template>

<script>
	var _this
	export default {
		data() {
			return {
				url: ''
			}
		},
		onLoad() {
			_this = this
			this.url = this.config.domain + '/applet/login'
			// #ifdef H5   
			window.addEventListener("message", receive_message, false); 
			function receive_message(event) {
				let res = event.data.data.arg
				let action = res.action
				let d = res.data
				_this.login_listen(action, d)
			}
			// #endif
		},
		methods: {
			message(e) {
				console.log('on message')
				console.log(e)
				let res = e.detail.data[0]
				let d = res.data
				let action = res.action
				_this.login_listen(action, d)
			},
			login_listen(action, d) {
				if (action == 'login') {
					if (d.token) { 
						uni.navigateBack()
					}
				}
			}
		}
	}
</script> 

客服APP

主要用于多商户系统,

客户点击商家联系图标弹出聊天窗口,发送信息,商家在PC端或APP端收到来自客户的信息并进行回复。

当客户点击系统的平台客服时弹出聊天窗口,平台客服在PC或APP端到来自客户的信息并进行回复。

PC、H5、APP聊天基础功能,PC直接用URL注册、登录后打开IM页面就可以聊天了。

PC 界面

H5、APP

已知问题

  1. PC注册、登录未加sign
  2. 消息未加离线
  3. APP未加通知

注意:为了APP登录安全建议开启腾讯云验证码

点击发送验证码时效果

技术部分

服务端配置

location / {
  limit_req zone=nglimit burst=100 nodelay;
  if (!-e $request_filename) {
    rewrite  ^(.*)$  /index.php?s=$1  last;
  } 
}
location /uploads/ {
    try_files $uri /image_cache/index.php/$uri;
}

location /wss {
    proxy_pass http://127.0.0.1:10001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header X-Real-IP $remote_addr;
} 

location /ws {
    proxy_pass http://127.0.0.1:10001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header X-Real-IP $remote_addr;
} 

分销

项目 bbc_video (多用户视频商城系统)

模块 fx

平台后台请访问左侧 分销菜单

小程序

点击提现

发起提现

点击直拉邀请、间接邀请等

点击邀请好友

joomla

语言包

1.后台安装语言包

/administrator/index.php?option=com_installer&view=languages

2.选择中文

注意有前台、后台区别

/administrator/index.php?option=com_languages&view=installed&client=1

Nginx 限流

在nginx主配置中加

http {
     limit_req_zone $binary_remote_addr zone=nglimit:100m rate=200r/s; 
}

100m 用于指定限流区域 nglimit 所占用的内存空间。这个值通常需要根据服务器的性能和预期的请求频率来合理设置。内存的分配越大,存储的状态信息越多,可以更准确地进行请求限流,但也会占用更多的服务器内存。

200r/s 每秒允许的请求频率

站点中修改

location / {
  limit_req zone=nglimit burst=100 nodelay; 
}
  • burst=100 允许的突发请求数等。

以宝塔为例

NG

站点

burst 参数用于设置允许的突发请求数。这个参数指定了在限流策略生效时,允许在一次请求周期内突发处理的最大请求数量。当达到限流的请求频率时,如果有突发请求超过了指定的 burst 数量,Nginx 会暂时允许处理这些突发请求,而不会立即进行限流处理。

换句话说,burst 参数用于控制限流策略在短期内对突发请求的处理方式。例如,如果您设置了 rate=200r/s(每秒允许请求频率为 200 次)和 burst=100,那么在一秒钟内允许的请求数为 200 个,但如果有突发请求,最多可以允许处理 300 个请求,以平滑处理请求峰值。

内容类型

这是一个实验性软件,为了减少书写表格、表单、接口、权限而开发。

能够有效的处理一些业务场景。可以少写代码甚至不写代码即可完成后端开发。

  • 内容类型
  • 内容管理
  • 内容权限
  • 内容接口

当有 author字段及status字段时,后台仅能审核。

status对应值 ok err wait

接口调用只是自己的需传 use_author = 1

内容类型:用于创建不同的内容类型,管理字段,配置列表、表单、搜索

内容管理:用于管理由内容类型创建的内容。支持列表显示、添加、编辑、删除、搜索操作。

部分截图

接口

/cck/api_content/pager?_type=blog
/cck/api_content/tree?_type=blog
/cck/api_content/view?_type=blog&id=6625d47712650dfe9f0314a3

表单2.0

https://github.com/thefunpower/element

安装

在composer.json中添加

composer require thefunpower/element

使用

搜索

<?php 
echo element("filter",[ 
    'data'=>'list',
    'url'=>'/video/group/get_pager',
    'is_page'=>true,
    'init'=>true,
    [
        'type'=>'input','name'=>'title',
        'attr_element'=>[
            'placeholder'=>'名称',
        ],
    ],
]); 
?>

表格

<?php 
echo element('table',[
    ['name'=>'open',':data'=>'list',':height'=>'height'],
    ['name'=>'column','prop'=>'title','label'=>'名称','width'=>''],
    ['name'=>'column','prop'=>'count','label'=>'成员数','width'=>''],
    ['name'=>'column','prop'=>'count','label'=>'操作','width'=>'100',
      'tpl'=>[
          ['name'=>'button','label'=>'成员','@click'=>'show_user(scope.row)'],
          ['name'=>'button','label'=>'编辑','@click'=>'edit(scope.row)','style'=>'margin-left: 20px;'],
       ]
    ],
    ['name'=>'close'],
]);
?> 

分页

<?php 
echo element("pager",[ 
    'data'=>'list',
    'url'=>'/video/group/get_pager', 
    'reload_data'=>[]
]); 
?> 

表单

echo element('form',[ 
    ['type'=>'open','model'=>'form','label-width'=>'180px'],
    [
        'type'=>'input','name'=>'title','label'=>'标题',
        'attr'=>['title'=>'演示标题'],
    ],
    [
        'type'=>'color','name'=>'aa31','label'=>'color', 
    ],
    [
        'type'=>'datetime','name'=>'aa32','label'=>'datetime', 
    ],
    [
        'type'=>'time','name'=>'aa33','label'=>'time', 
    ],
    [
        'type'=>'tag','name'=>'tag','label'=>'tag', 
    ],
    [
        'type'=>'sku','name'=>'sku','label'=>'sku',         
        'js'=>"app.add_media('upload_spec');"
    ],
    [
        'type'=>'checkbox','name'=>'checkbox','label'=>'多选',
        'value'=>[['label'=>'选项1','value'=>1],['label'=>'选项2','value'=>2],], 
    ],
    [
        'type'=>'radio','name'=>'radio','label'=>'radio',
        'value'=>[['label'=>'选项1','value'=>1],['label'=>'选项2','value'=>2],], 
    ],
    
    [
        'type'=>'text','name'=>'text','label'=>'text', 
        'attr'=>['required',],
        'attr_element'=>[':rows'=>10],
    ],

    [
        'type'=>'editor','name'=>'editor','label'=>'editor',  
    ],

    [
        'type'=>'attribute','name'=>'attribute','label'=>'attribute', 
        'value'=>[ ['label'=>'选项1','value'=>1],['label'=>'选项2','value'=>2],],  
    ],

    [
        'type'=>'select','name'=>'select1','label'=>'select单选', 
        'value'=>[ ['label'=>'选项1','value'=>1],['label'=>'选项2','value'=>2],],  
    ],
    [
        'type'=>'select','name'=>'select2','label'=>'select多选', 
        'value'=>[ ['label'=>'选项1','value'=>1],['label'=>'选项2','value'=>2],], 
        'attr_element'=>['multiple'],
    ],
    [
        'type'=>'date','name'=>'date1','label'=>'时间', 
        'attr'=>['title'=>''], 
        'attr_element'=>[':picker-options'=>'pickerOptions','align'=>"center"],
    ],
    [
        'type'=>'autocomplete','name'=>'aa','label'=>'autocomplete', 
        'url'=>'/video/group/autocomplete',  
    ],

    [
        'type'=>'cascader','name'=>'bb','label'=>'cascader', 
        //':props'="{ checkStrictly: true }",
        'url'=>'/video/group/cascader', 
        'attr_element'=>[':props'=>"{value:'id',label:'label'}"],
    ],

    [
        'type'=>'upload','name'=>'fiel','label'=>'上传', 
        'url'=>'/upload',
        'mime'=>'jpg',
        'multiple', 
    ],
    ['type'=>'close']
]);

对form操作

<?php 
$vue->method("save"," 
let url = '/dry/index/do_add';
if(this.form.id){
    url = '/dry/index/do_edit';
}
ajax(url,this.form,function(res){
    ".vue_message()."
    if(app.code == 0){
        app.load_filter_list();
    }
});
");
$vue->method("close"," 
this.is_add = false;
");
?> 

ajax


public function cascader(){
    $d = \element\form::get_city(); 
    return json_success(['data'=>$d]);
}

public function autocomplete(){
    $arr[] = ['id'=>1,'value'=>'test'];
    $arr[] = ['id'=>2,'value'=>'test22'];
    return json($arr);
}

sku

think_vue_media($vue,"
if(app.upload_spec_field == 'sku'){
    for(let i in dd){
        if(dd[i] && dd[i].url){
            this.form[this.upload_spec_field][this.upload_spec_index].img = dd[i].url;   
            return;       
        } 
    }   
}"," 
    this.selected_media_use_muit = false; 
");

效果

在NetteAdmin中使用

控制器

AdminWithController 是兼容门店后台功能,当继承此类时需要配置

protected $auth = ['admin','store'];

$auth属性默认是 admin,可修改为 store 或 [‘admin’,’store’]

其中 admin表示管理员权限,store表示门店权限。

<?php 
namespace app\kefu\controller;
 
use app\AdminController; 
use hg\apidoc\annotation as Apidoc; 
/**
* @Apidoc\Title("API 客服管理")
*/
class Admin extends AdminController
{  
    use \app\CRUD;
    //protected $ignore_auth  = true;
    protected $auth_name  = 'novel_chapter';
    protected $table  = 'kefu_user';
    protected $validate_add  = 'app\kefu\validate\User.add';
    protected $validate_edit = 'app\kefu\validate\User.edit';
    protected $field  = [
        'name',
        'avatar_url', 
        'user_id',  
    ];
    /**
    * 分页条件查寻
    */
    protected function pager_where(&$where,$input = []){}
    /**
    * 分页每行数据
    */
    protected function get_row(&$v){}
    /**
    * init 前
    */
    protected function before_init(){}
    /**
    * 写入数据前
    */
    protected function insert($data){}
    /**
    *写入数据后
    */
    protected function after_insert($data,$id){}
    /**
    * 更新数据前
    */
    protected function update($data,$id){}
    /**
    * 更新数据后
    */
    protected function after_update($data,$id){}
    /**
    * 删除前
    */
    protected function del($id){}
    /**
    * 删除后
    */
    protected function after_del($id){} 
  
    protected function form(){  
      $form = get_kefu_user_form_field(); 
      return $form; 
    }
      
}

验证类

https://doc.thinkphp.cn/v8_0/rule_buildin.html

<?php 
namespace app\kefu\validate; 
class User extends \FormValidate
{
    protected $rule = [ 
        'name'  =>  'require', 
        'user_id'  =>  'require', 
    ];
  
    protected $message  =   [
        'name.require'    => '客服名必须',  
        'user_id.require' => '第三方用户ID必须',  
    ];
  
    protected $scene = [
        'add'  =>  ['name','user_id'],
        'edit' =>  ['name','user_id'], 
    ];    
  
    public function form_validate_field(){ 
        return get_kefu_user_form_field();
    } 
}

VUE

$vue->method("save()","
    const loading = this.\$loading({
      lock: true,
      text: '处理中,请稍等',
      spinner: 'el-icon-loading',
      background: 'rgba(0, 0, 0, 0.7)'
    });
    this.form.tag = 'blog';
    if(this.form.id){
        $.post('/blog/blog/do_edit',this.form,function(res){
            ".vue_message()."
            if(res.code == 0){
                app.is_open = false;
                app.get_lists();
            }
            loading.close();
        },'json'); 
    }else{
        $.post('/blog/blog/do_add',this.form,function(res){
            ".vue_message()."
            if(res.code == 0){
                app.is_open = false;
                app.get_lists();
            }
            loading.close();
        },'json'); 
    }
       
");

composer源

composer global require slince/composer-registry-manager

composer repo:ls

composer repo:use composer

autoloader后手动添加

global $autoloader;
$autoloader = require __DIR__ . '/../vendor/autoload.php';
$autoloader->addPsr4('app\\', __DIR__.'/../app');