feat: 权限设置静态交互主体完成

master
donghao 3 weeks ago
parent bf96269ef4
commit 1f2db187a5

@ -0,0 +1,18 @@
// 最小化
export const clientMinimizeWeb = () => {
electron.ipcRenderer.invoke('renderer-to-main', {
name: 'min-win'
})
}
// 最大化
export const clientMaximizeWeb = () => {
electron.ipcRenderer.invoke('renderer-to-main', {
name: 'max-win'
})
}
// 关闭
export const clientCloseWeb = () => {
electron.ipcRenderer.invoke('renderer-to-main', {
name: 'win-close'
})
}

@ -1,11 +1,119 @@
@import url('element-plus/dist/index.css'); @import url('element-plus/dist/index.css');
@import url('element-plus/theme-chalk/dark/css-vars.css'); // @import url('element-plus/theme-chalk/dark/css-vars.css'); //
body {
// color: #fff;
}
// //
:root { :root {
--el-color-primary: #154ddd; // --el-color-primary: #154ddd; //
// --el-fill-color-blank: transparent; //
}
/* button */
.el-button--default {
--el-button-text-color: #fff;
--el-fill-color-blank: transparent; //
}
.el-button--default:hover {
--el-button-hover-bg-color: transparent; //
--el-button-hover-border-color: var(--el-color-primary); //
--el-button-hover-text-color: var(--el-color-primary);
}
.el-button--primary:hover {
--el-button-hover-bg-color: var(--el-color-primary); //
--el-button-hover-border-color: var(--el-color-primary); //
--el-button-hover-text-color: var(--el-color-primary);
}
.el-button--info {
--el-button-bg-color: var(--el-color-info);
// --el-button-border-color: var(--el-color-info);
// --el-button-outline-color: var(--el-color-info-light-5);
// --el-button-active-color: var(--el-color-info-dark-2);
// --el-button-hover-text-color: var(--el-color-white);
// --el-button-hover-link-text-color: var(--el-color-info-light-5);
// --el-button-hover-bg-color: var(--el-color-info-light-3);
// --el-button-hover-border-color: var(--el-color-info-light-3);
// --el-button-active-bg-color: var(--el-color-info-dark-2);
// --el-button-active-border-color: var(--el-color-info-dark-2);
// --el-button-disabled-text-color: var(--el-color-white);
// --el-button-disabled-bg-color: var(--el-color-info-light-5);
// --el-button-disabled-border-color: var(--el-color-info-light-5);
}
.el-button--info:hover {
}
.el-button,
.el-button.is-round {
padding-left: 26px;
padding-right: 26px;
}
.el-button + .el-button {
margin-left: 8px;
}
// .el-button:hover {
// background-color: var(--el-button-hover-bg-color);
// border-color: var(--el-button-hover-border-color);
// color: var(--el-button-hover-text-color);
// outline: none;
// }
/* form */
.el-form-item__label {
--el-text-color-regular: #fff; //
}
.el-form-item__content{
color: #fff;
}
.el-input {
--el-input-text-color: #fff; //
--el-input-bg-color: transparent; //
}
// .el-input__wrapper {
// align-items: center;
// background-color: var(--el-input-bg-color, var(--el-fill-color-blank));
// background-image: none;
// border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
// box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
// cursor: text;
// display: inline-flex
// ;
// flex-grow: 1;
// justify-content: center;
// padding: 1px 11px;
// transform: translateZ(0);
// transition: var(--el-transition-box-shadow);
// }
.el-form-item--default {
margin-bottom: 12px;
}
.el-form-item--default .el-form-item__content {
line-height: 22px;
}
.el-switch {
height: 20px;
} }
/* 弹框 */ /* 弹框 */
.el-dialog {
--el-dialog-padding-primary: 0; //
}
.el-dialog__footer {
--el-dialog-padding-primary: 0; //
}
.el-dialog__headerbtn {
width: 68px;
height: 54px;
.el-dialog__close {
font-size: 20px;
}
}
.el-dialog__header {
height: 54px;
}
.design-dialog { .design-dialog {
padding: 0 !important; padding: 0 !important;
overflow: hidden; overflow: hidden;

@ -0,0 +1,262 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-04 10:36:19
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-07 17:29:54
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\permission.vue
* @Description: 权限设置
3完善交互效果
-->
<template>
<div class="settings_permission_wrap">
<el-form
style="max-width: 472px"
:model="formData"
label-width="auto"
label-position="top"
size="default"
>
<div>
<div class="el-form-item--label-top">
<div class="el-form-item__label">
<span>权限导入导出</span>
</div>
</div>
<div class="flex">
<el-form-item label="" class="mr-[8px]">
<el-button :type="formData?.import ? 'primary' : ''" @click="handleImport"
>导入</el-button
>
</el-form-item>
<el-form-item label="">
<el-button :type="formData?.export ? 'primary' : ''" @click="handleExport"
>导出</el-button
>
</el-form-item>
</div>
</div>
<el-form-item label="">
<span>{{ formData.encryption ? '开启' : '关闭' }}加密</span>
<el-switch v-model="formData.encryption" class="pl-[12px]" />
</el-form-item>
<div v-if="formData.encryption">
<el-form-item label="修改管理员密码">
<el-button @click="handleUpdatePassword"></el-button>
</el-form-item>
<el-form-item label="技术员权限">
<el-switch v-model="formData.technicianPermission" />
</el-form-item>
<el-form-item label="技术员密码">
<el-input
v-model="formData.technicianPassword"
placeholder="请输入密码"
type="password"
show-password
/>
</el-form-item>
<el-form-item label="技术员权限配置">
<el-button @click="() => (showPermissionDialog = true)">配置</el-button>
</el-form-item>
<el-form-item label="操作员权限">
<el-switch v-model="formData.operatorPermission" />
</el-form-item>
<el-form-item label="操作员密码">
<el-input
v-model="formData.operatorPassword"
placeholder="请输入密码"
type="password"
show-password
/>
</el-form-item>
<el-form-item label="操作员使能">
<el-switch v-model="formData.operatorEnabled" />
</el-form-item>
</div>
</el-form>
<!-- 修改管理员密码 -->
<el-dialog
align-center
v-model="showTechnicianPswDialog"
width="520"
@close="showTechnicianPswDialog = false"
class="settings-dialog design-dialog"
>
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between h-full dialog-header pl-[24px]">
<p class="overflow-hidden whitespace-nowrap text-ellipsis">设置管理员密码</p>
</div>
</template>
<div class="p-[24px]">
<el-form
ref="updatePswFormRef"
style="max-width: 472px"
:model="updatePswFromData"
label-width="auto"
label-position="top"
size="default"
:rules="pswFormRules"
>
<el-form-item label="设置密码" prop="pass">
<el-input v-model="updatePswFromData.pass" type="password" autocomplete="off" />
</el-form-item>
<el-form-item label="确认密码" prop="checkPass">
<el-input v-model="updatePswFromData.checkPass" type="password" autocomplete="off" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer mr-[24px] pb-[24px] pt-[16px]">
<el-button type="info" size="default" @click="resetPswFromData(updatePswFormRef)" class=""
>重置</el-button
>
<el-button
type="primary"
size="default"
@click="submitUpdatePswForm(updatePswFormRef)"
class=""
>确定</el-button
>
</div>
</template>
</el-dialog>
<!-- //TODO -->
<el-dialog
align-center
v-model="showPermissionDialog"
width="520"
@close="showPermissionDialog = false"
class="settings-dialog design-dialog"
>
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between h-full dialog-header pl-[24px]">
<p class="overflow-hidden whitespace-nowrap text-ellipsis">权限分配</p>
</div>
</template>
<div class="p-[24px]">
<el-form
style="max-width: 472px"
:model="permissionFromData"
label-width="auto"
label-position="top"
size="default"
>
<el-form-item label="选择开放给技术员的工具权限" prop="pass">
<el-checkbox label="所有权限"></el-checkbox>
<!-- <el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="handleCheckAllChange"
>
</el-checkbox> -->
<!-- @change="handleCheckedPermissionChange" -->
<el-checkbox-group v-model="permissionFromData.permission" >
<el-checkbox
v-for="v in ['权限1', '权限2', '权限3', '权限4', '权限5']"
:key="v"
:label="v"
:value="v"
>
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer mr-[24px] pb-[24px] pt-[16px]">
<el-button type="info" size="default" @click="resetPermission()" class="">取消</el-button>
<el-button type="primary" size="default" @click="submitPermission()" class=""
>确定</el-button
>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
const formData = reactive({
import: false, //
export: false, //
encryption: false, //
technicianPermission: false, //
technicianPassword: '', //
operatorPermission: false, //
operatorPassword: '', //
operatorEnabled: true
})
const showTechnicianPswDialog = ref<boolean>(false) //
const updatePswFormRef = ref<FormInstance>() //
const updatePswFromData = reactive({
pass: '',
checkPass: ''
})
const showPermissionDialog = ref<boolean>(false) //
const permissionFromData = reactive({
permission: [],
})
/**管理员重置密码 */
const validatePass = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请输入密码'))
} else {
if (updatePswFromData.checkPass !== '') {
if (!updatePswFormRef.value) return
updatePswFormRef.value.validateField('checkPass')
}
callback()
}
}
const validatePass2 = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== updatePswFromData.pass) {
callback(new Error('两次密码不一致'))
} else {
callback()
}
}
const pswFormRules = reactive<FormRules<typeof updatePswFromData>>({
pass: [{ validator: validatePass, trigger: 'blur' }],
checkPass: [{ validator: validatePass2, trigger: 'blur' }]
})
const handleUpdatePassword = () => {
console.log('Technician Config')
showTechnicianPswDialog.value = true
}
const submitUpdatePswForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.validate((valid) => {
if (valid) {
console.log('submit!')
} else {
console.log('error submit!')
}
})
}
const resetPswFromData = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
}
/**导入、导出 */
const handleImport = () => {
console.log('Import')
formData.import = !formData.import
}
const handleExport = () => {
console.log('Export')
formData.export = !formData.export
}
</script>

@ -0,0 +1,5 @@
<template>
<div>
方案设置
</div>
</template>

@ -1,58 +1,53 @@
.settings-dialog { .settings-dialog {
/* Your dialog styles */ /* Your dialog styles */
// background-color: #363940 !important;
background-color: #363940 !important; background-color: #2d3a4b;
height: 736px;
.settings-container { .settings-container {
display: flex; display: flex;
height: 400px; /* Adjust as needed */ min-height: 632px;
} }
.settings-sidebar { .settings-sidebar {
width: 200px; width: 120px;
background-color: #2d3a4b; /* Dark background */ padding: 24px;
color: #fff; }
padding: 20px; .settings-line {
} position: absolute;
left: 120px;
.sidebar-item { width: 1px;
padding: 10px; height: 100vh;
background-color: #fff;
opacity: 0.3;
}
.sidebar-item {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 5px; margin-bottom: 16px;
} opacity: 0.3;
&.active {
.sidebar-item:hover, opacity: 1;
.sidebar-item.active { }
background-color: #3c4b64; }
}
// .sidebar-item:hover,
.sidebar-item .el-icon { // .sidebar-item.active {
margin-right: 5px; // background-color: #3c4b64;
} // }
.settings-content { .settings-content {
flex: 1; flex: 1;
padding: 20px; padding: 24px 24px 12px;
color: #fff; }
}
.section { .section {
margin-bottom: 12px; margin-bottom: 12px;
} }
.section-title { .section-title {
font-weight: bold; font-weight: bold;
margin-bottom: 8px; margin-bottom: 8px;
} }
.button-group {
display: flex;
}
.button-group .el-button {
margin-right: 10px;
}
} }

@ -2,179 +2,134 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-03 11:12:04 * @Date: 2025-07-03 11:12:04
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-03 15:38:41 * @LastEditTime: 2025-07-07 15:51:03
* @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\setPermissions.vue * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\setPermissions.vue
* @Description: 设置权限 * @Description: 设置权限
--> -->
<template> <template>
<el-dialog <el-dialog
title="设置" align-center
v-model="dialogVisible" v-model="show"
width="800" width="800"
:close-on-click-modal="false" @close="handleClose"
:destroy-on-close="true"
:show-close="true"
class="settings-dialog design-dialog" class="settings-dialog design-dialog"
> >
<!-- 自定义标题栏 -->
<template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between h-full dialog-header pl-[24px]">
<p class="overflow-hidden whitespace-nowrap text-ellipsis">设置</p>
</div>
</template>
<div class="settings-container"> <div class="settings-container">
<div class="settings-sidebar"> <div class="settings-sidebar">
<div <div
class="sidebar-item" class="flex flex-col items-center justify-center sidebar-item"
:class="{ active: activeTab === 'permission' }" :class="{ active: activeTab === v.value }"
@click="setActiveTab('permission')" @click="setActiveTab(v)"
> v-for="(v, k) in settings"
<el-icon><Setting /></el-icon> :key="k"
权限设置
</div>
<div
class="sidebar-item"
:class="{ active: activeTab === 'software' }"
@click="setActiveTab('software')"
>
<el-icon><Edit /></el-icon>
软件设置
</div>
<div
class="sidebar-item"
:class="{ active: activeTab === 'plan' }"
@click="setActiveTab('plan')"
>
<el-icon><Document /></el-icon>
方案设置
</div>
<div
class="sidebar-item"
:class="{ active: activeTab === 'strategy' }"
@click="setActiveTab('strategy')"
> >
<el-icon><VideoPlay /></el-icon> <!-- // TODO icon -->
运行策略 <img src="@/assets/electron.svg" alt="" class="w-[32px]" />
</div> <span>{{ v.label }}</span>
</div>
<div class="settings-content">
<div v-if="activeTab === 'permission'">
<ThemeSwitcher />
<div class="section">
<div class="mb-0 section-title">权限导入导出</div>
<div class="button-group">
<el-button @click="handleImport"></el-button>
<el-button @click="handleExport"></el-button>
</div>
</div>
<div class="flex items-center section">
<div class="section-title">关闭加密</div>
<el-switch v-model="closeEncryption" class="pl-[12px]" />
</div>
<div class="section">
<div class="section-title">修改管理员密码</div>
<el-button type="primary" @click="handleChangePassword"> </el-button>
</div>
<div class="section">
<div class="section-title">技术员权限</div>
<el-switch v-model="technicianPermission" />
</div>
<div class="section">
<div class="section-title">技术员密码</div>
<el-input
v-model="technicianPassword"
placeholder="请输入密码"
type="password"
show-password
/>
</div>
<div class="section">
<div class="section-title">技术员权限配置</div>
<el-button @click="handleTechnicianConfig"></el-button>
</div>
<div class="section">
<div class="section-title">操作员权限</div>
<el-switch v-model="operatorPermission" />
</div>
<div class="flex section">
<div class="section-title">操作员密码</div>
<el-input
v-model="operatorPassword"
placeholder="请输入密码"
type="password"
show-password
/>
</div>
<div class="section">
<div class="section-title">操作员使能</div>
<el-switch v-model="operatorEnabled" />
</div> </div>
</div> </div>
<div class="settings-line"></div>
<ul class="settings-content">
<li v-if="activeTab === 'permission'">
<Permission />
</li>
<!-- Add other tabs' content here --> <!-- Add other tabs' content here -->
<div v-if="activeTab === 'software'"> <li v-if="activeTab === 'software'">
<p>Software Settings Content</p> <p>Software Settings Content</p>
</div> </li>
<div v-if="activeTab === 'plan'"> <li v-if="activeTab === 'plan'">
<p>Plan Settings Content</p> <p>Plan Settings Content</p>
</div> </li>
<div v-if="activeTab === 'strategy'"> <li v-if="activeTab === 'strategy'">
<p>Strategy Settings Content</p> <p>Strategy Settings Content</p>
</li>
</ul>
</div> </div>
</div>
</div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="pt-0 dialog-footer">
<el-button type="primary" @click="handleConfirm"></el-button> <el-button type="primary" size="default" @click="handleConfirm" class="mr-[24px] mb-[24px]"
>确定</el-button
>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ThemeSwitcher from '@/components/Theme/themeSwitcher.vue' // import ThemeSwitcher from '@/components/Theme/themeSwitcher.vue'
const dialogVisible = ref<boolean>(false) // Assuming you have a v-model to control the dialog's visibility import Permission from './permission.vue'
const activeTab = ref('permission') interface Props {
/** 弹窗显隐 */
// Data Bindings value: boolean
const closeEncryption = ref(false) info: Record<string, any>
const technicianPermission = ref(false) image: any
const technicianPassword = ref('')
const operatorPermission = ref(false)
const operatorPassword = ref('')
const operatorEnabled = ref(true)
// Methods
const setActiveTab = (tab: string) => {
activeTab.value = tab
} }
interface Emits {
const handleImport = () => { (e: 'update:value', val: boolean): void
console.log('Import')
// Implement import logic here
} }
const props = withDefaults(defineProps<Props>(), {
const handleExport = () => { value: false
console.log('Export') })
// Implement export logic here const emit = defineEmits<Emits>()
//
const handleClose = () => {
// emits('close');
} }
const handleChangePassword = () => { const show = computed({
console.log('Change Password') get() {
// Implement change password logic here return props.value
},
set(val: boolean) {
emit('update:value', val)
}
})
const activeTab = ref('permission')
interface SettingItem {
label: string
value: string //
icon?: string // URL
} }
const handleTechnicianConfig = () => { const settings: SettingItem[] = [
console.log('Technician Config') {
// Implement technician configuration logic here label: '权限设置',
value: 'permission',
icon: 'fa fa-cog' //
},
{
label: '软件设置',
value: 'software',
icon: 'fa fa-file-code-o' //
},
{
label: '方案设置',
value: 'scheme',
icon: 'fa fa-clipboard' //
},
{
label: '运行策略',
value: 'strategy',
icon: 'fa fa-play-circle-o' //
}
]
const setActiveTab = (tab: SettingItem) => {
activeTab.value = tab.value
} }
const handleConfirm = () => { const handleConfirm = () => {
console.log('Confirm') console.log('Confirm')
// Implement confirm logic here (e.g., save the changes) // Implement confirm logic here (e.g., save the changes)
dialogVisible.value = false // Close the dialog show.value = false // Close the dialog
} }
</script> </script>

@ -0,0 +1,5 @@
<template>
<div>
软件设置
</div>
</template>

@ -0,0 +1,13 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-04 10:57:20
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-04 10:58:12
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\views\Design\Settings\strategy.vue
* @Description: 运行策略
-->
<template>
<div>
运行策略
</div>
</template>

@ -2,14 +2,14 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-02 16:17:29 * @Date: 2025-07-02 16:17:29
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-03 14:19:48 * @LastEditTime: 2025-07-07 09:43:05
* @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\index.vue * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
--> -->
<template> <template>
<div class="design-wrap"> <div class="design-wrap">
<div class="design-header"> <div class="design-header">
<HeadCtrl @setting="() => isOpenSetting = true" /> <HeadCtrl @setting="() => (isOpenSetting = true)" />
<NavCtrl /> <NavCtrl />
</div> </div>
<div class="flex design-content"> <div class="flex design-content">
@ -26,7 +26,7 @@
</div> </div>
</div> </div>
<!-- 弹窗 --> <!-- 弹窗 -->
<SettingList /> <SettingList v-model:value="isOpenSetting" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -37,5 +37,5 @@ import LogicFlowView from './Workflow/logicFlowView.vue'
import OutputView from './Workflow/outputView.vue' import OutputView from './Workflow/outputView.vue'
import ResultsView from './Workflow/resultsView.vue' import ResultsView from './Workflow/resultsView.vue'
import SettingList from './Settings/settingList.vue' import SettingList from './Settings/settingList.vue'
const isOpenSetting = ref<boolean>(false) const isOpenSetting = ref<boolean>(true)
</script> </script>

Loading…
Cancel
Save