liziyu 发布的文章

在 MySQL 8.0 中,出现该错误提示是因为默认启用了 ONLY_FULL_GROUP_BY SQL 模式。这个模式要求在 GROUP BY 语句中的每个列都必须在 SELECT 列表中出现或使用聚合函数进行聚合。

要完美解决这个问题,有几种方法可以尝试:

1、将 sql_mode 设置为非严格模式:可以在会话级别或全局级别修改 sql_mode,具体取决于你的需求。以下是在会话级别进行修改的示例:

SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

注意:这个方法可能会影响其他部分的代码,因为它会禁用其他严格模式的功能。

2、为非聚合的列添加聚合函数:可以将非聚合的列添加到 GROUP BY 子句中,或者使用聚合函数对这些列进行聚合。如下所示:

SELECT column1, MAX(column2) AS max_column2
FROM table
GROUP BY column1;

根据你的具体需求,选择适当的聚合函数。

3、使用 ANY_VALUE() 函数:另一种解决方法是使用 ANY_VALUE() 函数,该函数可以在 SELECT 语句中引用非聚合列,而无需在 GROUP BY 子句中包含它们。如下所示:

SELECT column1, ANY_VALUE(column2) AS column2
FROM table
GROUP BY column1;

ANY_VALUE() 函数会返回在给定组内的任意一个值。

通常建议采用第3种方式解决。

方法一

省略了,需要修改 mysql.ini 文件,有点麻烦。

方案二

这种就简单了,直接将网站数据库配置文件中的服务器地址配置项改成127.0.0.1即可,tp6.x的位置在config/database.php

注:原因是127.0.0.1对于mysql来说,是TCP/IP连接,不会使用Unix domain socket,不会走mysql.socket。

如下图所示,想要从 roles 中查询 id4 的记录。
WechatIMG141539.jpg

方法一:

$users = DB::table('users')
    ->where('column_name', 'LIKE', '%,4,%')
    ->orWhere('column_name', 'LIKE', '4,%')
    ->orWhere('column_name', 'LIKE', '%,4')
    ->get();

方法二:

$users = DB::table('users')
    ->whereRaw("FIND_IN_SET('4', column_name) > 0")
    ->get();


号外:

还有一种巧妙的设计,就是在值入库时人为增加一个逗号,4,12,14,56,44,65,24,这种。在查询时,直接用以下语句:

$users = DB::table('users')
    ->where('column_name', 'LIKE', '%,4%')
    ->get();

注意这里where('column_name', 'LIKE', '%,4%')的条件,是不是很妙。

将 vue 与 golang 开发的项目部署上线的注意事宜。
1、整理本机的项目端口路径。
2、用 BT 新建一个项目网站点。
3、配置好数据库与 Redis 等。
4、最主要的是 Nignx 的配置,如下:

server
{
    listen 80;
    server_name go.studio.com;
    index index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/go.studio.com/public;

    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #SSL-END

    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    #error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END

    #PHP-INFO-START  PHP引用配置,可以注释或修改
    include enable-php-00.conf;
    #PHP-INFO-END

    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/go.studio.com.conf;
    #REWRITE-END
    
    
    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }

    #一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }

    #禁止在证书验证目录放入敏感文件
    if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
        return 403;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
        error_log /dev/null;
        access_log /dev/null;
    }

    location ~ .*\.(js|css)?$
    {
        expires      12h;
        error_log /dev/null;
        access_log /dev/null;
    }
    
    
    location /api {
        proxy_pass http://127.0.0.1:9985;
        proxy_set_header Host 127.0.0.1:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        add_header X-Cache $upstream_cache_status;
        proxy_set_header X-Host $host:$server_port;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 30s;
        proxy_read_timeout 86400s;
        proxy_send_timeout 30s;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    
    # 开启 gzip 功能
    gzip on;
    gzip_min_length 10k;
    gzip_comp_level 9;
    gzip_types text/plain text/css application/javascript application/x-javascript text/javascript application/xml;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    
    access_log  /www/wwwlogs/go.studio.com.log;
    error_log  /www/wwwlogs/go.studio.com.error.log;
    
    # 显式的根路径配置
    location / {
        try_files $uri $uri/ /manage/index.html;

        # 这里可以添加其他指令或配置
    }
    
}



服务器的截图:
QQ20240318-164854@2x.png

项目打包后默认只能部署在服务器根路径,如果想 http://localhost:5173/admin/ 这种形式,可以根据 vite、vue-router 文档介绍进行配置。

1、在 vite.config.js 中配置:

// ......省略其它代码
export default defineConfig(({ command }) => {
    return {
        // 在这里增加 base 写子路径
        base: '/admin/',  // 注意这里前后都要有斜杠
        // ......省略其它代码
        resolve: { /*......省略*/ }
        // 如果要修改打包后的输出目录可以加这个配置
        build: {
            outDir: 'admin'  // 默认是 dist
        }
    };
});

2、然后在 src/router/index.js 中增加:

// ......省略其它代码
const router = createRouter({
    routes,
    // 给 createWebHistory 方法传参数配置子路径
    history: createWebHistory(import.meta.env.BASE_URL)
});

3、然后重新运行(run dev)或者打包(run build)部署后再访问就可以带上配置的子路径了,也可以在打包的时候动态设置子路径:

npm run build --base=/admin/

App.vue

<script setup>
import {ref} from 'vue'
import Footer from './components/footer.vue'

const uid = ref("")

const userName = (res) =>{
  uid.value = res

}

</script>

<template>
  <div>
    接收子组件值为:{{uid}}
    <hr />
  </div>
<!--Footer上的 name与 age传给的是组件页-->
  <Footer @emitsUserName="userName" name="张小虎" age="22">
<!--#abc是插槽名称,其中 data是用来接收子组件 slot上的属性值-->
    <template #abc="d">
      <!--接收来的属性值直接可以在此使用-->
      {{d.title}} - {{d.score}}
      <!--下面本段文字是直接被子组件 slot显示并装载至父组件内-->
      我是一个小小鸟
    </template>
    <template #cde>
      Footer内的第二个 slot传来的值。
    </template>
  </Footer>
</template>



footer.vue

<script setup>
  const props = defineProps({
    name:{
      type:String,
      required:true,
      default:"默认值哦哦"
    },
    age:{
      type:String,
    },
  });

  var emits = defineEmits(["emitsUserName"]);
  emits("emitsUserName", "Footer子传父亲")
</script>

<template>
<div>
  <div>
    父组件传递过来的值:<h3>{{props.name}} --- {{props.age}}</h3>
    <hr />
  </div>
  <div>
    <slot name="abc" title="我是子组件内 slot上的title" score="100"></slot>
    <hr />
  </div>
  <div>
    <slot name="cde"></slot>
  </div>
</div>
</template>

<style scoped>

</style>

效果:

QQ20240310-165113@2x.png

简述,下述组件的粗略粗略粗略的理解:
其中“:button-style”表示父组件向子组件传值;
其中“@upload”表示,子向父传值,这里接收的是一个事件。
<el-upload
    :button-style="buttonStyle"
    v-model="data"
    @upload="onUpload"
/>



:button-style="buttonStyle" 是将 buttonStyle 这个属性的值从父组件传递给子组件的语法。在父组件中,你可以定义一个名为 buttonStyle 的属性,并将其绑定到子组件的 button-style 属性上。子组件可以使用这个属性值来自定义按钮的样式。

@upload="onUpload" 是父组件监听子组件触发的 upload 事件的语法。在子组件中,当某个操作或条件满足时,你可以使用 this.$emit('upload') 来触发 upload 事件。父组件可以在相应的方法(例如 onUpload)中定义逻辑来响应该事件。

通过这样的方式,父组件可以向子组件传递属性(props)和监听事件(events),实现父子组件之间的数据传递和通信。

总结:

步骤 1、首页在子组件定义组件需要发射的组件事件,数组方式,如:
const emits = defineEmits(["emit_a", "emit_b"])
步骤 2、然后通过返回的变量 emits来执行发射服务,如下:
emits("emit_a", {name:"liziyu",age:20})
步骤 3、在父组件内的子组件标签通过@与事件名emit_a作为接收点,如:
<Footer @emit_a="getEmitsObj" />
其中 getEmitsObj为任意自定义的函数名。
步骤 4、在父组件内,定义getEmitsObj函数,来接收子组件的值。如:
const getEmitsObj = (data) => {console.log(data);}
其中data就是接收到的值,此时可以将它赋值给组件变量,就可以正常使用了。

App.vue

<script setup>
  import { reactive,ref } from 'vue'

  //导入子组件
  import Header from "./components/header.vue"

  //响应式数据
  const web = reactive({
    name: "邓瑞编程",
    url: 'dengruicode.com'
  })

  const user = ref(0)

  //子传父
  const emitsWeb = (data) => {
    console.log("emitsWeb:",data)
    web.url = data.url
  }

  const emitsUser = (data) => {
    console.log("emitsUser:",data)
    user.value += data
  }
</script>

<template>
  <!-- 子传父 -->
  <Header @web="emitsWeb" @user="emitsUser" />

  {{ web.url }} - {{ user }}
</template>

<style scoped></style>


header.vue

<script setup>
    //子组件

    /*
        defineEmits是Vue3的编译时宏函数,
        用于子组件向父组件发送自定义事件
    */
    //子传父
    //定义一个名为 emits 的对象, 用于存储自定义事件
    const emits = defineEmits(["web","user"])
    //发送名为 web 和 user 的自定义事件
    emits("web", {name:"邓瑞",url:"www.dengruicode.com"})
    
    //添加用户
    const userAdd = () => {
        //发送名为 user 的自定义事件
        emits("user", 10)
    }
</script>

<template>
    <h3>Header</h3>

    <button @click="userAdd">添加用户</button>
</template>

<style scoped>

</style>

转自:邓瑞编程

总结:

一、传数组:

步骤 1、在父亲组件内,通过子组件标签属性方式,定义参数名称,如:
<Header propsName="liziyu" propsAge=20 />

步骤 2、然后在子组件页面内,接收两个参数,如:
defineProps(["propsName", "propsAge"])
这样就可以在header 里使用上面两个数组元素了。

二、传对象:

步骤 1、在父组件内,通过子组件标签绑定一个对象参数的名称,如:
reactive({name:"liziyu",age:20})
<Footer v-bind="propsObj" />

步骤 2、在子组件页面内,接收这两个参数,与接收数组不同的是,需要在子组件内定义接收对象各字段类型用于接收对象值(有点像 golang的请求对象的结构体),如:
defineProps({name:String, age:Number})

App.vue

<script setup>
  import { reactive } from 'vue'

  //导入子组件
  //App.vue是父组件,因为它包含了header.vue和footer.vue两个子组件
  import Header from "./components/header.vue"
  import Footer from "./components/footer.vue"

  /*
  const propsWeb = {
    user: 10,
    ip: '127.0.0.1'
  }
  */
  //响应式数据
  const propsWeb = reactive({
    user: 10,
    ip: '127.0.0.1'
  })

  //添加用户
  const userAdd = () => {
    propsWeb.user++
    console.log(propsWeb.user)
  }
</script>

<template>
  <!-- 父传子 - 方式1 -->
  <Header propsName="邓瑞编程" propsUrl="dengruicode.com" />

  dengruicode.com

  <button @click="userAdd">添加用户</button>

  <!-- 父传子 - 方式2 -->
  <!-- <Footer v-bind="propsWeb" /> -->
  <Footer :="propsWeb" />
</template>

<style scoped></style>


header.vue

<script setup>
    //子组件

    //接收方式1 - 数组
    /*
        defineProps是Vue3的编译时宏函数,
        用于接收父组件向子组件传递的属性(props)

        注
        当使用Vue编译器编译包含defineProps的组件时,
        编译器会将这些宏替换为相应的运行时代码
    */
    const props = defineProps(["propsName","propsUrl"])
    console.log(props)
</script>

<template>
    <h3>Header</h3>
</template>

<style scoped>

</style>


footer.vue

<script setup>
    //子组件

    //接收方式2 - 对象
    /*
    const props = defineProps({
        user: Number,
        ip: String
    })
    */
    const props = defineProps({
        user: Number,
        ip: {
            type: String,
            required: true, //true表示必传属性,若未传则会提示警告信息
            default: 'localhost' //未传默认值
        }
    })

    console.log(props)
</script>

<template>
    <h3>Footer</h3>
    user: {{ props.user }}
</template>

<style scoped>

</style>

转自:邓瑞编程

//0表示8进制 644表示权限 os.FileMode(0777).String()进行打印

//- rwx rwx rwx -表示普通文件
//r表示可读
//w表示可写
//x表示可执行
//第1位:文件属性,一般常用的是"-”表示是普通文件;"d"表示是一个目录,

-:代表这是一个普通文件(regular),其中其他文件类型还包括了
d:目录文件(directory)
1:链接文件(link)
b:块设备文件(block)
c:字符设备文件(character)
s:套接字文件(socket)
p:管道文件(pipe)

//第2~4位:文件所有者的权限rwx(可读/可写/可执行)。
//第5~7位:文件所属用户组的权限rwx(可读/可写/可执行)。
//第8~10位:其他人的权限rwx(可读/可写/可执行)。

//在golang中,可以使用os.FileMode(perm).String()来查看权限标识

//os.FileMode(0777).String()
//返回-rwxrwxrwx
//os.FileMode(0666).String()

//返回-rw-rw-rw
//os.FileMode(0644).String()
//返回-rw-r--r-

//0777表示:创建了一个普通文件,所有人拥有所有的读、写、执行权限
//0666表示:创建了一个普通文件,所有人拥有对该文件的读、写权限,但是都不可执行
//0644表示:创建了一个普通文件,文件所有者对该文件有读写权限,用户组和其他人只有读权限,都没有执行权限