创建一个electron桌面备忘录

 

 

Sound Of Silence

1.创建electron项目命令: npm create @quick-start/electron my-new-project

        2选择:√ Select a framework: » vue

        √ Add TypeScript? ... No

        √ Add Electron updater plugin? ... Yes

        √ Enable Electron download mirror proxy? ... Yes

        3.命令:cd my-new-project

        4.命令:yarn

        5.启动命令: yarn dev

        6.打包命令:yarn build:win

 主进程代码index.js:

import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
function createWindow() {// Create the browser window.创建浏览器窗口。const mainWindow = new BrowserWindow({width: 900,height: 670,// 设置窗口的尺寸是否包含窗口边框和标题栏useContentSize: true,// 在创建 Electron 主窗口时禁用窗口外框frame: false,// 控制是否显示的变量show: false,// 设置自动隐藏菜单栏为 trueautoHideMenuBar: true,alwaysOnTop: true,...(process.platform === 'linux' ? { icon } : {}),webPreferences: {preload: join(__dirname, '../preload/index.js'),sandbox: false}})mainWindow.on('ready-to-show', () => {mainWindow.show()})mainWindow.webContents.setWindowOpenHandler((details) => {shell.openExternal(details.url)return { action: 'deny' }})if (is.dev && process.env['ELECTRON_RENDERER_URL']) {mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])} else {mainWindow.loadFile(join(__dirname, '../renderer/index.html'))}
}
app.whenReady().then(() => {electronApp.setAppUserModelId('com.electron')app.on('browser-window-created', (_, window) => {optimizer.watchWindowShortcuts(window)})ipcMain.on('ping', () => console.log('pong'))createWindow()app.on('activate', function () {if (BrowserWindow.getAllWindows().length === 0) createWindow()})
})
app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit()}
})

preload预加载的代码index.js:

import { contextBridge } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'// Custom APIs for renderer
const api = {}// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {try {contextBridge.exposeInMainWorld('electron', electronAPI)contextBridge.exposeInMainWorld('api', api)} catch (error) {console.error(error)}
} else {window.electron = electronAPIwindow.api = api
}

渲染进程的代码main.js:

import './assets/css/main.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

index.html

 

<!doctype html>
<html>
<head><meta charset="UTF-8" /><title></title><!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --><meta http-equiv="Content-Security-Policy" /><!-- content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"  --><!-- <iframe frameborder="0" width="0" height="0"></iframe> -->
</head>
<body><div id="app"></div><script type="module" src="/src/main.js"></script>
</body>
</html>

 App.vue

<template><MyLogs />
</template>
<script setup>
import MyLogs from './components/MyLogs.vue'
</script>

 MyLogs.vue

<template><div><div class="header"><a href="https://blog.csdn.net/lulei5153" title="与妖为邻CSDN博客" class="" target="_blank"><img src="../assets/img/kong.jpg" alt="与妖为邻" style="border-radius: 50%" /></a><button v-if="!formVisible" class="openForm" @click="openForm">编辑</button><button v-if="formVisible" @click="closeForm">取消编辑</button><NowTime /><iframeref="weather"frameborder="0"width="150"height="36"scrolling="no"hspace="0"src="https://i.tianqi.com/?c=code&id=99"style="margin-left: 20px"></iframe><span class="windowTool"><i class="minimize"><img src="../assets/img/最小化.svg" alt="最小化" /></i><i class="maximize"><img src="../assets/img/最大化.svg" alt="最大化" /></i><i class="close"><img src="../assets/img/关闭.svg" alt="关闭" /></i></span></div><formv-if="formVisible"class="draggable-form":style="{ top: formPosition.y + 'px', left: formPosition.x + 'px' }"@submit.prevent="addMemo"><div v-drag drag-min-top="50" class="form-title" @mousedown="startDrag">{{ formTitle }}</div><div class="form-content"><input type="reset" value="重置" /><textarea v-model="newItem" rows="10" placeholder="请输入备注内容"></textarea><button type="submit" class="addBtn">添加</button></div></form><div class="memo" @click="handleMemoAction"><div v-for="(memo, index) in memos" :key="index" class="item"><span class="item-number">{{ index + 1 }}.</span><button v-if="showActions && !memo.finished" @click="completeMemo(index)">完成</button><button v-if="showActions && memo.finished" @click="cancelMemo(index)">取消</button><span class="text-content" :class="{ content: true, finish: memo.finished }">{{ memo.name }}</span><button v-if="showActions && memo.finished" @click="reworkMemo(index)">修改</button><buttonv-if="showActions && memo.finished"v-show="noindex == index ? false : true"class="deleteBtn"@click="deleteMemo(index)">删除</button><span v-show="noindex == index ? true : false" class="alter"><textarea v-model="newItem" rows="10"></textarea><button @click="csu">提交</button></span></div></div></div>
</template>
<script setup>
import NowTime from './NowTime.vue'
import { ref } from 'vue'
import '../assets/css/MyLogs.css'
import Drag from '../assets/js/Drag.js'
const { formTitle, formPosition, startDrag } = Drag()
const formVisible = ref(false)
const newItem = ref('')
const memos = ref([])
const showActions = ref(false)
const noindex = ref(-1)
const openForm = () => {formVisible.value = trueshowActions.value = true
}
const closeForm = () => {formVisible.value = falseshowActions.value = false
}
const reworkMemo = (index) => {if (newItem.value === '' || false) {newItem.value = memos.value[index].namenoindex.value = indexformVisible.value = falseshowActions.value = false} else {newItem.value = ''noindex.value = -1}
}
const csu = () => {if (noindex.value === -1) {return}memos.value[noindex.value].name = newItem.value// 取消备忘录的完成状态memos.value[noindex.value].finished = falsenoindex.value = -1newItem.value = ''saveTodo()
}
const addMemo = () => {if (newItem.value.trim() !== '') {memos.value.push({ name: newItem.value, finished: false })newItem.value = ''formVisible.value = falseshowActions.value = falsesaveTodo()}
}
const completeMemo = (index) => {memos.value[index].finished = truesaveTodo()
}
const cancelMemo = (index) => {memos.value[index].finished = falsesaveTodo()
}
const deleteMemo = (index) => {memos.value.splice(index, 1)updateItemNumbers()formVisible.value = falseshowActions.value = falsesaveTodo()
}
const handleMemoAction = (event) => {const target = event.targetif (target.innerHTML === '完成') {// handle complete action} else if (target.innerHTML === '取消') {// handle cancel action} else if (target.innerHTML === '删除') {// handle delete action}
}
const saveTodo = () => {localStorage.myLogs = JSON.stringify(memos.value)
}
const loadTodo = () => {const savedMemos = JSON.parse(localStorage.myLogs ?? '[]')memos.value = savedMemosupdateItemNumbers()
}
const updateItemNumbers = () => {const itemNumbers = document.querySelectorAll('.item-number')itemNumbers.forEach((item, index) => {item.textContent = index + 1})
}
loadTodo()
</script>
<style scoped></style>

NowTime.vue

<template><div><p>{{ dateTime }}</p><sub>{{ dayTime }}</sub><p>{{ currentTime }}</p></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const dateTime = ref('')
const dayTime = ref('')
const currentTime = ref('')
const updateTime = () => {const now = new Date()const year = now.getFullYear()let month = now.getMonth() + 1const day = now.getDate()let hour = now.getHours()let min = now.getMinutes()let second = now.getSeconds()const arrWork = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']const week = arrWork[now.getDay()]month = month < 10 ? '0' + month : monthhour = hour < 10 ? '0' + hour : hourmin = min < 10 ? '0' + min : minsecond = second < 10 ? '0' + second : seconddateTime.value = `${year}-${month}-${day}`dayTime.value = `${week}`currentTime.value = `${hour}:${min}:${second}`
}
onMounted(() => {window.setInterval(updateTime, 1000)updateTime()
})
</script>
<style scoped>
div {display: flex;
}
p {font-size: 25px;background: -webkit-linear-gradient(315deg, #e1ff00 50%, #ff0000);
}
sub {margin: 15px 0 0 0;background: -webkit-linear-gradient(315deg, hsl(0, 0%, 100%) 50%, #fcf401);
}
p,
sub {/*将背景剪切成文字的形状*/background-clip: text;-webkit-background-clip: text;/*文字颜色设为透明,使文字与背景融为一体*/-webkit-text-fill-color: transparent;/* 设置字体粗细 */font-weight: 900;text-shadow: 2px -1px 8px rgba(250, 80, 193, 0.323);
}
</style>

拖拽窗口的代码Drag.js

/* eslint-disable prettier/prettier */
/* 引入 */
import { reactive, onMounted } from 'vue'
export default function () {/*窗口移动事件*/const formTitle = '鼠标事件绑定标题栏实现拖动功能'const formPosition = reactive({ x: 0, y: 0 }) // 记录窗口位置的变量const startDrag = (event) => {event.preventDefault() // 阻止默认拖动行为const offsetX = event.clientX - formPosition.xconst offsetY = event.clientY - formPosition.yconst onDrag = (e) => {let newX = e.clientX - offsetXlet newY = e.clientY - offsetY// 边界检查newX = Math.max(0, Math.min(newX, window.innerWidth - formPosition.x))newY = Math.max(50, Math.min(newY, window.innerHeight - formPosition.y))formPosition.x = newXformPosition.y = newY}const onStopDrag = () => {document.removeEventListener('mousemove', onDrag)document.removeEventListener('mouseup', onStopDrag)}document.addEventListener('mousemove', onDrag)document.addEventListener('mouseup', onStopDrag)}onMounted(() => {const initialX = window.innerWidth / 4 // 窗口水平const initialY = window.innerHeight / 4 // 窗口垂直formPosition.x = initialXformPosition.y = initialY})return {formTitle,formPosition,startDrag}
}

MyLogs.css

button,
input {cursor: pointer;border: none;color: #ffffff94;text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);background-color: hsla(160, 100%, 37%, 0.247);&:hover {color: #f6f200;background-color: hsla(160, 100%, 37%, 0.995);box-shadow: 0 0 15px rgba(255, 254, 254, 0.5);}
}
/* 头部样式 */
.header {width: 100%;height: 35px;position: relative;display: flex;align-items: center;justify-content: space-between;background-color: #ffffff9c;-webkit-app-region: drag;z-index: 99;img {width: 30px;height: 30px;/* border-radius: 50%; */margin: 8px 0 0px 5px;-webkit-app-region: no-drag;transition: transform 0.3s ease;&:hover {transform: scale(1.2);}}button {font-size: 1.5rem;-webkit-app-region: no-drag;background-color: hsla(160, 100%, 37%, 0);&:hover {background-color: hsla(160, 100%, 37%, 0.445);}}iframe {-webkit-app-region: no-drag;}span {min-width: 110px;i {cursor: pointer;img {width: 30px;height: 30px;&:hover {background-color: hsla(0, 100%, 50%, 0.489);}}}}
}
/* 拖动窗口的样式 */
.draggable-form {position: absolute;/* 最小宽度 */min-width: 50%;border-radius: 8px;background-color: rgba(0, 0, 0, 0.443);z-index: 199;box-shadow: 0 0 10px rgba(255, 254, 254, 0.5);
}
.form-title {text-align: center;padding: 5px;color: hsla(160, 100%, 37%, 1);box-shadow: 0 0 3px rgba(255, 255, 255, 0.751);border-radius: 5px 5px 0 0;cursor: move;
}
.form-content {display: flex;margin: 2px 5px 5px 5px;box-shadow: 0 0 3px rgba(255, 255, 255, 0.751);border-radius: 0 0 5px 5px;input,button {font-size: 1.5rem;/* 文本竖排 */writing-mode: vertical-rl;/* 文字间距 */letter-spacing: 10px;}input {border-bottom-left-radius: 5px;}button {border-bottom-right-radius: 5px;}textarea {flex: 1;font-size: 1rem;background-color: rgba(0, 0, 0, 0.308);color: rgb(255, 255, 255);text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);&::placeholder {text-align: center;}}
}
/* 文本显示区样式 */
.memo {display: flex;align-content: flex-start;flex-wrap: wrap;margin: 0 20px;
}
.item {margin: 5px 10px;padding: 0 5px;border-radius: 10px;box-shadow: 0 0 10px rgba(255, 254, 254, 0.5);display: flex;align-items: center;&:hover {box-shadow: 0 0 15px rgba(255, 254, 254, 0.5);}.alter {position: absolute;min-width: 50%;display: flex;top: 100px;textarea {flex: 1;font-size: 1rem;color: #f85f5faf;text-shadow: 1px 1px 1px #030303;background-color: hsla(160, 96%, 18%, 0.952);box-shadow:inset -2px -2px 3px rgba(255, 255, 255, 0.6),inset 2px 2px 3px rgba(0, 0, 0, 0.6);border-radius: 10px 0 0 10px;}button {font-size: 1.5rem;/* 文本竖排 */writing-mode: vertical-rl;/* 文字间距 */letter-spacing: 10px;border-radius:0 5px  5px 0;}}
}
.item-number {/* 粗字体 */font-weight: bold;color: #fff;text-shadow: 1px 1px 1px #030303;/* 背景颜色 */background-color: #fbff06b6;border-radius: 20px;
}
.text-content {color: #1ded39a0;text-shadow: 1px 1px 1px #030303;background-color: #144756;border-radius: 10px;user-select: text;padding: 0 5px;&:hover {color: rgb(255, 250, 250);text-shadow: 1px 1px 1px #030303;background-color: rgb(191, 210, 255);}
}
/* 点击完成按钮显示.finish样式  */
.finish {/* 文本-装饰:删除线 */text-decoration: line-through;color: #f85f5faf;background-color: hsla(160, 100%, 37%, 0.2);text-shadow: 1px 1px 1px #030303;box-shadow:inset -2px -2px 3px rgba(255, 255, 255, 0.6),inset 2px 2px 3px rgba(0, 0, 0, 0.6);border-radius: 10px;
}
/* 删除按钮样式  */
.deleteBtn {color: #f3d303;text-shadow: 1px 1px 1px rgb(0, 0, 0);background: #ff0000;border-radius: 5px;border: none;margin: 5px;padding: 2px;/* 粗体 */font-weight: bold;&:hover {background-color: #f3d303;color: #ff0505;}
}

 main.css

@import './base.css';
/* 全局样式 */
* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;
}
body {min-height: 100vh;color: var(--color-text);background: var(--color-background);background-image: url('../img/wavy-lines.svg');background-size: cover;line-height: 1.6;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Fira Sans','Droid Sans','Helvetica Neue',sans-serif;text-rendering: optimizeLegibility;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}

base.css

:root {--ev-c-white: #ffffff;--ev-c-white-soft: #f8f8f8;--ev-c-white-mute: #f2f2f2;--ev-c-black: #1b1b1f;--ev-c-black-soft: #222222;--ev-c-black-mute: #282828;--ev-c-gray-1: #515c67;--ev-c-gray-2: #414853;--ev-c-gray-3: #32363f;--ev-c-text-1: rgba(255, 255, 245, 0.86);--ev-c-text-2: rgba(235, 235, 245, 0.6);--ev-c-text-3: rgba(235, 235, 245, 0.38);--ev-button-alt-border: transparent;--ev-button-alt-text: var(--ev-c-text-1);--ev-button-alt-bg: var(--ev-c-gray-3);--ev-button-alt-hover-border: transparent;--ev-button-alt-hover-text: var(--ev-c-text-1);--ev-button-alt-hover-bg: var(--ev-c-gray-2);--color-background: var(--ev-c-black);--color-background-soft: var(--ev-c-black-soft);--color-background-mute: var(--ev-c-black-mute);--color-text: var(--ev-c-text-1);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hutool相关base64图片处理工具类

引入maven <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.4</version> </dependency>工具类 package com.db.common.utils.image;import cn.hutool.core.img.ImgUtil;import j…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 身高差值排序(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

22种常用设计模式示例代码

文章目录 创建型模式结构型模式行为模式 仓库地址https://github.com/Xiamu-ssr/DesignPatternsPractice 参考教程 refactoringguru设计模式-目录 创建型模式 软件包复杂度流行度工厂方法factorymethod❄️⭐️⭐️⭐️抽象工厂abstractfactory❄️❄️⭐️⭐️⭐️生成器bui…

如何配置node.js环境

文章目录 step1. 下载node.js安装包step2. 创建node_global, node_cache文件夹step3.配置node环境变量step3. cmd窗口检查安装的node和npm版本号step4. 设置缓存路径\全局安装路径\下载镜像step5. 测试配置的nodejs环境 step1. 下载node.js安装包 下载地址&#xff1a;node.js…

[程序员] openstack: openvswitch: firewall丢包

最近看到一个老问题&#xff1a;说openvswitch提供的防火墙策略&#xff0c;会导致网络性能下降&#xff0c;而且有丢包。 https://bugzilla.redhat.com/show_bug.cgi?id1559604 the firewalling changed and the firewall_driver is now ‘openvswitch’ ([security_groups…

application/x-www-form-urlencoded和json的区别

application/x-www-form-urlencoded 和 application/json 是两种不同的数据格式&#xff0c;常用于HTTP请求中传递数据。 它们各自的特点和使用场景如下&#xff1a; 1. application/x-www-form-urlencoded •特点&#xff1a;这是一种传统的表单提交时采用的编码类型&#x…

24年新版!这份Excel+Python飞速搞定数据分析手册,简直可以让Excel飞起来

前⾔ 微软在 UserVoice 上运营着⼀个反馈论坛&#xff0c;每个⼈都可以在这⾥提交新点⼦供他⼈投票。票数最⾼的功能请求是“将 Python 作为Excel 的⼀门脚本语⾔”&#xff0c;其得票数差不多是第⼆名的两倍。尽管⾃2015 年这个点⼦发布以来并没有什么实质性进展&#xff0c;…

Java基础学习-算术运算符-案例

目录 运算符&#xff1a; 表达式&#xff1a; 简单练习&#xff1a; 案例&#xff1a;拆分 数字运算注意点 隐式转换&#xff08;自动类型提升&#xff09;&#xff1a; 强制转换&#xff1a; 字符串操作&#xff1a; 字符&#xff1a; 运算符&#xff1a; 对字面量或…

交叉编译三方库时不生成动态库

交叉编译三方库时不生成动态库 在x86架构下交叉编译liblog4cpp库时&#xff0c;x86执行./configure && make 可以正常生成动态库&#xff0c;但是交叉编译时执行./configure --hostarm时只生成了.a的静态库&#xff0c;查看config.log,进一步发现“ checking if libto…

为数据安全护航,袋鼠云在数据分类分级上的探索实践

在大数据时代&#xff0c;数据具有多源异构的特性&#xff0c;且价值各异&#xff0c;企业需依据数据的重要性、价值指数等予以区分&#xff0c;以利采取不同的数据保护举措&#xff0c;避免数据泄露。故而&#xff0c;数据分类分级管理属于数据安全保护中极为重要的环节之一。…

Coco Test Engine:代码覆盖率分析的新时代

本文翻译自&#xff1a;Coco Test Engine – The New Era of Code Coverage Analysis 原文作者&#xff1a;Qt Group首席软件工程师Sbastien Fricker 审校&#xff1a;Felix Zhang 我们的Coco 7重大更新带来了一个长期以来备受期待的功能——测试数据生成&#xff08;即Coco …

springboot mybatis mysql新增后返回id(ai生成)

在Spring Boot项目中使用MyBatis和MySQL时&#xff0c;若想在插入数据后返回生成的ID&#xff0c;可以在Mapper接口的插入方法上使用Options注解&#xff0c;并设置useGeneratedKeys属性为true&#xff0c;同时指定keyProperty为实体类中对应ID的属性名。 以下是一个简单的示例…

对角线法则的由来

目录 一、前言 二、对角线法则 三、行列式的定义 1. 行列式的定义 2. (全)排列 3. 逆序数 四、由全排列逆序数 到 对角线法则规律 ​编辑 五、参考书目 一、前言 仅限于个人理解&#xff0c;对错没有查证。 二、对角线法则 提起对角线法则&#xff0c;我们更倾向于他是…

Rocky Linux 9.4 部署Zabbix 7.0

文章目录 Zabbix基本概念zabbix介绍zabbix特性zabbix结构 安装Zabbix主机名配置配置Zabbix-Server(1)禁用EPEL提供的Zabbix软件包(2)安装Zabbix Server、Web前端、Agent(3)创建初始数据库(4)Zabbix server配置数据库(5)为Zabbix前端配置PHP(6)启动Zabbix server和agent进程(7)放…

js正则表达式将一个字符串拆分成3个一组,每组添加,

let a123456789.9876543210a.toString().replace(/\B(?(\d{3})(?!\d))/g, ",")//输出结果&#xff1a;123,456,789.9,876,543,210num.toString(): 将数字 num 转换为字符串。 .replace(/\B(?(\d{3})(?!\d))/g, ,): .replace() 是字符串对象的方法&#xff0c;用…

RK3588 代码中导入torch报错

RK3588 代码中导入torch报错 使用RK3588测试官方的YOLOv8,出现下面的问题 发现是dfl函数中导入torch的时候产生的&#xff0c;但是我在python终端上执行导入torch并没有发生报错 Traceback (most recent call last):File "infer.py", line 243, in <module>b…

Linux进程概念(个人笔记)

Linux进程概念 1.冯诺依曼体系结构2.操作系统&#xff08;先描述&#xff0c;再组织&#xff09;3.进程3.1查看进程的方式3.2通过系统调用获取进程标识符3.4查看进程中常见字段状态的指令3.3fork创建子进程3.3.1fork的原理 3.4进程状态3.5进程优先级3.5.1Linux内核的调度队列与…

Java代码中如何在JSONObject按put顺序排序

编写java代码时&#xff0c;发现在JSONObject 对象中put 一些数据后&#xff0c;输出JSONObject对象信息时&#xff0c;展示的json信息中&#xff0c;排序发生了变化。 以下为部分代码&#xff1a; JSONObject expDataJson new JSONObject();JSONObject expJson new JSONObj…

如何基于Redis实现消息队列

Redis可以用作消息队列的实现方案,有以下几种实现方案: 一 列表(List)作为消息队列 List如何实现消息队列,详情见这篇文章:基于Redis List实现消息队列 二 发布/订阅(Pub/Sub) 发布/订阅是一种消息通信模式,其中消息生产者(发布者)发送消息,而消息消费者(订阅者…

【教师资格证考试综合素质——法律专项】教师法笔记以及练习题

《中华人民共和国教师法》 一&#xff0e;首次颁布&#xff1a;第一部《中华人民共和国教师法》于1993年10月31日由第八届全国人民代表大会常务委员会第四次会议通过&#xff0c;1994年1月1日起执行。 二&#xff0e;历次修改&#xff1a;2009年8月27日第十一届全国人民代表…