一、环境布署
1、解析域名时,请解析到根目录下的web目录
2、解析完成后,添加伪静态,如nginx规则:
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
- location /admin {
- try_files $uri $uri/ /admin/index.php?$query_string;
- }
- location /api {
- try_files $uri $uri/ /api/index.php?$query_string;
- }
二、系统安装
- php init // 初始化,选择生产环境还是开发环境
- composer install // 安装vendor包
- //先去common/config/main-local.php修改数据库连接信息
- php yii migrate/up // 导入数据表或者./yii
- php ./yii password/init // 重置后台用户名密码
- ## composer可以设置忽略版本匹配,命令是:
- composer install --ignore-platform-reqs
- ## or
- composer update --ignore-platform-reqs
安装成功会生成一个安装文件:web/storage/install.txt,加载第三方模块 / 插件时会判断这个文件是否存在,所以如果有报错,请一定检查一下
安装xlswriter扩展,用于解析excel文件,替代PhpSpreadsheet
- pecl install xlswriter
- ##PECL 安装时将会提示是否开启读取功能,请键入 yes;
安装完成后,修改php.ini,添加:
- extension = xlswriter.so
安装完成后,可以输入命令查看已安装的扩展:php -m
用法示例可以参考【数据采集】扩展模块
1、安装成功后,先进入系统变量,修改相关参数:
基本属性——网站地址
基本属性——API地址
基本属性——附件地址
基本属性——附件URL
图片设置——图片存储方式(默认为本地存储,支持OSS存储)
2、更新缓存与栏目目录
右上角的头像——系统刷新,按顺序点:
清除临时文件和数据 -> 恢复栏目目录 -> 更新栏目关系
二、view视图需在资源包的末尾添加js或css
- <?php $this->beginBlock('js') ?>
- <script>
- </script>
- <?php $this->endBlock() ?>
三、安装成功后,会在/web/storage 目录创建一个install.txt
卸载时除了将数据库清空以外,还需要删除这个文件,否则会报错,用于加载扩展模块
关于a链接跳转说明:
- <a href="javascript:void(0)">点我不动</a>
- <a href="/xxxx/url" data-ajax='1' data-target="_blank" data-width="" data-height="" data-title="">点我出弹出窗</a>
- <a href="/xxxx/url">在当前TAB内刷新并打开一个链接,TAB标题都会跟着换</a>
- <a href="/xxxx/url" target="_blank">创建一个新的TAB内容</a>
- <a href="/xxxx/url" data-frame="false">打开新链接</a>
- <a href="/xxxx/url" data-location="1">在当前TAB打开一个链接,当前TAB标题等保持现状</a>
如果发现加了target="_blank"不仅跳新标签页,当前页同时也更新了,注意一下是不是pjax影响了
四、获取下拉列表
无限级下拉列表
- /**
- * 获取下拉树列表
- *
- * @param string $id
- * @return array
- */
- public static function getDropDownList($id = '')
- {
- $list = self::find()
- ->andFilterWhere(['<>', 'id', $id])
- ->select(['id', 'parent_id', 'title'])
- ->orderBy('sort asc,id asc')
- ->asArray()
- ->all();
- $tree = Tree::build($list,'id', 'parent_id', 'children', 0);
- return self::generationDropDown($tree);
- }
- /**
- * 生成下拉选择的列表结束
- * @param array $tree
- * @param array $result
- * @param int $deep
- * @param string $separator
- * @return array
- */
- protected static function generationDropDown($tree = [], &$result = [], $deep = 0, $separator = '--'){
- $deep++;
- foreach ($tree as $list) {
- $result[$list['id']] = str_repeat($separator, $deep - 1) . $list['title'];
- if (isset($list['children'])) {
- self::generationDropDown($list['children'], $result, $deep);
- }
- }
- return $result;
- }
一维数组下拉列表:
- /**
- * 获取全部数据表的下拉列表
- * @param string $id
- * @return array
- */
- public static function getDropDownList($id = ''){
- $res = self::find()->andFilterWhere(['<>', 'id', $id])->asArray()->all();
- return ArrayHelper::map($res, "id", "title");
- }
form调用:
- <?= $form->field($model, 'parent_id')->dropDownList($model::getDropDownList(), ['encode' => false, 'prompt' => '请选择', 'data-plugin' => 'selectpicker', 'data-style' => 'btn-select']) ?>
输入身份证号,自动赋值出年月 + 性别
- <?php $this->beginBlock('js') ?>
- <script>
- var $cardNoInput = $("#<?= Html::getInputId($model, 'card_no') ?>");
- var $birthdayInput = $("#<?= Html::getInputId($model, 'birthday') ?>");
- var url = "<?= \yii\helpers\Url::to(['generate-slug']) ?>";
- $cardNoInput.on('blur', function () {
- const idCard = $cardNoInput.val();
- const birth = getBirth(idCard);
- if (birth) {
- $birthdayInput.val(birth);
- }
- const sex = getSex(idCard);
- //循环单选按钮
- console.log(sex);
- $("input[name='OrganizationMemberForm[gender]']").each(function(index, element) {
- //判断当前按钮的值与input的值是否一致,一致则赋值
- // console.log($(this).val());
- if($(this).val()==sex){
- $(this).prop("checked",true);
- }else{
- $(this).prop("checked",false);
- }
- });
- });
- /**
- * @param idCard
- */
- function getBirth(idCard) {
- var birthday = "";
- if (idCard != null && idCard != "") {
- console.log(idCard.length)
- if (idCard.length == 15) {
- birthday = "19" + idCard.slice(6, 10);
- } else if (idCard.length == 18) {
- birthday = idCard.slice(6, 12);
- } else {
- $.modal.alert("身份证号位数有误");
- return false;
- }
- birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2");
- //通过正则表达式来指定输出格式为:1990-01-01
- }
- return birthday;
- }
- function getSex(idCard) {
- var sexStr = '';
- if (parseInt(idCard.slice(-2, -1)) % 2 == 1) {
- sexStr = 0;//'man';
- } else {
- sexStr = 1;//'woman';
- }
- return sexStr;
- }
- </script>
- <?php $this->endBlock() ?>
输入身份证号,解析年/月/日
- /**
- * @param idCard
- */
- function getBirth(idCard) {
- var birthday = "";
- if (idCard != null && idCard != "") {
- if (idCard.length == 15) {
- birthday = "19"+idCard.substr(6,6);
- } else if (idCard.length == 18) {
- birthday = idCard.substr(6,8);
- } else {
- this.$baseJs.msg("身份证号位数有误");
- return false;
- }
- birthday = birthday.replace(/(.{4})(.{2})/,"$1-$2-");
- //通过正则表达式来指定输出格式为:1990-01-01
- }
- return birthday;
- }
保存base64图片入库
- $picpath = $data['srcpic_data'];
- $saveDir = "/discern-helmet/" . date("Ymd") . "/";
- $base64Img = "data:image/jpg;base64,".$picpath; //统一保存为jpg格式,由于前面没有这一串,所以手动拼接上
- $img_url = Attachment::uploadFromBase64($saveDir,$base64Img,"oss");
API模块中,model中添加extraFields附加字段
api/models/Document.php
- class Document extends \common\modules\document\models\Document
- {
- public function fields()
- {
- return [
- 'id',
- 'title',
- 'category' => function ($model) {
- return $model->categoryTitle;
- },
- 'category_id',
- 'view',
- 'description',
- 'user_id',
- 'published_at',
- ];
- }
- /**
- * 附加字段
- * @return array|false
- */
- public function extraFields()
- {
- return [
- 'module',
- 'content' => function ($model) {
- if($model->module == "article"){
- return $model->data->content;
- }else{
- return "";
- }
- },
- ];
- }
- }
在控制器中使用:
- public function actionView($id)
- {
- \Yii::$app->request->setQueryParams(['expand' => 'content,module']);
- $model = Document::find()->where(['id' => $id])->with("data")->one();
- if ($model === null) {
- throw new NotFoundHttpException('信息不存在,请联系管理员');
- }
- return $model;
- }
从post中保存图片入库
首先,数据需要是form-data,然后需要添加enctype=multipart/form-data
视图:
- <?php
- use common\helpers\Html;
- use backend\widgets\ActiveForm;
- ?>
- <div class="page material-create">
- <div class="page-content">
- <?php $form = ActiveForm::begin([
- 'options' => [
- "enctype" => "multipart/form-data",
- ],
- ]); ?>
- <div class="panel">
- <div class="panel-body">
- <div class="form-group form-material">
- <label class="col-form-label" for="select">选择项目</label>
- <?= Html::dropDownList("project_id", null, \common\models\Project::getDropDownList(), ['encode' => false, 'class' => 'form-control']) ?>
- </div>
- <div class="form-group form-material">
- <label class="col-form-label" for="inputFile">文件域</label>
- <input type="text" class="form-control" placeholder="请选择文件.." readonly="">
- <input type="file" id="inputFile" name="file">
- </div>
- </div>
- <div class="panel-footer">
- <button class="btn btn-primary">开始导入</button>
- </div>
- </div>
- <?php ActiveForm::end(); ?>
- </div>
- </div>
控制器:
- public function actionUpload(){
- if (Yii::$app->request->isPost){
- $post = Yii::$app->request->post();
- $path = date("Ymd")."/"; //后缀一定要加/
- $file = UploadedFile::getInstancesByName("file");
- $uploadFile = Attachment::uploadFromPost($path,$file[0],"local");
- p($uploadFile);
- }
- return $this->render('upload');
- }
JS插件初始化,应用场景,pjax请求后,页面需要重新加载JS:
- $(document).on('pjax:complete', function() {
- // init();
- $.components.init('switchery',window);
- // $.components.init(window); //初始化插件
- })
请求第三方URL,形成日志,记录回调以及传参
- $api = "";
- $params = [
- "key" => "value"
- ];
- $res = Yii::$app->services->logExternal->post(true,$api,$params);
处理base64编码的图片转为本地或oss图片
- public function beforeSave($insert)
- {
- parent::beforeSave($insert);
- if(!$this->id){
- $this->id = StringHelper::uuid('uniqid');
- // throw new Exception("ID不能为空");
- }
- // 筛出所有图片
- $this->tigan = $this->processingEditorContent($this->tigan); // 题干
- $this->choices = $this->ProcessingEditorChoicesContent($this->choices); // 选择项
- return true;
- }
- // 这里选择项和题干单独处理,是由于题干只是由base64组合的一段string,而选择项它是由json字符串组合的,那么在转义的过程中,在src里面就要求格式是src=\"xxxx.jpg\",前后分别多两个反斜杠
- /**
- * 转换编辑器内容,将base64的内容替换为本地文件
- * @param $content
- * @return string|string[]|null
- */
- public static function ProcessingEditorContent($content){
- $text = preg_replace_callback('/<img.*?src="(.*?)".*?\/>/', function ($matches){
- $image = $matches[1];
- if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $image, $result)) {
- $path = date("Ymd")."/";
- $url = Attachment::uploadFromBase64($path,$image,"local");
- return str_replace($image,$url,$matches[0]);
- }else{
- return $image[0];
- }
- }, $content);
- return $text;
- }
- /**
- * 选择项是json字符串,被转义了,所以需要重新处理一下格式
- * @param $content
- * @return array|string|string[]|null
- * @throws \yii\base\Exception
- */
- public static function ProcessingEditorChoicesContent($content){
- // 考虑到JSON传参,那么在src前面还有转义的反斜杠,这里一并加入规则处理
- $text = preg_replace_callback('/\<img.*?src=.*?"(.*?)".*?\/>/', function ($matches) {
- $image = $matches[1];
- if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $image, $result)) {
- $path = date("Ymd")."/";
- $url = Attachment::uploadFromBase64($path,$image,"local");
- // 考虑到JSON传参,在src前面有转义的反斜杠,那么在尾部也应该有一个反斜杠
- return str_replace($image,$url . "\\",$matches[0]);
- }else{
- return $image[0];
- }
- }, $content);
- return $text;
- }