Przeglądaj źródła

fix:电话控件小休调整;

zhangchong 1 rok temu
rodzic
commit
ddca291b8b

+ 1 - 1
src/App.vue

@@ -71,7 +71,7 @@ onMounted(() => {
 	nextTick(async () => {
 		// 获取登录页的背景图和系统名称等
 		const res: any = await loginPageInfo();
-		themeConfig.value.globalTitle = res.result.sysName; // 标题名称
+		themeConfig.value.globalTitle = res.result.sysName.join('|') ?? ''; // 标题名称
 		themeConfig.value.loginImage = res.result.loginImage ? `url${res.result.loginImage}` : `url(${getImageUrl('login/bg.png')})`; // 登录页背景图
 		Local.set('themeConfig', themeConfig.value);
 		// 开发环境不提示

+ 1 - 1
src/api/home/index.ts

@@ -23,7 +23,7 @@ export const geFastMenu = () => {
  * @param {object} data
  * @return {*}
  */
-export const fastMenu = (data: object) => {
+export const fastMenu = (data?: object) => {
     return request({
         url: '/api/v1/Home/get-fastmenu',
         method: 'post',

+ 53 - 0
src/api/login/user.ts

@@ -133,6 +133,28 @@ export const telRest = (data: object) => {
 		data,
 	});
 };
+/**
+ * 分机休息wex
+ */
+export const telRestAdd = (data: object) => {
+	return request({
+		url: `/api/v1/Pbx/rest-add`,
+		method: 'post',
+		data,
+	});
+};
+/**
+ * 分机休息wex 需要审核
+ * @param {object}  params
+ */
+export const telRestProcess = (params?: object) => {
+	return request({
+		url: `/api/v1/Pbx/begin-rest`,
+		method: 'get',
+		params
+	});
+};
+
 /**
  * 查询小修流程开启参数
  * @returns 返回接口数据
@@ -143,6 +165,28 @@ export const restFlowStart = () => {
 		method: 'get',
 	});
 };
+/**
+ * 删除分机休息
+ * @returns 返回接口数据
+ */
+export const restFlowDel= () => {
+	return request({
+		url: `/api/v1/Pbx/rest-del`,
+		method: 'get',
+	});
+};
+/**
+ * 开始小修流程
+ * @param {object} data
+ * @returns 返回接口数据
+ */
+export const restFlowStartWex = (data:object) => {
+	return request({
+		url: `/api/v1/Pbx/rest-flow`,
+		method: 'post',
+		data
+	});
+};
 /**
  * 分机结束休息
  */
@@ -152,6 +196,15 @@ export const telUnrest = () => {
 		method: 'put',
 	});
 };
+/**
+ * 分机结束休息wex
+ */
+export const telUnrestWex = () => {
+	return request({
+		url: `/api/v1/Pbx/un-rest-wex`,
+		method: 'get',
+	});
+};
 /**
  * 通话保持
  *  @param callId 通话id

+ 39 - 5
src/api/system/parameter.ts

@@ -12,22 +12,56 @@ import request from '/@/utils/request';
  * @param {object} params
  * @return {*}
  */
- export const getSystemSettings = (params?: object) => {
+ export const getSystemSettings = (params: object) => {
 	return request({
 		url: '/api/v1/Setting/getsyssettings',
 		method: 'get',
-		params: params,
+		params
+	});
+};
+/**
+ * @description: 新增配置
+ * @param {object} data
+ * @return {*}
+ */
+export const SetingsAdd = (data: object) => {
+	return request({
+		url: '/api/v1/Setting/setting-add',
+		method: 'post',
+		data
 	});
 };
 /**
  * @description: 更新配置
- * @param {object} params
+ * @param {object} data
  * @return {*}
  */
- export const modifySettings = (params: object) => {
+ export const modifySettings = (data: object) => {
 	return request({
 		url: '/api/v1/Setting/modifysettings',
 		method: 'post',
-		data: params,
+		data
+	});
+};
+/**
+ * @description: 删除配置
+ * @param {object} params
+ * @return {*}
+ */
+// export const removeSetitngs = (params: object) => {
+// 	return request({
+// 		url: '/api/v1/Setting/modifysettings',
+// 		method: 'post',
+// 		data: params,
+// 	});
+// };
+/**
+ * @description: 查询配置详情
+ * @return {*}
+ */
+export const setitngsDetail = (id:string) => {
+	return request({
+		url: `/api/v1/Setting/getsetting-entity/${id}`,
+		method: 'get',
 	});
 };

+ 0 - 11
src/api/system/workflow.ts

@@ -133,17 +133,6 @@ export const getSelectList = (handlerType?: string) => {
 		method: 'get',
 	});
 };
-/**
- * @description: 查询业务流程是否已经启用模板
- * @param {moduleCode} moduleCode
- * @return {*}
- */
-export const WorkflowHasDefine = (moduleCode?: string) => {
-	return request({
-		url: `/api/v1/Workflow/has-define/${moduleCode}`,
-		method: 'get',
-	});
-};
 /**
  * @description: 分页查询流程
  * @param {object} params

+ 162 - 162
src/components/IconSelector/index.vue

@@ -1,85 +1,85 @@
 <template>
-	<div class="icon-selector w100 h100">
-		<el-input v-model="state.fontIconSearch" :placeholder="state.fontIconPlaceholder" :clearable="clearable"
-			:disabled="disabled" :size="size" ref="inputWidthRef" @clear="onClearFontIcon" @focus="onIconFocus"
-			@blur="onIconBlur">
-			<template #prepend>
-				<SvgIcon :name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"
-					v-if="state.fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : state.fontIconPrefix?.indexOf('ele-') > -1" />
-				<i v-else :class="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"></i>
-			</template>
-		</el-input>
-		<el-popover placement="bottom" :width="state.fontIconWidth" transition="el-zoom-in-top"
-			popper-class="icon-selector-popper" trigger="click" :virtual-ref="inputWidthRef" virtual-triggering>
-			<template #default>
-				<div class="icon-selector-warp">
-					<div class="icon-selector-warp-title">{{ title }}</div>
-					<el-tabs v-model="state.fontIconTabActive" @tab-click="onIconClick">
-						<el-tab-pane lazy label="ali" name="ali">
-							<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription"
-								:prefix="state.fontIconPrefix" @get-icon="onColClick" />
-						</el-tab-pane>
-						<el-tab-pane lazy label="ele" name="ele">
-							<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription"
-								:prefix="state.fontIconPrefix" @get-icon="onColClick" />
-						</el-tab-pane>
-						<!-- <el-tab-pane lazy label="awe" name="awe">
-							<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
-						</el-tab-pane> -->
-					</el-tabs>
-				</div>
-			</template>
-		</el-popover>
-	</div>
+  <div class="icon-selector w100 h100">
+    <el-input v-model="state.fontIconSearch" :placeholder="state.fontIconPlaceholder" :clearable="clearable"
+              :disabled="disabled" :size="size" ref="inputWidthRef" @clear="onClearFontIcon" @focus="onIconFocus"
+              @blur="onIconBlur">
+      <template #prepend>
+        <SvgIcon :name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"
+                 v-if="state.fontIconPrefix === '' ? prepend?.indexOf('ele-') > -1 : state.fontIconPrefix?.indexOf('ele-') > -1" />
+        <i v-else :class="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14"></i>
+      </template>
+    </el-input>
+    <el-popover placement="bottom" :width="state.fontIconWidth" transition="el-zoom-in-top"
+                popper-class="icon-selector-popper" trigger="click" :virtual-ref="inputWidthRef" virtual-triggering>
+      <template #default>
+        <div class="icon-selector-warp">
+          <div class="icon-selector-warp-title">{{ title }}</div>
+          <el-tabs v-model="state.fontIconTabActive" @tab-click="onIconClick">
+            <el-tab-pane lazy label="ali" name="ali">
+              <IconList :list="fontIconSheetsFilterList" :empty="emptyDescription"
+                        :prefix="state.fontIconPrefix" @get-icon="onColClick" />
+            </el-tab-pane>
+            <el-tab-pane lazy label="ele" name="ele">
+              <IconList :list="fontIconSheetsFilterList" :empty="emptyDescription"
+                        :prefix="state.fontIconPrefix" @get-icon="onColClick" />
+            </el-tab-pane>
+            <!-- <el-tab-pane lazy label="awe" name="awe">
+              <IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
+            </el-tab-pane> -->
+          </el-tabs>
+        </div>
+      </template>
+    </el-popover>
+  </div>
 </template>
 
 <script setup lang="ts" name="iconSelector">
-import { defineAsyncComponent, ref, reactive, onMounted, nextTick, computed, watch } from 'vue';
+import {defineAsyncComponent, ref, reactive, onMounted, nextTick, computed, watch, PropType} from 'vue';
 import type { TabsPaneContext } from 'element-plus';
 import initIconfont from '/@/utils/getStyleSheets';
 import '/@/theme/iconSelector.scss';
-
+type inputSize = "default" | "small" | "large";
 // 定义父组件传过来的值
 const props = defineProps({
-	// 输入框前置内容
-	prepend: {
-		type: String,
-		default: () => 'ele-Pointer',
-	},
-	// 输入框占位文本
-	placeholder: {
-		type: String,
-		default: () => '请输入内容搜索图标或者选择图标',
-	},
-	// 输入框占位文本
-	size: {
-		type: String,
-		default: () => 'default',
-	},
-	// 弹窗标题
-	title: {
-		type: String,
-		default: () => '请选择图标',
-	},
-	// 禁用
-	disabled: {
-		type: Boolean,
-		default: () => false,
-	},
-	// 是否可清空
-	clearable: {
-		type: Boolean,
-		default: () => true,
-	},
-	// 自定义空状态描述文字
-	emptyDescription: {
-		type: String,
-		default: () => '无相关图标',
-	},
-	// 双向绑定值,默认为 modelValue,
-	// 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
-	// 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
-	modelValue: String,
+  // 输入框前置内容
+  prepend: {
+    type: String,
+    default: () => 'ele-Pointer',
+  },
+  // 输入框占位文本
+  placeholder: {
+    type: String,
+    default: () => '请输入内容搜索图标或者选择图标',
+  },
+  // 输入框占位文本
+  size: {
+    type:String as unknown as PropType<inputSize>,
+    default: () => 'default',
+  },
+  // 弹窗标题
+  title: {
+    type: String,
+    default: () => '请选择图标',
+  },
+  // 禁用
+  disabled: {
+    type: Boolean,
+    default: () => false,
+  },
+  // 是否可清空
+  clearable: {
+    type: Boolean,
+    default: () => true,
+  },
+  // 自定义空状态描述文字
+  emptyDescription: {
+    type: String,
+    default: () => '无相关图标',
+  },
+  // 双向绑定值,默认为 modelValue,
+  // 参考:https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
+  // 参考:https://v3.cn.vuejs.org/guide/component-custom-events.html#%E5%A4%9A%E4%B8%AA-v-model-%E7%BB%91%E5%AE%9A
+  modelValue: String,
 });
 
 // 定义子组件向父组件传值/事件
@@ -91,137 +91,137 @@ const IconList = defineAsyncComponent(() => import('/src/components/IconSelector
 // 定义变量内容
 const inputWidthRef = ref<RefType>();
 const state = reactive({
-	fontIconPrefix: '',
-	fontIconWidth: 0,
-	fontIconSearch: '',
-	fontIconPlaceholder: '',
-	fontIconTabActive: 'ali',
-	fontIconList: {
-		ali: [],
-		ele: [],
-		awe: [],
-	},
+  fontIconPrefix: '',
+  fontIconWidth: 0,
+  fontIconSearch: '',
+  fontIconPlaceholder: '',
+  fontIconTabActive: 'ali',
+  fontIconList: {
+    ali: [],
+    ele: [],
+    awe: [],
+  },
 });
 
 // 处理 input 获取焦点时,modelValue 有值时,改变 input 的 placeholder 值
 const onIconFocus = () => {
-	if (!props.modelValue) return false;
-	state.fontIconSearch = '';
-	state.fontIconPlaceholder = props.modelValue;
+  if (!props.modelValue) return false;
+  state.fontIconSearch = '';
+  state.fontIconPlaceholder = props.modelValue;
 };
 // 处理 input 失去焦点时,为空将清空 input 值,为点击选中图标时,将取原先值
 const onIconBlur = () => {
-	const list = fontIconTabNameList();
-	setTimeout(() => {
-		const icon = list.filter((icon: string) => icon === state.fontIconSearch);
-		if (icon.length <= 0) state.fontIconSearch = '';
-	}, 300);
+  const list = fontIconTabNameList();
+  setTimeout(() => {
+    const icon = list.filter((icon: string) => icon === state.fontIconSearch);
+    if (icon.length <= 0) state.fontIconSearch = '';
+  }, 300);
 };
 // 图标搜索及图标数据显示
 const fontIconSheetsFilterList = computed(() => {
-	const list = fontIconTabNameList();
-	if (!state.fontIconSearch) return list;
-	let search = state.fontIconSearch.trim().toLowerCase();
-	return list.filter((item: string) => {
-		if (item.toLowerCase().indexOf(search) !== -1) return item;
-	});
+  const list = fontIconTabNameList();
+  if (!state.fontIconSearch) return list;
+  let search = state.fontIconSearch.trim().toLowerCase();
+  return list.filter((item: string) => {
+    if (item.toLowerCase().indexOf(search) !== -1) return item;
+  });
 });
 // 根据 tab name 类型设置图标
 const fontIconTabNameList = () => {
-	let iconList: any = [];
-	if (state.fontIconTabActive === 'ali') iconList = state.fontIconList.ali;
-	else if (state.fontIconTabActive === 'ele') iconList = state.fontIconList.ele;
-	else if (state.fontIconTabActive === 'awe') iconList = state.fontIconList.awe;
-	return iconList;
+  let iconList: any = [];
+  if (state.fontIconTabActive === 'ali') iconList = state.fontIconList.ali;
+  else if (state.fontIconTabActive === 'ele') iconList = state.fontIconList.ele;
+  else if (state.fontIconTabActive === 'awe') iconList = state.fontIconList.awe;
+  return iconList;
 };
 // 处理 icon 双向绑定数值回显
 const initModeValueEcho = () => {
-	if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
-	(<string | undefined>state.fontIconPlaceholder) = props.modelValue;
-	(<string | undefined>state.fontIconPrefix) = props.modelValue;
+  if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
+  (<string | undefined>state.fontIconPlaceholder) = props.modelValue;
+  (<string | undefined>state.fontIconPrefix) = props.modelValue;
 };
 // 处理 icon 类型,用于回显时,tab 高亮与初始化数据
 const initFontIconName = () => {
-	let name = 'ali';
-	if (props.modelValue) {
-		if (props.modelValue!.indexOf('iconfont') > -1) name = 'ali';
-		else if (props.modelValue!.indexOf('ele-') > -1) name = 'ele';
-		else if (props.modelValue!.indexOf('fa') > -1) name = 'awe';
-	}
-	// 初始化 tab 高亮回显
-	state.fontIconTabActive = name;
-	return name;
+  let name = 'ali';
+  if (props.modelValue) {
+    if (props.modelValue!.indexOf('iconfont') > -1) name = 'ali';
+    else if (props.modelValue!.indexOf('ele-') > -1) name = 'ele';
+    else if (props.modelValue!.indexOf('fa') > -1) name = 'awe';
+  }
+  // 初始化 tab 高亮回显
+  state.fontIconTabActive = name;
+  return name;
 };
 // 初始化数据
 const initFontIconData = async (name: string) => {
-	if (name === 'ali') {
-		// 阿里字体图标使用 `iconfont xxx`
-		if (state.fontIconList.ali.length > 0) return;
-		await initIconfont.ali().then((res: any) => {
-			state.fontIconList.ali = res.map((i: string) => `iconfont ${i}`);
-		});
-	} else if (name === 'ele') {
-		// element plus 图标
-		if (state.fontIconList.ele.length > 0) return;
-		await initIconfont.ele().then((res: any) => {
-			state.fontIconList.ele = res;
-		});
-	} else if (name === 'awe') {
-		// fontawesome字体图标使用 `fa xxx`
-		if (state.fontIconList.awe.length > 0) return;
-		await initIconfont.awe().then((res: any) => {
-			state.fontIconList.awe = res.map((i: string) => `fa ${i}`);
-		});
-	}
-	// 初始化 input 的 placeholder
-	// 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
-	state.fontIconPlaceholder = props.placeholder;
-	// 初始化双向绑定回显
-	initModeValueEcho();
+  if (name === 'ali') {
+    // 阿里字体图标使用 `iconfont xxx`
+    if (state.fontIconList.ali.length > 0) return;
+    await initIconfont.ali().then((res: any) => {
+      state.fontIconList.ali = res.map((i: string) => `iconfont ${i}`);
+    });
+  } else if (name === 'ele') {
+    // element plus 图标
+    if (state.fontIconList.ele.length > 0) return;
+    await initIconfont.ele().then((res: any) => {
+      state.fontIconList.ele = res;
+    });
+  } else if (name === 'awe') {
+    // fontawesome字体图标使用 `fa xxx`
+    if (state.fontIconList.awe.length > 0) return;
+    await initIconfont.awe().then((res: any) => {
+      state.fontIconList.awe = res.map((i: string) => `fa ${i}`);
+    });
+  }
+  // 初始化 input 的 placeholder
+  // 参考(单项数据流):https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
+  state.fontIconPlaceholder = props.placeholder;
+  // 初始化双向绑定回显
+  initModeValueEcho();
 };
 // 图标点击切换
 const onIconClick = (pane: TabsPaneContext) => {
-	initFontIconData(pane.paneName as string);
-	inputWidthRef.value.focus();
+  initFontIconData(pane.paneName as string);
+  inputWidthRef.value.focus();
 };
 // 获取当前点击的 icon 图标
 const onColClick = (v: string) => {
-	state.fontIconPlaceholder = v;
-	state.fontIconPrefix = v;
-	emit('get', state.fontIconPrefix);
-	emit('update:modelValue', state.fontIconPrefix);
-	inputWidthRef.value.focus();
+  state.fontIconPlaceholder = v;
+  state.fontIconPrefix = v;
+  emit('get', state.fontIconPrefix);
+  emit('update:modelValue', state.fontIconPrefix);
+  inputWidthRef.value.focus();
 };
 // 清空当前点击的 icon 图标
 const onClearFontIcon = () => {
-	state.fontIconPrefix = '';
-	emit('clear', state.fontIconPrefix);
-	emit('update:modelValue', state.fontIconPrefix);
+  state.fontIconPrefix = '';
+  emit('clear', state.fontIconPrefix);
+  emit('update:modelValue', state.fontIconPrefix);
 };
 // 获取 input 的宽度
 const getInputWidth = () => {
-	nextTick(() => {
-		state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
-	});
+  nextTick(() => {
+    state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
+  });
 };
 // 监听页面宽度改变
 const initResize = () => {
-	window.addEventListener('resize', () => {
-		getInputWidth();
-	});
+  window.addEventListener('resize', () => {
+    getInputWidth();
+  });
 };
 // 页面加载时
 onMounted(() => {
-	initFontIconData(initFontIconName());
-	initResize();
-	getInputWidth();
+  initFontIconData(initFontIconName());
+  initResize();
+  getInputWidth();
 });
 // 监听双向绑定 modelValue 的变化
 watch(
-	() => props.modelValue,
-	() => {
-		initModeValueEcho();
-		initFontIconName();
-	}
+    () => props.modelValue,
+    () => {
+      initModeValueEcho();
+      initFontIconName();
+    }
 );
 </script>

+ 1 - 30
src/components/LogicFlow/index.vue

@@ -50,7 +50,7 @@ import '@logicflow/core/dist/style/index.css';
 import '@logicflow/extension/lib/style/index.css';
 import { SnakerFlowElement, SnakerFlowAdapter } from './snakerflow/index';
 import { NodeTypeEnum } from './enums';
-import { workflowAdd, workflowUpdate, publish, baseData, WorkflowHasDefine } from '/@/api/system/workflow';
+import { workflowAdd, workflowUpdate, publish, baseData } from '/@/api/system/workflow';
 import mittBus from '/@/utils/mitt';
 import { throttle } from '/@/utils/tools';
 import { ElMessage, ElMessageBox } from 'element-plus';
@@ -425,34 +425,6 @@ const release = throttle(async () => {
 				ElMessage.warning(submitData.error);
 				return;
 			}
-			const response: any = await WorkflowHasDefine(form.moduleCode);
-			if (response.result) {
-				//若已存在有效模板
-				ElMessageBox.confirm(`业务模块【${form.moduleName}】已有流程模板,确认覆盖当前版本?`, '提示', {
-					confirmButtonText: '确认',
-					cancelButtonText: '取消',
-					type: 'warning',
-					draggable: true,
-					cancelButtonClass: 'default-button',
-					autofocus: false,
-				})
-					.then(() => {
-						publish(submitData).then(() => {
-							//保存并发布
-							ElMessage.success('操作成功');
-							// 关闭当前 tagsView
-							mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
-							mittBus.emit('clearCache', 'systemWorkflow');
-							router.push({
-								path: '/system/config/workflow',
-                query:{
-                  tabIndex:'1'
-                }
-							});
-						});
-					})
-					.catch(() => {});
-			} else {
 				//不存在直接发布
 				ElMessageBox.confirm(`此操作将发布模板:“${form.name}”,是否继续?`, '提示', {
 					confirmButtonText: '确认',
@@ -478,7 +450,6 @@ const release = throttle(async () => {
 						});
 					})
 					.catch(() => {});
-			}
 			emits('on-save', getGraphData());
 		} else {
 			return false;

+ 1 - 1
src/components/ProcessTimeLine/index.vue

@@ -328,6 +328,6 @@ onMounted(() => {
 	border-left: 1px solid #bfcdff;
 }
 :deep(.el-timeline-item:last-child .el-timeline-item__tail){
-  display: block;
+  //display: block;
 }
 </style>

+ 59 - 82
src/layout/navBars/breadcrumb/telControl.vue

@@ -125,26 +125,26 @@
 				</div>
 			</template>
 
-			<!-- 静音和取消静音 可用 -->
-			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('mute')">
-				<div
-					class="item active"
-					@click="onControlClick(telStatusInfo.isMute ? 'unMute' : 'mute')"
-					@mouseenter="onHover('muteSrc', 'phoneControls/mute_white.png')"
-					:title="telStatusInfo.isMute ? '取消静音' : '静音'"
-					@mouseleave="onHover('muteSrc', 'phoneControls/mute_blue.png')"
-				>
-					<img :src="state.muteSrc" alt="" />
-					<span>{{ telStatusInfo.isMute ? '取消静音' : '静音' }}</span>
-				</div>
-			</template>
+			<!-- 静音和取消静音 可用  维尔信不支持静音-->
+<!--			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('mute')">-->
+<!--				<div-->
+<!--					class="item active"-->
+<!--					@click="onControlClick(telStatusInfo.isMute ? 'unMute' : 'mute')"-->
+<!--					@mouseenter="onHover('muteSrc', 'phoneControls/mute_white.png')"-->
+<!--					:title="telStatusInfo.isMute ? '取消静音' : '静音'"-->
+<!--					@mouseleave="onHover('muteSrc', 'phoneControls/mute_blue.png')"-->
+<!--				>-->
+<!--					<img :src="state.muteSrc" alt="" />-->
+<!--					<span>{{ telStatusInfo.isMute ? '取消静音' : '静音' }}</span>-->
+<!--				</div>-->
+<!--			</template>-->
 			<!-- 静音不可用 -->
-			<template v-else>
-				<div class="item disabled" title="保持">
-					<img :src="getImageUrl('phoneControls/mute_grey.png')" alt="" />
-					<span>静音</span>
-				</div>
-			</template>
+<!--			<template v-else>-->
+<!--				<div class="item disabled" title="保持">-->
+<!--					<img :src="getImageUrl('phoneControls/mute_grey.png')" alt="" />-->
+<!--					<span>静音</span>-->
+<!--				</div>-->
+<!--			</template>-->
 
 			<!-- 转接 可用 -->
 			<template v-if="telStatusInfo.isDutyOn && activeArr.includes('transfer')">
@@ -547,24 +547,24 @@ import { commonEnum } from '/@/utils/tools';
 import other from '/@/utils/other';
 import { userState } from '/@/api/login';
 import {
-	onDuty,
-	offDuty,
-	telRest,
-	telUnrest,
-	telHold,
-	telUnHold,
-	telMute,
-	telUnMute,
-	visitorToTel,
-	telToOuter,
-	telToTel,
-	visitorToOuter,
-	meeting,
-	hangupApi,
-	restFlowStart,
-	evaluateCall,
-	outerToTel,
-	outerToOuter,
+  onDuty,
+  offDuty,
+  telRest,
+  telUnrest,
+  telHold,
+  telUnHold,
+  telMute,
+  telUnMute,
+  visitorToTel,
+  telToOuter,
+  telToTel,
+  visitorToOuter,
+  meeting,
+  hangupApi,
+  restFlowStart,
+  evaluateCall,
+  outerToTel,
+  outerToOuter, restFlowStartWex, restFlowDel,
 } from '/@/api/login/user';
 import { TelStates, RestStates } from '/@/stores/interface';
 import { workflowStepOptions } from '/@/api/system/workflow';
@@ -662,13 +662,13 @@ const metingFormRef = ref<RefType>(); // 三方会议表单
 const router = useRouter();
 
 // 小休审批通过消息
-const RestApplyPassFn = () => {
+const RestApplyPassFn = (data:any) => {
 	ElNotification({
 		title: '成功',
 		message: '小休审批通过,开始小休',
 		type: 'success',
 	});
-  VoiceInterfaceObject.SetBusy(); //设置忙碌
+  VoiceInterfaceObject.SetBusy(data); //设置忙碌
 };
 // 链接websocket
 const initWebsocket = ()=>{
@@ -722,7 +722,7 @@ const signalRStart = () => {
 	signalR.SR.on('RestApplyPass', (data: any) => {
 		// 小休审批通过消息
 		console.log(data, '小休审批通过消息');
-		RestApplyPassFn();
+		RestApplyPassFn(data);
 	});
 };
 signalRStart(); //开启消息监听
@@ -965,44 +965,29 @@ const clickOnRest = () => {
 								submitObj.nextMainHandler = submitObj.nextHandlers[0].id;
 							}
 						}
-            VoiceInterfaceObject.SetBusy(); //设置忙碌
-            state.showRestDialog = false;
-            state.loading = false;
-						// telRest(submitObj)
-						// 	.then(() => {
-						// 		ElNotification({
-						// 			title: '成功',
-						// 			message: '申请小休成功',
-						// 			type: 'success',
-						// 		});
-						// 		// 设置休息状态 审核中
-						// 		useTelStatusStore.setRest(RestStates.InReview);
-						// 		state.showRestDialog = false;
-						// 		state.loading = false;
-						// 	})
-						// 	.catch(() => {
-						// 		state.loading = false;
-						// 	});
+            restFlowStartWex(submitObj)
+							.then(() => {
+								ElNotification({
+									title: '成功',
+									message: '申请小休成功',
+									type: 'success',
+								});
+								// 设置休息状态 审核中
+								useTelStatusStore.setRest(RestStates.InReview);
+								state.showRestDialog = false;
+								state.loading = false;
+							})
+							.catch(() => {
+                restFlowDel().then(() => {
+                  state.loading = false;
+                  state.showRestDialog = false;
+                });
+							});
 					} else {
             //不需要审核直接开始小休
-            VoiceInterfaceObject.SetBusy(); //设置忙碌
+            VoiceInterfaceObject.SetBusy(state.restForm.reason); //设置忙碌
             state.showRestDialog = false;
             state.loading = false;
-						// telRest(state.restForm)
-						// 	.then(() => {
-						// 		ElNotification({
-						// 			title: '成功',
-						// 			message: '小休开始',
-						// 			type: 'success',
-						// 		});
-            //     //不需要审核直接开始小休
-            //     VoiceInterfaceObject.SetBusy(); //设置忙碌
-            //     state.showRestDialog = false;
-						// 		state.loading = false;
-						// 	})
-						// 	.catch(() => {
-						// 		state.loading = false;
-						// 	});
 					}
 				})
 				.catch(() => {});
@@ -1031,14 +1016,6 @@ const onRestEnd = () => {
 			state.loading = true;
       VoiceInterfaceObject.SetIdle(); //设置空闲
       state.loading = false;
-			// telUnrest()
-			// 	.then(() => {
-      //     VoiceInterfaceObject.SetIdle(); //设置空闲
-			// 		state.loading = false;
-			// 	})
-			// 	.catch(() => {
-			// 		state.loading = false;
-			// 	});
 		})
 		.catch(() => {});
 };

+ 43 - 14
src/utils/PhoneScript.ts

@@ -7,6 +7,7 @@ import { useUserInfo } from '/@/stores/userInfo';
 import { useAppConfig } from '/@/stores/appConfig';
 import { TelStates, RestStates } from '/@/stores/interface';
 import { debounce } from '/@/utils/tools';
+import {restFlowDel, restFlowStart, telRestAdd, telRestProcess, telUnrestWex} from "/@/api/login/user";
 
 const storesUserInfo = useUserInfo();
 const { userInfos } = storeToRefs(storesUserInfo);
@@ -19,8 +20,8 @@ const { AppConfigInfo } = storeToRefs(appConfigStore);
 const SystemAttr = {
     CurrentUser: { "DepartmentID": "", "GongHao": "", "FenJi": "", "AgentGroupName": "" }
 }
-let timer: any = null;
-let time = 0;
+let timer: any = null; // 计时器
+let time = 0; // 计时时间
 // 开始计时
 const startTime = debounce(() => {
     // @ts-ignore
@@ -45,6 +46,8 @@ const removeTimer = debounce(() => {
     clearInterval(timer);
 }, 1000);
 
+// 小休原因
+let restReason: string = "";
 //音频接口对象
 export const VoiceInterfaceObject:any = {
     // 设置全局变量
@@ -110,13 +113,6 @@ export const VoiceInterfaceObject:any = {
                 },
             }).then(()=>{} );
         }
-        //layer.open({
-        //    title: "来电弹屏",
-        //    type: 1,
-        //    area: ['600px', '360px'],
-        //    shadeClose: true, //点击遮罩关闭
-        //    content: '\<\div style="padding:10px;">来电号码:' + DialInfo.telNum + '<br>来电工号:' + DialInfo.telGongHao + '<br>来电区域:' + DialInfo.telArea + '<br>来电GUID:' + DialInfo.telGuid + '<br>来电IVR名称:' + DialInfo.telIVR + '<br>来电类型:' + DialInfo.telType + ' \<\/div>'
-        //});
     },
     //弹屏 回调
     // Back_RegNumberState: function (returnVal: any) {
@@ -237,8 +233,9 @@ export const VoiceInterfaceObject:any = {
         console.info(returnVal.message);
     },
     //示忙当前座席
-    SetBusy: function () {
+    SetBusy: function (reason:string) {
         const modelJson = this.GetSendModel("SetBusy");
+        restReason = reason || '';
         const returnVal = WebsocketInterface("Send", JSON.stringify(modelJson));
         if (returnVal != 1) {
             console.info(WebsocketInterface("GetError", returnVal));
@@ -255,12 +252,36 @@ export const VoiceInterfaceObject:any = {
     //示忙回调
     Back_SetBusy: function (returnVal: { Params: string; Message: any; }) {
         if (returnVal.Params == "0") {
-            ElMessage.success("小休开始!")
-            // 设置电话状态小休中
-            useTelStatusStore.setPhoneControlState(TelStates.rest);
-            useTelStatusStore.setRest(RestStates.resting);
+            if (AppConfigInfo.value.isRestApproval) {
+                // 如果小休需要审核
+                telRestProcess().then((res: any) => {
+                    console.log('小休申请成功', res)
+                    // 设置电话状态小休中
+                    useTelStatusStore.setPhoneControlState(TelStates.rest);
+                    useTelStatusStore.setRest(RestStates.resting);
+                    ElMessage.success("小休开始!")
+                }).catch((err: any) => {
+                    console.log('小休申请失败', err)
+                    restFlowDel().then(() => { // 删除小休流程
+                    });
+                    this.SetIdle(); // 调用失败示闲
+                })
+            }else{
+                ElMessage.success("小休开始!")
+                // 设置电话状态小休中
+                useTelStatusStore.setPhoneControlState(TelStates.rest);
+                useTelStatusStore.setRest(RestStates.resting);
+                // 添加小休记录
+                telRestAdd({reason: restReason}).then((res: any) => {
+                    console.log('小休记录添加成功 开始休息', res)
+                }).catch((err: any) => {
+                    console.log('小休记录添加失败 开始休息', err)
+                    this.SetIdle(); // 调用失败示闲
+                })
+            }
         } else {
             console.info(returnVal.Message);
+            ElMessage.error(returnVal.Message)
         }
     },
     //示闲当前座席
@@ -269,6 +290,8 @@ export const VoiceInterfaceObject:any = {
         const returnVal = WebsocketInterface("Send", JSON.stringify(modelJson));
         if (returnVal != 1) {
             console.info(WebsocketInterface("GetError", returnVal));
+        }else{
+
         }
     },
     //强制示闲座席
@@ -287,8 +310,14 @@ export const VoiceInterfaceObject:any = {
             useTelStatusStore.setRest(RestStates.unRest);
             // 设置话机状态 结束休息改为签入状态
             useTelStatusStore.setPhoneControlState(TelStates.dutyOn);
+            telUnrestWex().then((res: any) => {
+                console.log('小休记录修改成功 结束休息', res)
+            }).catch((err: any) => {
+                console.log('小休记录修改失败 结束休息', err)
+            })
         } else {
             console.info(returnVal.Message);
+            ElMessage.error(returnVal.Message)
         }
     },
     //保持

+ 1 - 1
src/utils/request.ts

@@ -31,7 +31,7 @@ export default function myAxios(axiosConfig: any, customOptions?: any, loadingOp
 
 	// 添加请求拦截器
 	service.interceptors.request.use(
-		(config: AxiosRequestConfig) => {
+		(config: any) => {
 			removePending(config);
 			custom_options.repeat_request_cancel && addPending(config);
 			// 创建loading实例

+ 1 - 1
src/views/business/order/components/Order-comment.vue

@@ -74,7 +74,7 @@
 			</div>
 			<template #footer v-if="state.active === 'add' || state.manage">
 				<div style="flex: auto">
-					<el-button @click="deleteComment" class="default-button" v-if="state.active === 'default' && state.manage">删 除</el-button>
+					<el-button @click="deleteComment" class="default-button" :disabled="!state.chooseCommentList.length" v-if="state.active === 'default' && state.manage">删 除</el-button>
 					<el-button type="primary" @click="commentSave" v-if="state.active === 'add'">保 存</el-button>
 				</div>
 			</template>

+ 12 - 3
src/views/home/component/Entrance.vue

@@ -38,7 +38,7 @@
 				<div class="mb20" v-loading="state.selectLoading">
 					<template v-if="state.entranceSelect.length">
 						<ul class="entrance-list-box">
-							<li class="entrance-list-box-item" v-for="(item, index) in state.entranceSelect" :key="index" :title="item.pageName">
+							<li class="entrance-list-box-item" v-for="(item, index) in state.entranceSelect" :key="item.id" :title="item.pageName">
 								<img v-lazy="getImageUrl(item.fastIcon)" alt="" class="mb10"  src=""/>
 								<p class="entrance-list-box-item-name text-no-wrap">{{ item.pageName }}</p>
 								<SvgIcon
@@ -88,7 +88,6 @@ const openDialog = () => {
 	getEntranceSelect();
 	emit('openDialog');
 };
-
 // 关闭弹窗
 const closeDialog = () => {
 	state.isShowDialog = false;
@@ -109,9 +108,19 @@ const getEntrance = () => {
 // 获取可选入口
 const getEntranceSelect = () => {
 	state.selectLoading = true;
-	fastMenu({ name: state.searchKey })
+	fastMenu({})
 		.then((res: any) => {
 			state.entranceSelect = res?.result ?? [];
+      if(state.searchKey){
+        state.entranceSelect = state.entranceSelect.filter((i: any) => i.pageName.includes(state.searchKey));
+        if(state.entranceList.length){
+          state.entranceSelect = state.entranceSelect.filter((i: any) => !state.entranceList.some((j: any) => j.id === i.id));
+        }
+      }else{
+        if(state.entranceList.length){
+          state.entranceSelect = state.entranceSelect.filter((i: any) => !state.entranceList.some((j: any) => j.id === i.id));
+        }
+      }
 			setTimeout(() => {
 				state.selectLoading = false;
 			}, 300);

+ 2 - 2
src/views/home/index.vue

@@ -111,8 +111,8 @@
 						<ul class="right-entrance-list">
 							<li
 								class="right-entrance-list-item"
-								v-for="(item, index) in state.entranceList"
-								:key="index"
+								v-for="item in state.entranceList"
+								:key="item.id"
 								:data-id="item.id"
 								@click="goLink(item.path)"
 							>

+ 1 - 1
src/views/system/config/dict/component/Dict-add.vue

@@ -43,7 +43,7 @@
 			<template #footer>
 				<span class="dialog-footer">
 					<el-button @click="onCancel" class="default-button">取 消</el-button>
-					<el-button type="primary" @click="onSubmit()" :loading="loading">确 定</el-button>
+					<el-button type="primary" @click="onSubmit" :loading="loading">确 定</el-button>
 				</span>
 			</template>
 		</el-dialog>

+ 2 - 1
src/views/system/config/workflow/component/Workflow-config.vue

@@ -91,7 +91,8 @@ const openDialog = async (row: any) => {
   try {
     queryList();
     state.rowCode = row.code;
-    state.tableRadio = '';
+    if(row.definitionId) state.tableRadio = row.definitionId;
+    else state.tableRadio = '';
     dialogTitle.value = row.name;
     dialogVisible.value = true;
   } catch (error) {

+ 1 - 21
src/views/system/config/workflow/index.vue

@@ -174,7 +174,6 @@ import {
   workflowEnable,
   workflowDisable,
   workflowTerminate,
-  WorkflowHasDefine,
   baseData,
   wfmodules, wfmodulesMatch,
 } from '/@/api/system/workflow';
@@ -310,25 +309,7 @@ const onDeleteTemp = (row: any) => {
 };
 // 发布模板
 const onReleaseTemp = async (row: any) => {
-	const response: any = await WorkflowHasDefine(row.code);
-	if (response.result) {
-		//若已存在有效模板
-		ElMessageBox.confirm(`业务模块【${row.moduleName}】已有流程模板,确认覆盖当前版本?`, '提示', {
-			confirmButtonText: '确认',
-			cancelButtonText: '取消',
-			type: 'warning',
-			draggable: true,
-			cancelButtonClass: 'default-button',
-			autofocus: false,
-		})
-			.then(() => {
-				publishOnList(row.id).then(() => {
-					ElMessage.success('发布成功');
-					queryList();
-				});
-			})
-			.catch(() => {});
-	} else {
+  console.log(row)
 		ElMessageBox.confirm(`此操作将发布模板:“${row.name}”,是否继续?`, '提示', {
 			confirmButtonText: '确认',
 			cancelButtonText: '取消',
@@ -344,7 +325,6 @@ const onReleaseTemp = async (row: any) => {
 				});
 			})
 			.catch(() => {});
-	}
 };
 // 启用模板
 const tempEnable = (row: any) => {

+ 1 - 1
src/views/system/menu/component/Menu-add.vue

@@ -62,7 +62,7 @@
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
 							<el-form-item label="菜单图标" prop="icon" :rules="[{ required: false, message: '请输入菜单名称', trigger: 'blur' }]">
-								<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.icon" type="all" />
+								<icon-selector placeholder="请输入菜单图标" v-model="state.ruleForm.icon" type="all"/>
 							</el-form-item>
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">

+ 1 - 1
src/views/system/menu/component/Menu-edit.vue

@@ -62,7 +62,7 @@
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
 							<el-form-item label="菜单图标" prop="icon" :rules="[{ required: false, message: '请输入菜单名称', trigger: 'blur' }]">
-								<IconSelector placeholder="请输入菜单图标" v-model="state.ruleForm.icon" type="all" />
+								<icon-selector placeholder="请输入菜单图标" v-model="state.ruleForm.icon" type="all" />
 							</el-form-item>
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">

+ 116 - 0
src/views/system/parameter/component/Parameter-add.vue

@@ -0,0 +1,116 @@
+<template>
+	<div class="system-parameter-add-container">
+		<el-dialog v-model="state.isShowDialog" width="50%" draggable title="新增参数">
+			<el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef">
+				<el-row :gutter="10">
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="参数名称" prop="settingName" :rules="[{ required: true, message: '请输入参数名称', trigger: 'blur' }]">
+							<el-input v-model="state.ruleForm.settingName" placeholder="请输入参数名称" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="参数" prop="code" :rules="[{ required: true, message: '请输入参数', trigger: 'blur' }]">
+							<el-input v-model.trim="state.ruleForm.code" placeholder="请输入参数" clearable></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+						<el-form-item label="参数值" prop="settingValue" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]">
+							<el-input v-model.trim="state.ruleForm.settingValue" placeholder="有多个参数值,请以的|隔开,如1|2|3" clearable></el-input>
+						</el-form-item>
+					</el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+            <el-form-item label="排序" prop="sort" :rules="[{ required: false, message: '请输入排序', trigger: 'blur' }]">
+              <el-input-number v-model="state.ruleForm.sort" :min="1"  :precision="0"/>
+            </el-form-item>
+          </el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="参数说明" prop="remark" :rules="[{ required: false, message: '请输入参数说明', trigger: 'blur' }]">
+							<el-input
+								type="textarea"
+								:autosize="{ minRows: 6, maxRows: 10 }"
+								v-model="state.ruleForm.remark"
+								placeholder="请输入参数说明"
+								clearable
+							></el-input>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" :loading="loading">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="parameterAdd">
+import { reactive, ref } from 'vue';
+import { ElMessage } from 'element-plus';
+import { throttle } from '/@/utils/tools';
+import {SetingsAdd} from "/@/api/system/parameter";
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+
+// 定义变量内容
+const state = reactive<any>({
+	isShowDialog: false,
+	ruleForm: {
+    settingName: '', // 参数名称
+    code: '', // 参数
+    settingValue: '', // 参数值
+    sort: 1, // 排序
+    remark: '', // 参数说明
+	},
+});
+let loading = ref<boolean>(false);
+// 打开弹窗
+const ruleFormRef = ref<RefType>();
+const openDialog = async (typeId: string) => {
+	ruleFormRef.value?.resetFields();
+	try {
+		state.isShowDialog = true;
+	} catch (error) {
+		console.log(error);
+	}
+};
+// 关闭弹窗
+const closeDialog = () => {
+	state.isShowDialog = false;
+};
+// 取消
+const onCancel = () => {
+	closeDialog();
+};
+// 新增
+const onSubmit = throttle(() => {
+	ruleFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			loading.value = true;
+      state.ruleForm.settingValue = state.ruleForm.settingValue.split('|')
+      SetingsAdd(state.ruleForm)
+				.then(() => {
+					ElMessage({
+						message: '新增成功',
+						type: 'success',
+					});
+					loading.value = false;
+					closeDialog();
+					emit('updateList');
+				})
+				.catch(() => {
+					// 新增失败
+					loading.value = false;
+					closeDialog();
+				});
+		}
+	});
+}, 1000);
+// 暴露变量
+defineExpose({
+	openDialog,
+	closeDialog,
+});
+</script>

+ 125 - 0
src/views/system/parameter/component/Parameter-edit.vue

@@ -0,0 +1,125 @@
+<template>
+  <div class="system-Parameter-edit-container">
+    <el-dialog v-model="state.isShowDialog" width="50%" draggable :title="dialogTitle">
+      <el-form :model="state.ruleForm" label-width="90px" ref="ruleFormRef">
+        <el-row :gutter="10">
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+            <el-form-item label="参数名称" prop="settingName" :rules="[{ required: true, message: '请输入参数名称', trigger: 'blur' }]">
+              <el-input v-model="state.ruleForm.settingName" placeholder="请输入参数名称" clearable :disabled="state.isDisabled"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+            <el-form-item label="参数" prop="code" :rules="[{ required: true, message: '请输入参数', trigger: 'blur' }]">
+              <el-input v-model.trim="state.ruleForm.code" placeholder="请输入参数" clearable :disabled="state.isDisabled"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+            <el-form-item label="参数值" prop="settingValue" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]">
+              <el-input v-model.trim="state.ruleForm.settingValue"  placeholder="有多个参数值,请以的|隔开,如1|2|3" clearable :disabled="state.isDisabled"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
+            <el-form-item label="排序" prop="sort" :rules="[{ required: false, message: '请输入排序', trigger: 'blur' }]">
+              <el-input-number v-model="state.ruleForm.sort" :min="1"  :precision="0" :disabled="state.isDisabled"/>
+            </el-form-item>
+          </el-col>
+          <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+            <el-form-item label="参数说明" prop="remark" :rules="[{ required: false, message: '请输入参数说明', trigger: 'blur' }]">
+              <el-input
+                  :disabled="state.isDisabled"
+                  type="textarea"
+                  :autosize="{ minRows: 6, maxRows: 10 }"
+                  v-model="state.ruleForm.remark"
+                  placeholder="请输入参数说明"
+                  clearable
+              ></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer v-if="!state.isDisabled">
+				<span class="dialog-footer">
+					<el-button @click="onCancel" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" :loading="loading">确 定</el-button>
+				</span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="ts" name="parameterEdit">
+import {computed, reactive, ref} from 'vue';
+import { ElMessage } from 'element-plus';
+import { throttle } from '/@/utils/tools';
+import {modifySettings, setitngsDetail} from "/@/api/system/parameter";
+// 定义子组件向父组件传值/事件
+const emit = defineEmits(['updateList']);
+
+// 定义变量内容
+const state = reactive<any>({
+  isShowDialog: false,
+  ruleForm: {
+    settingName: '', // 参数名称
+    code: '', // 参数
+    settingValue: '', // 参数值
+    sort: 1, // 排序
+    remark: '', // 参数说明
+  },
+  isDisabled: false, // 是否禁用
+});
+let loading = ref<boolean>(false);
+const dialogTitle = computed(() => {
+  return state.isDisabled ? '查看参数' : '编辑参数';
+});
+// 打开弹窗
+const ruleFormRef = ref<RefType>();
+const openDialog = async (id:string,isDisabled?:boolean) => {
+  ruleFormRef.value?.resetFields();
+  try {
+    const res: any = await setitngsDetail(id);
+    state.ruleForm = res.result ?? {};
+    state.ruleForm.settingValue = state.ruleForm.settingValue?.join('|')
+    state.isDisabled = isDisabled ?? false;
+    state.isShowDialog = true;
+  } catch (error) {
+    console.log(error);
+  }
+};
+// 关闭弹窗
+const closeDialog = () => {
+  state.isShowDialog = false;
+};
+// 取消
+const onCancel = () => {
+  closeDialog();
+};
+// 新增
+const onSubmit = throttle(() => {
+  ruleFormRef.value.validate((valid: boolean) => {
+    if (valid) {
+      loading.value = true;
+      state.ruleForm.settingValue = state.ruleForm.settingValue.split('|')
+      modifySettings(state.ruleForm)
+          .then(() => {
+            ElMessage({
+              message: '新增成功',
+              type: 'success',
+            });
+            loading.value = false;
+            closeDialog();
+            emit('updateList');
+          })
+          .catch(() => {
+            // 新增失败
+            loading.value = false;
+            closeDialog();
+          });
+    }
+  });
+}, 1000);
+// 暴露变量
+defineExpose({
+  openDialog,
+  closeDialog,
+});
+</script>

+ 133 - 311
src/views/system/parameter/index.vue

@@ -1,332 +1,154 @@
 <template>
 	<div class="system-parameter-container layout-pd">
       <el-card shadow="never">
-        <el-divider content-position="center"><h4 class="table-title">系统参数设置</h4></el-divider>
-        <el-form :model="state.ruleForm" label-width="200px" ref="ruleFormRef" v-loading="state.loading">
-          <el-row :gutter="35">
-            <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" v-for="items in state.data" :key="items.id">
-              <!-- <el-divider content-position="left">{{ items.groupName }}</el-divider> -->
-              <div v-for="item in items.systemSettings" :key="item.id">
-                <el-form-item :label="item.settingName">
-                  <!-- 单选框 -->
-                  <template v-if="item.valueType === 0">
-                    <el-radio-group v-model="item.settingValue" class="ml-4" @change="changeVal($event, item.id)">
-                      <el-radio :label="item1.value" v-for="item1 in item.presetValue" :key="item1.value">{{ item1.key }}</el-radio>
-                    </el-radio-group>
-                  </template>
-                  <!-- 多选框 -->
-                  <template v-else-if="item.valueType === 1">
-                    <el-checkbox-group v-model="item.settingValue" @change="changeVal($event, item.id)">
-                      <el-checkbox v-for="item1 in item.presetValue" :key="item1.value" :label="item1.value">{{ item1.key }}</el-checkbox>
-                    </el-checkbox-group>
-                  </template>
-                  <!-- 文本 -->
-                  <template v-else-if="item.valueType === 2">
-                    <el-input
-                        v-model="item.settingValue"
-                        :placeholder="'请输入' + item.settingName"
-                        class="max-width"
-                        @input="changeVal($event, item.id)"
-                    />
-                  </template>
-                  <!-- 数字 -->
-                  <template v-else-if="item.valueType === 3">
-                    <el-input-number v-model="item.settingValue" :placeholder="'请输入' + item.settingName" @input="changeVal($event, item.id)" />
-                  </template>
-                  <!-- 下拉框 -->
-                  <template v-else-if="item.valueType === 4">
-                    <el-select v-model="item.settingValue" :placeholder="'请选择' + item.settingName" @change="changeVal($event, item.id)">
-                      <el-option v-for="item1 in item.presetValue" :key="item1.value" :label="item1.key" :value="item1.value" />
-                    </el-select>
-                  </template>
-                  <!-- 开关 -->
-                  <template v-else-if="item.valueType === 5">
-                    <el-switch v-model="item.settingValue" @change="changeVal($event, item.id)" />
-                  </template>
-                  <!-- 时间 -->
-                  <template v-else-if="item.valueType === 6">
-                    <el-time-select
-                        v-model="item.settingValue"
-                        start="00:00"
-                        step="00:30"
-                        end="23:30"
-                        :placeholder="'请选择' + item.settingName"
-                        @change="changeVal($event, item.id)"
-                    />
-                  </template>
-                  <!-- 日期 -->
-                  <template v-else-if="item.valueType === 7">
-                    <el-date-picker
-                        v-model="item.settingValue"
-                        value-format="YYYY-MM-DD[T]HH:mm:ss"
-                        type="date"
-                        :placeholder="'请选择' + item.settingName"
-                        @change="changeVal($event, item.id)"
-                    />
-                  </template>
-                  <!-- 日期区间 -->
-                  <template v-else-if="item.valueType === 8">
-                    <div>
-                      <el-date-picker
-                          v-model="item.settingValue"
-                          value-format="YYYY-MM-DD[T]HH:mm:ss"
-                          type="daterange"
-                          :placeholder="'请选择' + item.settingName"
-                          @change="changeVal($event, item.id)"
-                          range-separator="至"
-                          start-placeholder="开始日期"
-                          end-placeholder="结束日期"
-                      />
-                    </div>
-                  </template>
-                  <!-- 时间区间 -->
-                  <template v-else-if="item.valueType === 9">
-                    <el-time-select
-                        v-model="item.settingValue[0]"
-                        :max-time="item.settingValue[1]"
-                        placeholder="开始时间"
-                        start="00:00"
-                        step="00:30"
-                        end="23:30"
-                        @change="changeVal($event, item.id, 'startTime')"
-                    />
-                    <el-time-select
-                        v-model="item.settingValue[1]"
-                        :min-time="item.settingValue[0]"
-                        placeholder="结束时间"
-                        start="00:00"
-                        step="00:30"
-                        end="23:30"
-                        @change="changeVal($event, item.id, 'endTime')"
-                    />
-                  </template>
-                  <!-- 单个图片上传 -->
-                  <template v-else-if="item.valueType === 10">
-                    <el-upload
-                        class="avatar-uploader"
-                        accept=".jpg, .jpeg, .png, .gif, .bmp, .JPG, .JPEG, .PBG, .GIF, .BMP"
-                        action=""
-                        :show-file-list="false"
-                        :on-success="handleAvatarSuccess"
-                        :http-request="(file) => uploadImg(file, item.id)"
-                        :before-upload="beforeAvatarUpload"
-                    >
-                      <img v-if="imageUrl" :src="imageUrl" class="avatar" alt=""/>
-                      <SvgIcon v-else class="avatar-uploader-icon" name="ele-Plus" size="32px" />
-                    </el-upload>
-                  </template>
-                  <!-- 多个图片上传 -->
-                  <template v-else-if="item.valueType === 11">
-                    <el-upload
-                        v-model:file-list="fileList"
-                        accept=".jpg, .jpeg, .png, .gif, .bmp, .JPG, .JPEG, .PBG, .GIF, .BMP"
-                        action=""
-                        list-type="picture-card"
-                        ref="uploadListRef"
-                        :autoUpload="false"
-                        :on-change="(file) => uploadImgList(file, fileList, item.id)"
-                    >
-                      <SvgIcon name="ele-Plus" size="32px" />
-                      <template #file="file">
-                        <div style="text-align: center" class="w100 h100">
-                          <div class="images w100 h100" v-viewer>
-                            <img class="w100 h100" :src="file.file.url"  alt=""/>
-                          </div>
-                          <span class="el-upload-list__item-actions">
-													<span title="预览图片" class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
-														<SvgIcon name="ele-ZoomIn" size="18px" />
-													</span>
-													<span title="删除图片" class="el-upload-list__item-delete" @click="handleRemove(file)">
-														<SvgIcon name="ele-Delete" size="18px" />
-													</span>
-												</span>
-                        </div>
-                      </template>
-                    </el-upload>
-                  </template>
-                </el-form-item>
-              </div>
-            </el-col>
-          </el-row>
-          <el-form-item>
-            <el-button type="primary" @click="submitForm" :loading="state.loading" v-auth="'system:parameter:edit'">保 存 </el-button>
-            <el-button @click="resetForm" :loading="state.loading" v-auth="'system:parameter:edit'">重 置</el-button>
+        <el-form
+            :model="state.queryParams"
+            ref="ruleFormRef"
+            :inline="true"
+            @submit.native.prevent
+        >
+          <el-form-item label="参数名称" prop="settingName">
+            <el-input v-model="state.queryParams.settingName" placeholder="请输入参数名称" clearable @keyup.enter="queryList" />
+          </el-form-item>
+          <el-form-item label="参数" prop="code">
+            <el-input v-model="state.queryParams.code" placeholder="请输入参数" clearable @keyup.enter="queryList" />
+          </el-form-item>
+          <el-form-item >
+            <el-button type="primary" @click="queryList" :loading="state.loading">
+              <SvgIcon name="ele-Search" class="mr5" />查询
+            </el-button>
+            <el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button"> <SvgIcon name="ele-Refresh" class="mr5" />重置 </el-button>
           </el-form-item>
         </el-form>
+        <div class="flex-center-between mb20">
+          <p class="table-title">信息列表</p>
+          <div>
+            <el-button type="primary" @click="addParameter" v-waves v-auth="'system:timeLimit:add'">
+              <SvgIcon name="ele-Plus" class="mr5" />新增
+            </el-button>
+          </div>
+        </div>
+        <!-- 表格 -->
+        <el-table :data="state.tableData" v-loading="state.loading">
+          <el-table-column type="index" width="60" label="序号" />
+          <el-table-column prop="settingName" label="参数名称" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="code" label="参数" show-overflow-tooltip width="130"></el-table-column>
+          <el-table-column prop="settingValue" label="参数值" show-overflow-tooltip>
+            <template #default="{ row }">
+              <span v-if="row.settingValue">{{ row.settingValue.join('|') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="remark" label="参数说明" show-overflow-tooltip width="300"></el-table-column>
+          <el-table-column prop="creator.name" label="创建人" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="afterBegin" label="创建时间" show-overflow-tooltip width="170">
+            <template #default="{ row }">
+              <span>{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="sort" label="排序" show-overflow-tooltip width="60"></el-table-column>
+          <el-table-column label="操作" width="200" fixed="right" align="center">
+            <template #default="{row}">
+              <el-button link type="primary" @click="updateParameter(row)" v-auth="'system:timeLimit:edit'" title="修改参数"> 修改 </el-button>
+              <el-button link type="info" @click="viewParameter(row)" v-auth="'system:timeLimit:detail'" title="查看详情"> 查看 </el-button>
+<!--              <el-button link type="danger" @click="parameterDelete(row)" v-auth="'system:timeLimit:detail'" title="删除参数"> 删除 </el-button>-->
+            </template>
+          </el-table-column>
+          <template #empty>
+            <Empty />
+          </template>
+        </el-table>
+        <!-- 分页 -->
+        <pagination
+            :total="state.total"
+            v-model:page="state.queryParams.PageIndex"
+            v-model:limit="state.queryParams.PageSize"
+            @pagination="queryList"
+        />
       </el-card>
+    <!--  参数新增  -->
+    <parameter-add ref="ParameterAddRef" @updateList="queryList"/>
+    <!--  参数编辑  -->
+    <parameter-edit ref="ParameterEditRef" @updateList="queryList"/>
 	</div>
 </template>
 
 <script lang="ts" setup name="systemParameter">
-import { reactive, ref, onMounted } from 'vue';
-import { getSystemSettings, modifySettings } from '/@/api/system/parameter';
-import { ElMessage } from 'element-plus';
-import type { UploadProps, UploadUserFile } from 'element-plus';
-import { auth } from '/@/utils/authFunction';
+import {reactive, ref, onMounted, defineAsyncComponent} from 'vue';
+import { getSystemSettings } from '/@/api/system/parameter';
+import {ElMessage, ElMessageBox, FormInstance} from 'element-plus';
 import { throttle } from '/@/utils/tools';
-import { api as viewerApi } from 'v-viewer';
+import {formatDate} from "/@/utils/formatTime";
 
-// 定义接口来定义对象的类型
-interface SystemState {
-	ruleForm: object;
-	data: Array<any>;
-	formatData: Array<any>;
-	loading: boolean;
-}
+// 引入组件
+const ParameterAdd = defineAsyncComponent(() => import('/@/views/system/parameter/component/Parameter-add.vue'));
+const ParameterEdit = defineAsyncComponent(() => import('/@/views/system/parameter/component/Parameter-edit.vue'));
 
 // 定义变量内容
-const timeRageRef = ref<any>(['', '']);
-const uploadListRef = ref<RefType>();
-const state = reactive<SystemState>({
-	ruleForm: {},
-	data: [],
-  formatData: [],
-	loading: false,
+const state = reactive<any>({
+  loading: false, // 加载状态
+  queryParams: { // 查询参数
+    PageIndex: 1,
+    PageSize: 10,
+    settingName: '', // 参数名称
+    code:'' // 参数编码
+  },
+  total: 0, // 总条数
+  tableData: [], // 表格数据
 });
-//获取参数列表
-const getSetList = () => {
-	if (!auth('system:parameter:query')) ElMessage.error('抱歉,您没有权限获取系统参数!');
-	else {
-		state.loading = true;
-		state.formatData = [];
-		getSystemSettings()
-			.then((res: any) => {
-				state.data = res?.result ?? [];
-				for (let j of state.data) {
-					for (let i of j.systemSettings) {
-						state.formatData.push({
-							id: i.id,
-							value: i.settingValue ? i.settingValue : i.valueType == 5 ? 'false' : null,
-							valueType: i.valueType,
-						});
-						if (i.presetValue) {
-							// 默认数据
-							i.presetValue = JSON.parse(i.presetValue);
-						}
-						if (i.valueType == 1 && i.settingValue == null) {
-							//多选
-							i.settingValue = [];
-						} else if (i.valueType == 1 && i.settingValue) {
-							i.settingValue = i.settingValue.split(',');
-						} else if (i.valueType == 8 && i.settingValue) {
-							i.settingValue = i.settingValue.split(',');
-						} else if (i.valueType == 9 && i.settingValue) {
-							// 时间区间
-							i.settingValue = i.settingValue.split(',');
-							timeRageRef.value = [i.settingValue[0], i.settingValue[1]];
-						}
-						if (i.valueType == 5 && i.settingValue) {
-							// 开关
-							i.settingValue = JSON.parse(i.settingValue);
-						}
-						if (i.valueType == 3 && i.settingValue) {
-							// 开关
-							i.settingValue = Number(i.settingValue);
-						}
-					}
-				}
-				state.loading = false;
-			})
-			.catch(() => {
-				state.loading = false;
-			});
-	}
-};
-// 处理提交数据
-const changeVal = (val: any, id: string | number, startOrEnd?: string) => {
-	state.formatData.forEach((item: any) => {
-		if (item.id == id) {
-			item.value = val;
-			if (item.valueType == 1 || item.valueType == 8) {
-				// 多选 日期区间
-				item.value = val.join(',');
-			}
-			if (item.valueType == 9) {
-				// 时间区间
-				if (startOrEnd == 'startTime') {
-					// 开始时间
-					timeRageRef.value[0] = val;
-					item.value = timeRageRef.value.join(',');
-				} else if (startOrEnd == 'endTime') {
-					// 结束时间
-					timeRageRef.value[1] = val;
-					item.value = timeRageRef.value.join(',');
-				}
-			}
-			if (item.valueType == 5 || item.valueType == 3) {
-				// 开关 数字输入
-				item.value = String(val);
-			}
-		}
-	});
-};
-// 单个上传列表
-const imageUrl = ref('https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100');
-const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
-	imageUrl.value = URL.createObjectURL(uploadFile.raw!);
-};
-// 单个图片上传
-const uploadImg = (response: any, uploadFile: any) => {
-	console.log(response, uploadFile);
-};
-// 上传之前限制大小和类型
-const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
-	if (rawFile.type !== 'image/jpeg') {
-		ElMessage.error('Avatar picture must be JPG format!');
-		return false;
-	} else if (rawFile.size / 1024 / 1024 > 2) {
-		ElMessage.error('Avatar picture size can not exceed 2MB!');
-		return false;
-	}
-	return true;
-};
-// 上传列表
-const fileList = ref<UploadUserFile[]>([
-	{
-		name: 'food.jpeg',
-		url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
-	},
-]);
-// 多张图片上传
-const uploadImgList = (file: any, list: any, id: any) => {
-	console.log(file, list, id);
-	fileList.value = list;
-};
-// 删除图片(多张)
-const handleRemove = (uploadFile: any) => {
-	uploadListRef.value[0].handleRemove(uploadFile.file);
-};
-// 预览图片 多张
-const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile: any) => {
-	for (let i = 0; i < document.querySelectorAll('.images').length; i++) {
-		if (uploadFile.file.url === document.querySelectorAll('.images')[i].getElementsByTagName('img')[0].src) {
-			viewerApi({
-				options: {
-					toolbar: true,
-					url: 'url',
-					initialViewIndex: i,
-				},
-				images: fileList.value,
-			});
-			break;
-		}
-	}
-};
-// 保存
-const submitForm = throttle(() => {
-	modifySettings({ list: state.formatData })
-		.then(() => {
-			ElMessage.success('配置成功');
-			getSetList();
-		})
-		.catch(() => {});
-}, 500);
-const resetForm = () => {
-	getSetList();
+const ruleFormRef = ref<any>(null); // 表单ref
+const ParameterAddRef = ref<RefType>(); // 参数新增
+const ParameterEditRef = ref<RefType>();  // 参数编辑
+
+// 获取参数列表
+const queryList = throttle(() => {
+  state.loading = true;
+  getSystemSettings(state.queryParams).then((res) => {
+      state.loading = false;
+      state.tableData = res.result.items ?? [];
+      state.total = res.result.total ?? 0;
+  }).finally(() => {
+      state.loading = false;
+  })
+}, 1000);
+// 重置表单
+const resetQuery = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  queryList();
 };
+// 新增参数
+const addParameter = ()=>{
+  ParameterAddRef.value.openDialog();
+}
+// 修改参数
+const updateParameter = (row:any)=>{
+  ParameterEditRef.value.openDialog(row.id);
+}
+// 查看详情
+const viewParameter = (row:any)=>{
+  ParameterEditRef.value.openDialog(row.id, true);
+}
+// 删除参数
+const parameterDelete = (row:any)=>{
+  ElMessageBox.confirm(`此操作将删除模板:“${row.name}”,是否继续?`, '提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+    cancelButtonClass: 'default-button',
+    autofocus: false,
+  })
+      .then(() => {
+        // workflowDelete(row.id).then(() => {
+          ElMessage.success('删除成功');
+          queryList();
+        // });
+      })
+      .catch(() => {});
+}
 // 页面加载时
 onMounted(() => {
-	getSetList();
+  queryList();
 });
 </script>
 

+ 4 - 1
src/views/tels/restApply/index.vue

@@ -130,6 +130,9 @@ const state = reactive<any>({
 	queryParams: {
 		PageIndex: 1,
 		PageSize: 10,
+    KeyWords:'',
+    Reason:'',
+    Status:'',
 		time: [],
 	},
 	loading: false,
@@ -174,6 +177,7 @@ const onSubmit = debounce((row: any, title: string, type?: string) => {
 }, 1000);
 // 审核记录
 const onRecord = (row: any) => {
+  console.log(row)
 	const params = {
 		title: '小休申请',
 		...row,
@@ -184,7 +188,6 @@ const onRecord = (row: any) => {
 const baseDataFn = () => {
   baseData().then((res: any) => {
 		state.restApplyStatus = res.result?.restApplyStatus;
-		state.queryParams.Status = res.result?.restApplyStatus[0].key;
 		state.restReason = res.result?.restReason;
 		queryList();
 	});