Merge branch 'master' of gitee.com:yudaocode/yudao-ui-admin-vue3 into master-iotscene
Signed-off-by: 熊猫大侠 <1565636758@qq.com>pull/880/head
commit
c8b132433a
|
|
@ -215,8 +215,8 @@ export const ThingModelFormRules = {
|
|||
identifier: [
|
||||
{ required: true, message: '标识符不能为空', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^[a-zA-Z0-9_]{1,50}$/,
|
||||
message: '支持大小写字母、数字和下划线,不超过 50 个字符',
|
||||
pattern: /^[a-zA-Z][a-zA-Z0-9_]{0,31}$/,
|
||||
message: '支持大小写字母、数字和下划线,必须以字母开头,不超过 32 个字符',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export interface ProAndonConfigVO {
|
|||
reason: string // 呼叫原因
|
||||
level: number // 级别
|
||||
handlerRoleId: number // 处置人角色编号
|
||||
handlerRoleName: string // 处置人角色名称
|
||||
handlerUserId: number // 处置人编号
|
||||
handlerUserNickname: string // 处置人昵称
|
||||
remark: string // 备注
|
||||
|
|
|
|||
|
|
@ -116,7 +116,8 @@ const toggleClick = () => {
|
|||
:row="{
|
||||
label: item.label
|
||||
}"
|
||||
>{{ item.label }}
|
||||
>
|
||||
{{ item.label }}
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
|
|
@ -130,9 +131,7 @@ const toggleClick = () => {
|
|||
<DictTag :type="item.dictType" :value="data[item.field] + ''" />
|
||||
</slot>
|
||||
<slot v-else :name="item.field" :row="data">
|
||||
{{
|
||||
item.mappedField ? data[item.mappedField] : data[item.field]
|
||||
}}
|
||||
{{ item.mappedField ? data[item.mappedField] : data[item.field] }}
|
||||
</slot>
|
||||
</template>
|
||||
</ElDescriptionsItem>
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ $toolbar-position: -55px;
|
|||
width: 80px;
|
||||
height: 25px;
|
||||
font-size: 12px;
|
||||
color: #6a6a6a;
|
||||
line-height: 25px;
|
||||
color: #6a6a6a;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
box-shadow:
|
||||
|
|
|
|||
|
|
@ -94,9 +94,9 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
|
|||
<style scoped lang="scss">
|
||||
.editor-left {
|
||||
z-index: 1;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
box-shadow: 8px 0 8px -8px rgb(0 0 0 / 12%);
|
||||
user-select: none;
|
||||
flex-shrink: 0;
|
||||
|
||||
:deep(.el-collapse) {
|
||||
border-top: none;
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@
|
|||
<div
|
||||
v-if="property.indicator === 'number'"
|
||||
class="absolute bottom-10px right-10px rounded-xl bg-black p-x-8px p-y-2px text-10px text-white opacity-40"
|
||||
>{{ currentIndex }} / {{ property.items.length }}</div
|
||||
>
|
||||
{{ currentIndex }} / {{ property.items.length }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@ const handleToggleFab = () => {
|
|||
/* 模态背景 */
|
||||
.modal-bg {
|
||||
position: absolute;
|
||||
left: calc(50% - 375px / 2);
|
||||
top: 0;
|
||||
left: calc(50% - 375px / 2);
|
||||
z-index: 11;
|
||||
width: 375px;
|
||||
height: 100%;
|
||||
background-color: rgba(#000000, 0.4);
|
||||
background-color: rgb(0 0 0 / 40%);
|
||||
}
|
||||
|
||||
.fab-icon {
|
||||
|
|
|
|||
|
|
@ -192,39 +192,39 @@ const handleAppLinkChange = (appLink: AppLink) => {
|
|||
<style scoped lang="scss">
|
||||
.hot-zone {
|
||||
position: absolute;
|
||||
background: var(--el-color-primary-light-7);
|
||||
opacity: 0.8;
|
||||
border: 1px solid var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
font-size: 16px;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
color: var(--el-color-primary);
|
||||
cursor: move;
|
||||
background: var(--el-color-primary-light-7);
|
||||
border: 1px solid var(--el-color-primary);
|
||||
opacity: 0.8;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: move;
|
||||
z-index: 10;
|
||||
|
||||
/* 控制点 */
|
||||
.ctrl-dot {
|
||||
position: absolute;
|
||||
z-index: 11;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
border: inherit;
|
||||
background-color: #fff;
|
||||
z-index: 11;
|
||||
border: inherit;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.delete {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
padding: 2px 2px 6px 6px;
|
||||
background-color: var(--el-color-primary);
|
||||
border-radius: 0 0 0 80%;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
background-color: var(--el-color-primary);
|
||||
border-radius: 0 0 0 80%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
|
|||
|
|
@ -28,15 +28,15 @@ const props = defineProps<{ property: HotZoneProperty }>()
|
|||
<style scoped lang="scss">
|
||||
.hot-zone {
|
||||
position: absolute;
|
||||
background: var(--el-color-primary-light-7);
|
||||
opacity: 0.8;
|
||||
border: 1px solid var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
font-size: 14px;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: var(--el-color-primary);
|
||||
cursor: move;
|
||||
background: var(--el-color-primary-light-7);
|
||||
border: 1px solid var(--el-color-primary);
|
||||
opacity: 0.8;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: move;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -42,22 +42,22 @@ const handleOpenEditDialog = () => {
|
|||
<style scoped lang="scss">
|
||||
.hot-zone {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
cursor: move;
|
||||
background: #409effbf;
|
||||
border: 1px solid var(--el-color-primary);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: move;
|
||||
|
||||
/* 控制点 */
|
||||
.ctrl-dot {
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</template>
|
||||
|
||||
|
|
@ -103,13 +103,16 @@ watch(
|
|||
.el-carousel__indicator {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
|
||||
.el-carousel__button {
|
||||
--el-carousel-indicator-height: 6px;
|
||||
--el-carousel-indicator-width: 6px;
|
||||
--el-carousel-indicator-out-color: #ff6000;
|
||||
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel__indicator.is-active {
|
||||
.el-carousel__button {
|
||||
--el-carousel-indicator-width: 12px;
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ defineOptions({ name: 'NavigationBarCellProperty' })
|
|||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: NavigationBarCellProperty[]
|
||||
isMp: boolean
|
||||
modelValue?: NavigationBarCellProperty[]
|
||||
isMp?: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: () => [],
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ const getSearchProp = computed(() => (cell: NavigationBarCellProperty) => {
|
|||
.navigation-bar {
|
||||
display: flex;
|
||||
height: 50px;
|
||||
padding: 0 6px;
|
||||
background: #fff;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 6px;
|
||||
|
||||
/* 左边 */
|
||||
.left {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@
|
|||
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||
class="ml-4px text-10px line-through"
|
||||
:style="{ color: property.fields.marketPrice.color }"
|
||||
>¥{{ fenToYuan(spu.marketPrice) }}
|
||||
>
|
||||
¥{{ fenToYuan(spu.marketPrice) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-12px">
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@
|
|||
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||
class="ml-4px text-10px line-through"
|
||||
:style="{ color: property.fields.marketPrice.color }"
|
||||
>¥{{ fenToYuan(spu.marketPrice) }}</span
|
||||
>
|
||||
¥{{ fenToYuan(spu.marketPrice) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-12px">
|
||||
<!-- 销量 -->
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@
|
|||
v-if="property.fields.marketPrice.show && spu.marketPrice"
|
||||
class="ml-4px text-10px line-through"
|
||||
:style="{ color: property.fields.marketPrice.color }"
|
||||
>¥{{ fenToYuan(spu.marketPrice) }}</span
|
||||
>
|
||||
¥{{ fenToYuan(spu.marketPrice) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-12px">
|
||||
<!-- 销量 -->
|
||||
|
|
|
|||
|
|
@ -583,12 +583,12 @@ $toolbar-height: 42px;
|
|||
gap: 8px;
|
||||
|
||||
:deep(.el-tag) {
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
|
||||
border: none;
|
||||
box-shadow: 0 2px 8px 0 rgb(0 0 0 / 10%);
|
||||
|
||||
.el-tag__content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ const { getPrefixCls } = useDesign()
|
|||
const prefixCls = getPrefixCls('form')
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
name: 'Form',
|
||||
props: {
|
||||
// 生成Form的布局结构数组
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ const displayUrl = computed(() => props.url || props.modelValue || '') // 显示
|
|||
const showPreview = computed(() => {
|
||||
return displayUrl.value && isUrl(displayUrl.value)
|
||||
}) // 是否显示预览
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
@ -64,9 +63,9 @@ const showPreview = computed(() => {
|
|||
}
|
||||
|
||||
.iframe-preview {
|
||||
overflow: hidden;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe-content {
|
||||
|
|
@ -76,11 +75,11 @@ const showPreview = computed(() => {
|
|||
|
||||
.iframe-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 200px;
|
||||
background-color: #fafafa;
|
||||
border: 1px dashed #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background-color: #fafafa;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ defineProps({
|
|||
title: propTypes.string.def(''),
|
||||
schema: {
|
||||
type: Array as PropType<Array<string | TipSchema>>,
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
showIndex: propTypes.bool.def(true),
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const { modelValue, color } = useVModels(props, emit)
|
|||
<style scoped lang="scss">
|
||||
:deep(.el-input-group__append) {
|
||||
padding: 0;
|
||||
|
||||
.el-color-picker__trigger {
|
||||
padding: 0;
|
||||
border-left: none;
|
||||
|
|
|
|||
|
|
@ -225,15 +225,16 @@ const eachCube = (callback: (x: number, y: number, cube: Cube) => void) => {
|
|||
<style lang="scss" scoped>
|
||||
.cube-table {
|
||||
position: relative;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
|
||||
.cube {
|
||||
border: 1px solid var(--el-border-color);
|
||||
text-align: center;
|
||||
color: var(--el-text-color-secondary);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--el-border-color);
|
||||
box-sizing: border-box;
|
||||
|
||||
&.active {
|
||||
background: var(--el-color-primary-light-9);
|
||||
}
|
||||
|
|
@ -242,28 +243,28 @@ const eachCube = (callback: (x: number, y: number, cube: Cube) => void) => {
|
|||
.hot-area {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
color: var(--el-color-primary);
|
||||
cursor: pointer;
|
||||
background: var(--el-color-primary-light-8);
|
||||
border: 1px solid var(--el-color-primary);
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--el-color-primary);
|
||||
background: var(--el-color-primary-light-8);
|
||||
color: var(--el-color-primary);
|
||||
box-sizing: border-box;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
cursor: pointer;
|
||||
|
||||
.btn-delete {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,14 +51,14 @@ onMounted(async () => {
|
|||
|
||||
<style lang="scss">
|
||||
.markdown-view {
|
||||
font-family: PingFang SC;
|
||||
max-width: 100%;
|
||||
font-family: 'PingFang SC';
|
||||
font-size: 0.95rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.6rem;
|
||||
letter-spacing: 0em;
|
||||
text-align: left;
|
||||
letter-spacing: 0;
|
||||
color: #3b3e55;
|
||||
max-width: 100%;
|
||||
text-align: left;
|
||||
|
||||
pre {
|
||||
position: relative;
|
||||
|
|
@ -69,22 +69,23 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
code.hljs {
|
||||
border-radius: 6px;
|
||||
padding-top: 20px;
|
||||
width: auto;
|
||||
@media screen and (min-width: 1536px) {
|
||||
padding-top: 20px;
|
||||
border-radius: 6px;
|
||||
|
||||
@media screen and (width >= 1536px) {
|
||||
width: 960px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1536px) and (min-width: 1024px) {
|
||||
@media screen and (width <= 1536px) and (width >= 1024px) {
|
||||
width: calc(100vw - 400px - 64px - 32px * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) and (min-width: 768px) {
|
||||
@media screen and (width <= 1024px) and (width >= 768px) {
|
||||
width: calc(100vw - 32px * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
@media screen and (width <= 768px) {
|
||||
width: calc(100vw - 16px * 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -107,9 +108,9 @@ onMounted(async () => {
|
|||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--color-G900);
|
||||
margin: 24px 0 8px;
|
||||
font-weight: 600;
|
||||
color: #3b3e55;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
@ -145,8 +146,8 @@ onMounted(async () => {
|
|||
/* 列表(有序,无序) */
|
||||
ul,
|
||||
ol {
|
||||
margin: 0 0 8px 0;
|
||||
padding: 0;
|
||||
margin: 0 0 8px;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #3b3e55; // var(--color-CG600);
|
||||
|
|
@ -158,8 +159,8 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
ol > li {
|
||||
list-style-type: decimal;
|
||||
margin-bottom: 1rem;
|
||||
list-style-type: decimal;
|
||||
// 表达式,修复有序列表序号展示不全的问题
|
||||
// &:nth-child(n + 10) {
|
||||
// margin-left: 30px;
|
||||
|
|
@ -171,23 +172,23 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
ul > li {
|
||||
list-style-type: disc;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
margin-right: 11px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #3b3e55; // var(--color-G900);
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
ol ul,
|
||||
ol ul > li,
|
||||
ul ul,
|
||||
ul ul li {
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 6px;
|
||||
// list-style: circle;
|
||||
font-size: 16px;
|
||||
list-style: none;
|
||||
margin-left: 6px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ul ul ul,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import { ElTag } from 'element-plus'
|
|||
defineOptions({ name: 'OperateLogV2' })
|
||||
|
||||
interface Props {
|
||||
logList: OperateLogVO[] // 操作日志列表
|
||||
logList?: OperateLogVO[] // 操作日志列表
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
|
|
|
|||
|
|
@ -246,9 +246,9 @@ onMounted(() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.simple-process-model-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
user-select: none; // 禁用文本选择
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,18 +17,18 @@
|
|||
v-model="currentNode.name"
|
||||
:placeholder="currentNode.name"
|
||||
/>
|
||||
<div v-else class="node-name"
|
||||
>{{ currentNode.name }}
|
||||
<Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()"
|
||||
/></div>
|
||||
<div v-else class="node-name">
|
||||
{{ currentNode.name }}
|
||||
<Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" />
|
||||
</div>
|
||||
|
||||
<div class="divide-line"></div>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<div class="mb-3 font-size-16px" v-if="currentNode.conditionSetting?.defaultFlow"
|
||||
>未满足其它条件时,将进入此分支(该分支不可编辑和删除)</div
|
||||
>
|
||||
<div class="mb-3 font-size-16px" v-if="currentNode.conditionSetting?.defaultFlow">
|
||||
未满足其它条件时,将进入此分支(该分支不可编辑和删除)
|
||||
</div>
|
||||
<div v-else>
|
||||
<Condition ref="conditionRef" v-model="condition" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -218,8 +218,9 @@
|
|||
:value="FieldPermissionType.READ"
|
||||
size="large"
|
||||
:label="FieldPermissionType.WRITE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
|
|
@ -227,16 +228,18 @@
|
|||
size="large"
|
||||
:label="FieldPermissionType.WRITE"
|
||||
disabled
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
:value="FieldPermissionType.NONE"
|
||||
size="large"
|
||||
:label="FieldPermissionType.NONE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -95,24 +95,27 @@
|
|||
:value="FieldPermissionType.READ"
|
||||
size="large"
|
||||
:label="FieldPermissionType.READ"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
:value="FieldPermissionType.WRITE"
|
||||
size="large"
|
||||
:label="FieldPermissionType.WRITE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
:value="FieldPermissionType.NONE"
|
||||
size="large"
|
||||
:label="FieldPermissionType.NONE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@
|
|||
<div>
|
||||
<el-divider content-position="left">跳过表达式</el-divider>
|
||||
<el-form-item prop="skipExpression">
|
||||
<el-input v-model="configForm.skipExpression" type="textarea" />
|
||||
<el-input v-model="configForm.skipExpression" type="textarea" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
|
@ -444,9 +444,9 @@
|
|||
:placeholder="item.displayName"
|
||||
v-if="btnDisplayNameEdit[index]"
|
||||
/>
|
||||
<el-button v-else text @click="changeBtnDisplayName(index)"
|
||||
>{{ item.displayName }} <Icon icon="ep:edit"
|
||||
/></el-button>
|
||||
<el-button v-else text @click="changeBtnDisplayName(index)">
|
||||
{{ item.displayName }} <Icon icon="ep:edit" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="button-setting-item-label">
|
||||
<el-switch v-model="item.enable" />
|
||||
|
|
@ -483,24 +483,27 @@
|
|||
:value="FieldPermissionType.READ"
|
||||
size="large"
|
||||
:label="FieldPermissionType.READ"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
:value="FieldPermissionType.WRITE"
|
||||
size="large"
|
||||
:label="FieldPermissionType.WRITE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
<div class="item-radio-wrap">
|
||||
<el-radio
|
||||
:value="FieldPermissionType.NONE"
|
||||
size="large"
|
||||
:label="FieldPermissionType.NONE"
|
||||
><span></span
|
||||
></el-radio>
|
||||
>
|
||||
<span></span>
|
||||
</el-radio>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@
|
|||
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,63 +1,67 @@
|
|||
<template>
|
||||
<div class="end-node-wrapper">
|
||||
<div class="end-node-box cursor-pointer" :class="`${useTaskStatusClass(currentNode?.activityStatus)}`" @click="nodeClick">
|
||||
<div
|
||||
class="end-node-box cursor-pointer"
|
||||
:class="`${useTaskStatusClass(currentNode?.activityStatus)}`"
|
||||
@click="nodeClick"
|
||||
>
|
||||
<span class="node-fixed-name" title="结束">结束</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="审批信息" v-model="dialogVisible" width="1000px" append-to-body>
|
||||
<el-row>
|
||||
<el-table
|
||||
:data="processInstanceInfos"
|
||||
size="small"
|
||||
border
|
||||
header-cell-class-name="table-header-gray"
|
||||
>
|
||||
<el-table-column
|
||||
label="序号"
|
||||
header-align="center"
|
||||
align="center"
|
||||
type="index"
|
||||
width="50"
|
||||
/>
|
||||
<el-table-column
|
||||
label="发起人"
|
||||
prop="assigneeUser.nickname"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column label="部门" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:formatter="dateFormatter"
|
||||
align="center"
|
||||
label="开始时间"
|
||||
prop="createTime"
|
||||
min-width="140"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="dateFormatter"
|
||||
align="center"
|
||||
label="结束时间"
|
||||
prop="endTime"
|
||||
min-width="140"
|
||||
/>
|
||||
<el-table-column align="center" label="审批状态" prop="status" min-width="90">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
|
||||
<template #default="scope">
|
||||
{{ formatPast2(scope.row.durationInMillis) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
<el-row>
|
||||
<el-table
|
||||
:data="processInstanceInfos"
|
||||
size="small"
|
||||
border
|
||||
header-cell-class-name="table-header-gray"
|
||||
>
|
||||
<el-table-column
|
||||
label="序号"
|
||||
header-align="center"
|
||||
align="center"
|
||||
type="index"
|
||||
width="50"
|
||||
/>
|
||||
<el-table-column
|
||||
label="发起人"
|
||||
prop="assigneeUser.nickname"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column label="部门" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:formatter="dateFormatter"
|
||||
align="center"
|
||||
label="开始时间"
|
||||
prop="createTime"
|
||||
min-width="140"
|
||||
/>
|
||||
<el-table-column
|
||||
:formatter="dateFormatter"
|
||||
align="center"
|
||||
label="结束时间"
|
||||
prop="endTime"
|
||||
min-width="140"
|
||||
/>
|
||||
<el-table-column align="center" label="审批状态" prop="status" min-width="90">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
|
||||
<template #default="scope">
|
||||
{{ formatPast2(scope.row.durationInMillis) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { SimpleFlowNode } from '../consts'
|
||||
|
|
@ -83,17 +87,17 @@ const dialogVisible = ref(false) // 弹窗可见性
|
|||
const processInstanceInfos = ref<any[]>([]) // 流程的审批信息
|
||||
|
||||
const nodeClick = () => {
|
||||
if (readonly) {
|
||||
if(processInstance && processInstance.value){
|
||||
if (readonly) {
|
||||
if (processInstance && processInstance.value) {
|
||||
processInstanceInfos.value = [
|
||||
{
|
||||
assigneeUser: processInstance.value.startUser,
|
||||
createTime: processInstance.value.startTime,
|
||||
endTime: processInstance.value.endTime,
|
||||
status: processInstance.value.status,
|
||||
durationInMillis: processInstance.value.durationInMillis
|
||||
}
|
||||
]
|
||||
{
|
||||
assigneeUser: processInstance.value.startUser,
|
||||
createTime: processInstance.value.startTime,
|
||||
endTime: processInstance.value.endTime,
|
||||
status: processInstance.value.status,
|
||||
durationInMillis: processInstance.value.durationInMillis
|
||||
}
|
||||
]
|
||||
dialogVisible.value = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
>
|
||||
<span class="iconfont icon-exclusive icon-size condition"></span>
|
||||
</div>
|
||||
<el-button v-else class="branch-node-add" color="#67c23a" @click="addCondition" plain
|
||||
>添加条件</el-button
|
||||
>
|
||||
<el-button v-else class="branch-node-add" color="#67c23a" @click="addCondition" plain>
|
||||
添加条件
|
||||
</el-button>
|
||||
|
||||
<div
|
||||
class="branch-node-item"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
>
|
||||
<span class="iconfont icon-inclusive icon-size inclusive"></span>
|
||||
</div>
|
||||
<el-button v-else class="branch-node-add" color="#345da2" @click="addCondition" plain
|
||||
>添加条件</el-button
|
||||
>
|
||||
<el-button v-else class="branch-node-add" color="#345da2" @click="addCondition" plain>
|
||||
添加条件
|
||||
</el-button>
|
||||
<div
|
||||
class="branch-node-item"
|
||||
v-for="(item, index) in currentNode.conditionNodes"
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
>
|
||||
<span class="iconfont icon-parallel icon-size parallel"></span>
|
||||
</div>
|
||||
<el-button v-else class="branch-node-add" color="#626aef" @click="addCondition" plain
|
||||
>添加分支</el-button
|
||||
>
|
||||
<el-button v-else class="branch-node-add" color="#626aef" @click="addCondition" plain>
|
||||
添加分支
|
||||
</el-button>
|
||||
<div
|
||||
class="branch-node-item"
|
||||
v-for="(item, index) in currentNode.conditionNodes"
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@
|
|||
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
]"
|
||||
>
|
||||
<div class="node-title-container">
|
||||
<div class="node-title-icon start-user"
|
||||
><span class="iconfont icon-start-user"></span
|
||||
></div>
|
||||
<div class="node-title-icon start-user">
|
||||
<span class="iconfont icon-start-user"></span>
|
||||
</div>
|
||||
<input
|
||||
v-if="!readonly && showInput"
|
||||
type="text"
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@
|
|||
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@
|
|||
<Icon icon="ep:arrow-right-bold" v-if="!readonly" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon"
|
||||
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||
/></div>
|
||||
<div class="toolbar-icon">
|
||||
<Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { set } from 'lodash-es'
|
|||
import { Pagination, TableColumn, TableSetPropsType, TableSlotDefault } from '@/types/table'
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
name: 'Table',
|
||||
props: {
|
||||
pageSize: propTypes.number.def(10),
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import { ElTable } from 'element-plus'
|
|||
defineOptions({ name: 'TableSelectForm' })
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any[]
|
||||
title: string
|
||||
modelValue?: any[]
|
||||
title?: string
|
||||
}>(),
|
||||
{ modelValue: () => [], title: '选择' }
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="upload-box">
|
||||
<div class="upload-box" :style="uploadStyle">
|
||||
<el-upload
|
||||
:id="uuid"
|
||||
:accept="fileType.join(',')"
|
||||
|
|
@ -82,6 +82,13 @@ const props = defineProps({
|
|||
showBtnText: propTypes.bool.def(true), // 是否显示按钮文字
|
||||
directory: propTypes.string.def(undefined) // 上传目录 ==> 非必传(默认为 undefined)
|
||||
})
|
||||
|
||||
const uploadStyle = computed(() => ({
|
||||
'--upload-width': props.width,
|
||||
'--upload-height': props.height,
|
||||
'--upload-border-radius': props.borderradius
|
||||
}))
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
// 生成组件唯一id
|
||||
|
|
@ -167,11 +174,11 @@ const uploadError = () => {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
width: var(--upload-width);
|
||||
height: var(--upload-height);
|
||||
overflow: hidden;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderradius);
|
||||
border-radius: var(--upload-border-radius);
|
||||
transition: var(--el-transition-duration-fast);
|
||||
|
||||
&:hover {
|
||||
|
|
@ -192,7 +199,7 @@ const uploadError = () => {
|
|||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderradius);
|
||||
border-radius: var(--upload-border-radius);
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-color-primary);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="upload-box">
|
||||
<div class="upload-box" :style="uploadStyle">
|
||||
<el-upload
|
||||
v-model:file-list="fileList"
|
||||
:accept="fileType.join(',')"
|
||||
|
|
@ -85,6 +85,12 @@ const props = defineProps({
|
|||
directory: propTypes.string.def(undefined) // 上传目录 ==> 非必传(默认为 undefined)
|
||||
})
|
||||
|
||||
const uploadStyle = computed(() => ({
|
||||
'--upload-width': props.width,
|
||||
'--upload-height': props.height,
|
||||
'--upload-border-radius': props.borderradius
|
||||
}))
|
||||
|
||||
const { uploadUrl, httpRequest } = useUpload(props.directory)
|
||||
|
||||
const fileList = ref<UploadUserFile[]>([])
|
||||
|
|
@ -238,7 +244,7 @@ const handleExceed = () => {
|
|||
padding: 0;
|
||||
overflow: hidden;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: v-bind(borderradius);
|
||||
border-radius: var(--upload-border-radius);
|
||||
|
||||
&:hover {
|
||||
border: 1px dashed var(--el-color-primary);
|
||||
|
|
@ -252,10 +258,10 @@ const handleExceed = () => {
|
|||
|
||||
.el-upload-list__item,
|
||||
.el-upload--picture-card {
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
width: var(--upload-width);
|
||||
height: var(--upload-height);
|
||||
background-color: transparent;
|
||||
border-radius: v-bind(borderradius);
|
||||
border-radius: var(--upload-border-radius);
|
||||
}
|
||||
|
||||
.upload-image {
|
||||
|
|
|
|||
|
|
@ -158,11 +158,13 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|||
.el-transfer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.el-transfer__buttons {
|
||||
display: flex !important;
|
||||
flex-direction: column-reverse;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
|
||||
.el-transfer__button:nth-child(2) {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,41 @@ const processReZoom = () => {
|
|||
bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto')
|
||||
}
|
||||
|
||||
let resizeObserver: ResizeObserver | null = null
|
||||
|
||||
/** 停止 ResizeObserver */
|
||||
const stopResizeObserver = () => {
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
resizeObserver = null
|
||||
}
|
||||
}
|
||||
|
||||
/** 启动 ResizeObserver 监听容器尺寸变化 */
|
||||
const startResizeObserver = () => {
|
||||
stopResizeObserver()
|
||||
if (!processCanvas.value || !bpmnViewer.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const { clientWidth, clientHeight } = processCanvas.value
|
||||
if (clientWidth > 0 && clientHeight > 0) {
|
||||
processReZoom()
|
||||
return
|
||||
}
|
||||
|
||||
resizeObserver = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
const { width, height } = entry.contentRect
|
||||
if (width > 0 && height > 0 && bpmnViewer.value) {
|
||||
processReZoom()
|
||||
stopResizeObserver()
|
||||
}
|
||||
}
|
||||
})
|
||||
resizeObserver.observe(processCanvas.value)
|
||||
}
|
||||
|
||||
/** Zoom:放大 */
|
||||
const processZoomIn = (zoomStep = 0.1) => {
|
||||
let newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100
|
||||
|
|
@ -198,6 +233,7 @@ const processZoomOut = (zoomStep = 0.1) => {
|
|||
|
||||
/** 流程图预览清空 */
|
||||
const clearViewer = () => {
|
||||
stopResizeObserver()
|
||||
if (processCanvas.value) {
|
||||
processCanvas.value.innerHTML = ''
|
||||
}
|
||||
|
|
@ -277,6 +313,12 @@ const importXML = async (xml: string) => {
|
|||
isLoading.value = false
|
||||
// 高亮流程
|
||||
setProcessStatus(props.view)
|
||||
// 启动 ResizeObserver,等待容器可见且有尺寸时自动居中
|
||||
// 对应 https://github.com/yudaocode/yudao-ui-admin-vue3/pull/221 场景
|
||||
if (bpmnViewer.value) {
|
||||
await nextTick()
|
||||
startResizeObserver()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import { isFunction, isObject, some } from 'min-dash'
|
|||
const WILDCARD = '*'
|
||||
|
||||
function CamundaModdleExtension(eventBus) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const self = this
|
||||
|
||||
eventBus.on('moddleCopy.canCopyProperty', function (context) {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
<element-form :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="task" v-if="isTaskCollapseItemShow(elementType)" key="task">
|
||||
<template #title
|
||||
><Icon icon="ep:checked" />{{ getTaskCollapseItemName(elementType) }}</template
|
||||
>
|
||||
<template #title>
|
||||
<Icon icon="ep:checked" />{{ getTaskCollapseItemName(elementType) }}
|
||||
</template>
|
||||
<element-task :id="elementId" :type="elementType" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@
|
|||
:placeholder="item.displayName"
|
||||
v-if="btnDisplayNameEdit[index]"
|
||||
/>
|
||||
<el-button v-else text @click="changeBtnDisplayName(index)"
|
||||
>{{ item.displayName }} <Icon icon="ep:edit"
|
||||
/></el-button>
|
||||
<el-button v-else text @click="changeBtnDisplayName(index)">
|
||||
{{ item.displayName }} <Icon icon="ep:edit" />
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="button-setting-item-label">
|
||||
<el-switch v-model="item.enable" @change="updateElementExtensions" />
|
||||
|
|
@ -127,15 +127,15 @@
|
|||
<div class="field-permit-title">
|
||||
<div class="setting-title-label first-title"> 字段名称 </div>
|
||||
<div class="other-titles">
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('READ')"
|
||||
>只读</span
|
||||
>
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('WRITE')"
|
||||
>可编辑</span
|
||||
>
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('NONE')"
|
||||
>隐藏</span
|
||||
>
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('READ')">
|
||||
只读
|
||||
</span>
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('WRITE')">
|
||||
可编辑
|
||||
</span>
|
||||
<span class="setting-title-label cursor-pointer" @click="updatePermission('NONE')">
|
||||
隐藏
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-setting-item" v-for="(item, index) in fieldsPermissionEl" :key="index">
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@
|
|||
/>
|
||||
<el-table-column label="操作" width="100px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button size="small" link style="color: #ff4d4f" @click="removeListener(scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
<el-button size="small" link style="color: #ff4d4f" @click="removeListener(scope.$index)">
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -167,17 +167,18 @@
|
|||
/>
|
||||
<el-table-column label="操作" width="130px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListenerField(scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -419,10 +420,7 @@ const saveListenerConfig = async () => {
|
|||
bpmnElement.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:ExecutionListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
updateElementExtensions(bpmnElement, otherExtensionList.value.concat(bpmnElementListeners.value))
|
||||
// 4. 隐藏侧边栏
|
||||
listenerFormModelVisible.value = false
|
||||
listenerForm.value = {}
|
||||
|
|
@ -448,10 +446,7 @@ const selectProcessListener = (listener) => {
|
|||
bpmnElement.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:ExecutionListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
updateElementExtensions(bpmnElement, otherExtensionList.value.concat(bpmnElementListeners.value))
|
||||
}
|
||||
|
||||
watch(
|
||||
|
|
|
|||
|
|
@ -17,17 +17,18 @@
|
|||
/>
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListener(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -183,9 +184,9 @@
|
|||
<el-divider />
|
||||
<p class="listener-filed__title">
|
||||
<span><Icon icon="ep:menu" />注入字段:</span>
|
||||
<el-button size="small" type="primary" @click="openListenerFieldForm(null)"
|
||||
>添加字段</el-button
|
||||
>
|
||||
<el-button size="small" type="primary" @click="openListenerFieldForm(null)">
|
||||
添加字段
|
||||
</el-button>
|
||||
</p>
|
||||
<el-table
|
||||
:data="fieldsListOfListener"
|
||||
|
|
@ -211,17 +212,18 @@
|
|||
/>
|
||||
<el-table-column label="操作" width="100px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListenerField(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -423,10 +425,7 @@ const saveListenerConfig = async () => {
|
|||
bpmnElement.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
updateElementExtensions(bpmnElement, otherExtensionList.value.concat(bpmnElementListeners.value))
|
||||
// 4. 隐藏侧边栏
|
||||
listenerFormModelVisible.value = false
|
||||
listenerForm.value = {}
|
||||
|
|
@ -490,10 +489,7 @@ const selectProcessListener = (listener) => {
|
|||
bpmnElement.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
updateElementExtensions(bpmnElement, otherExtensionList.value.concat(bpmnElementListeners.value))
|
||||
}
|
||||
|
||||
watch(
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-radio-group>
|
||||
<div v-else>
|
||||
除了UserTask以外节点的多实例待实现
|
||||
</div>
|
||||
<div v-else> 除了UserTask以外节点的多实例待实现 </div>
|
||||
<!-- 与Simple设计器配置合并,保留以前的代码 -->
|
||||
<el-form label-width="90px" style="display: none">
|
||||
<el-form-item label="快捷配置">
|
||||
|
|
|
|||
|
|
@ -141,8 +141,8 @@ watch(
|
|||
.header-editor {
|
||||
.header-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.header-item {
|
||||
|
|
@ -156,8 +156,8 @@ watch(
|
|||
}
|
||||
|
||||
.separator {
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.header-value {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
<div style="margin-bottom: 8px">
|
||||
<el-radio-group v-model="cronMode[f.key]" :key="'radio-' + f.key">
|
||||
<el-radio label="every" :key="'every-' + f.key">每{{ f.label }}</el-radio>
|
||||
<el-radio label="range" :key="'range-' + f.key"
|
||||
>从
|
||||
<el-radio label="range" :key="'range-' + f.key">
|
||||
从
|
||||
<el-input-number
|
||||
v-model="cronRange[f.key][0]"
|
||||
:min="f.min"
|
||||
|
|
@ -42,10 +42,10 @@
|
|||
style="width: 60px"
|
||||
:key="'range1-' + f.key"
|
||||
/>
|
||||
之间每{{ f.label }}</el-radio
|
||||
>
|
||||
<el-radio label="step" :key="'step-' + f.key"
|
||||
>从第
|
||||
之间每{{ f.label }}
|
||||
</el-radio>
|
||||
<el-radio label="step" :key="'step-' + f.key">
|
||||
从第
|
||||
<el-input-number
|
||||
v-model="cronStep[f.key][0]"
|
||||
:min="f.min"
|
||||
|
|
@ -63,8 +63,8 @@
|
|||
style="width: 60px"
|
||||
:key="'step1-' + f.key"
|
||||
/>
|
||||
{{ f.label }}</el-radio
|
||||
>
|
||||
{{ f.label }}
|
||||
</el-radio>
|
||||
<el-radio label="appoint" :key="'appoint-' + f.key">指定</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
|
@ -74,8 +74,9 @@
|
|||
v-for="n in f.max + 1"
|
||||
:label="pad(n - 1)"
|
||||
:key="'cb-' + f.key + '-' + (n - 1)"
|
||||
>{{ pad(n - 1) }}</el-checkbox
|
||||
>
|
||||
{{ pad(n - 1) }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
|
@ -90,73 +91,79 @@
|
|||
:key="'isoStr'"
|
||||
/>
|
||||
</div>
|
||||
<div style="margin-bottom: 10px"
|
||||
>循环次数:<el-input-number v-model="repeat" :min="1" style="width: 100px" :key="'repeat'"
|
||||
/></div>
|
||||
<div style="margin-bottom: 10px"
|
||||
>日期时间:<el-date-picker
|
||||
<div style="margin-bottom: 10px">
|
||||
循环次数:<el-input-number v-model="repeat" :min="1" style="width: 100px" :key="'repeat'" />
|
||||
</div>
|
||||
<div style="margin-bottom: 10px">
|
||||
日期时间:<el-date-picker
|
||||
v-model="isoDate"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
style="width: 200px"
|
||||
:key="'isoDate'"
|
||||
/></div>
|
||||
<div style="margin-bottom: 10px"
|
||||
>当前时长:<el-input
|
||||
/>
|
||||
</div>
|
||||
<div style="margin-bottom: 10px">
|
||||
当前时长:<el-input
|
||||
v-model="isoDuration"
|
||||
placeholder="如P3DT30M30S"
|
||||
style="width: 200px"
|
||||
:key="'isoDuration'"
|
||||
/></div>
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
>秒:<el-button
|
||||
<div>
|
||||
秒:<el-button
|
||||
v-for="s in [5, 10, 30, 50]"
|
||||
@click="setDuration('S', s)"
|
||||
:key="'sec-' + s"
|
||||
>{{ s }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
<div
|
||||
>分:<el-button
|
||||
>
|
||||
{{ s }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
<div>
|
||||
分:<el-button
|
||||
v-for="m in [5, 10, 30, 50]"
|
||||
@click="setDuration('M', m)"
|
||||
:key="'min-' + m"
|
||||
>{{ m }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
<div
|
||||
>小时:<el-button
|
||||
>
|
||||
{{ m }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
<div>
|
||||
小时:<el-button
|
||||
v-for="h in [4, 8, 12, 24]"
|
||||
@click="setDuration('H', h)"
|
||||
:key="'hour-' + h"
|
||||
>{{ h }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
<div
|
||||
>天:<el-button
|
||||
v-for="d in [1, 2, 3, 4]"
|
||||
@click="setDuration('D', d)"
|
||||
:key="'day-' + d"
|
||||
>{{ d }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
<div
|
||||
>月:<el-button
|
||||
>
|
||||
{{ h }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
<div>
|
||||
天:<el-button v-for="d in [1, 2, 3, 4]" @click="setDuration('D', d)" :key="'day-' + d">
|
||||
{{ d }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
<div>
|
||||
月:<el-button
|
||||
v-for="mo in [1, 2, 3, 4]"
|
||||
@click="setDuration('M', mo)"
|
||||
:key="'mon-' + mo"
|
||||
>{{ mo }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
<div
|
||||
>年:<el-button
|
||||
v-for="y in [1, 2, 3, 4]"
|
||||
@click="setDuration('Y', y)"
|
||||
:key="'year-' + y"
|
||||
>{{ y }}</el-button
|
||||
>自定义</div
|
||||
>
|
||||
>
|
||||
{{ mo }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
<div>
|
||||
年:<el-button v-for="y in [1, 2, 3, 4]" @click="setDuration('Y', y)" :key="'year-' + y">
|
||||
{{ y }}
|
||||
</el-button>
|
||||
自定义
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div>
|
||||
<div style="margin-bottom: 10px"
|
||||
>当前选择:<el-input v-model="isoString" readonly style="width: 300px"
|
||||
/></div>
|
||||
<div style="margin-bottom: 10px">
|
||||
当前选择:<el-input v-model="isoString" readonly style="width: 300px" />
|
||||
</div>
|
||||
<div v-for="unit in units" :key="unit.key" style="margin-bottom: 8px">
|
||||
<span>{{ unit.label }}:</span>
|
||||
<el-button-group>
|
||||
|
|
@ -11,8 +11,9 @@
|
|||
:key="val"
|
||||
size="mini"
|
||||
@click="setUnit(unit.key, val)"
|
||||
>{{ val }}</el-button
|
||||
>
|
||||
{{ val }}
|
||||
</el-button>
|
||||
<el-input
|
||||
v-model.number="custom[unit.key]"
|
||||
size="mini"
|
||||
|
|
|
|||
|
|
@ -3,22 +3,23 @@
|
|||
<div style="margin-top: 10px">
|
||||
<span>类型:</span>
|
||||
<el-button-group>
|
||||
<el-button size="mini" :type="type === 'time' ? 'primary' : ''" @click="setType('time')"
|
||||
>时间</el-button
|
||||
>
|
||||
<el-button size="mini" :type="type === 'time' ? 'primary' : ''" @click="setType('time')">
|
||||
时间
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
:type="type === 'duration' ? 'primary' : ''"
|
||||
@click="setType('duration')"
|
||||
>持续</el-button
|
||||
>
|
||||
<el-button size="mini" :type="type === 'cycle' ? 'primary' : ''" @click="setType('cycle')"
|
||||
>循环</el-button
|
||||
>
|
||||
持续
|
||||
</el-button>
|
||||
<el-button size="mini" :type="type === 'cycle' ? 'primary' : ''" @click="setType('cycle')">
|
||||
循环
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<el-icon v-if="valid" color="green" style="margin-left: 8px"><CircleCheckFilled /></el-icon>
|
||||
</div>
|
||||
<div style="margin-top: 10px; display: flex; align-items: center">
|
||||
<div style="display: flex; margin-top: 10px; align-items: center">
|
||||
<span>条件:</span>
|
||||
<el-input
|
||||
v-model="condition"
|
||||
|
|
@ -33,9 +34,9 @@
|
|||
<el-icon color="orange"><WarningFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="helpText" placement="top">
|
||||
<el-icon color="#409EFF" style="cursor: pointer" @click="showHelp = true"
|
||||
><QuestionFilled
|
||||
/></el-icon>
|
||||
<el-icon color="#409EFF" style="cursor: pointer" @click="showHelp = true">
|
||||
<QuestionFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
v-if="type === 'time'"
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`"
|
||||
>{{ t('analysis.newUser') }}
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">
|
||||
{{ t('analysis.newUser') }}
|
||||
</div>
|
||||
<CountTo
|
||||
:duration="2600"
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`"
|
||||
>{{ t('analysis.unreadInformation') }}
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">
|
||||
{{ t('analysis.unreadInformation') }}
|
||||
</div>
|
||||
<CountTo
|
||||
:duration="2600"
|
||||
|
|
@ -71,8 +71,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`"
|
||||
>{{ t('analysis.transactionAmount') }}
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">
|
||||
{{ t('analysis.transactionAmount') }}
|
||||
</div>
|
||||
<CountTo
|
||||
:duration="2600"
|
||||
|
|
@ -100,8 +100,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`"
|
||||
>{{ t('analysis.totalShopping') }}
|
||||
<div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">
|
||||
{{ t('analysis.totalShopping') }}
|
||||
</div>
|
||||
<CountTo
|
||||
:duration="2600"
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@
|
|||
<!-- 右上角的主题、语言选择 -->
|
||||
<div
|
||||
class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"
|
||||
style="color: var(--el-text-color-primary);"
|
||||
style="color: var(--el-text-color-primary)"
|
||||
>
|
||||
<div class="flex items-center at-2xl:hidden at-xl:hidden">
|
||||
<img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
|
||||
<span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-end space-x-10px h-48px">
|
||||
<ThemeSwitch />
|
||||
|
|
@ -75,7 +75,14 @@ import { useAppStore } from '@/store/modules/app'
|
|||
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
|
||||
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
||||
|
||||
import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue, ForgetPasswordForm } from './components'
|
||||
import {
|
||||
LoginForm,
|
||||
MobileForm,
|
||||
QrCodeForm,
|
||||
RegisterForm,
|
||||
SSOLoginVue,
|
||||
ForgetPasswordForm
|
||||
} from './components'
|
||||
|
||||
defineOptions({ name: 'Login' })
|
||||
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@
|
|||
</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :offset="6" :span="12">
|
||||
<el-link style="float: right" type="primary"
|
||||
>{{ t('login.forgetPassword') }}
|
||||
<el-link style="float: right" type="primary">
|
||||
{{ t('login.forgetPassword') }}
|
||||
</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@
|
|||
class="py-0.5 px-2.5"
|
||||
style="
|
||||
max-width: 220px;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--el-text-color-regular);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
"
|
||||
>
|
||||
{{ conversation.title }}
|
||||
|
|
@ -103,9 +103,9 @@
|
|||
<div
|
||||
class="absolute bottom-0 left-0 right-0 px-5 leading-8.75 flex justify-between items-center"
|
||||
style="
|
||||
color: var(--el-text-color);
|
||||
background-color: var(--el-fill-color-extra-light);
|
||||
box-shadow: 0 0 1px 1px var(--el-border-color-lighter);
|
||||
color: var(--el-text-color);
|
||||
"
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -53,11 +53,12 @@
|
|||
<Icon :icon="getFileIcon(file.name)" class="text-blue-500 mr-2 flex-shrink-0" />
|
||||
<span
|
||||
class="font-medium text-gray-900 mr-1 overflow-hidden text-ellipsis whitespace-nowrap flex-1"
|
||||
>{{ file.name }}</span
|
||||
>
|
||||
<span class="text-gray-500 flex-shrink-0 text-11px"
|
||||
>({{ formatFileSize(file.size) }})</span
|
||||
>
|
||||
{{ file.name }}
|
||||
</span>
|
||||
<span class="text-gray-500 flex-shrink-0 text-11px">
|
||||
({{ formatFileSize(file.size) }})
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 flex-shrink-0 ml-2">
|
||||
<el-progress
|
||||
|
|
@ -286,27 +287,29 @@ onUnmounted(() => {
|
|||
--el-button-border-color: transparent;
|
||||
--el-button-hover-bg-color: var(--el-fill-color-light);
|
||||
--el-button-hover-border-color: transparent;
|
||||
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
|
||||
.upload-btn.has-files {
|
||||
color: var(--el-color-primary);
|
||||
--el-button-hover-bg-color: var(--el-color-primary-light-9);
|
||||
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.file-tooltip {
|
||||
position: absolute;
|
||||
bottom: calc(100% + 8px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
max-width: 320px;
|
||||
min-width: 240px;
|
||||
padding: 8px;
|
||||
background: white;
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
z-index: 1000;
|
||||
min-width: 240px;
|
||||
max-width: 320px;
|
||||
padding: 8px;
|
||||
transform: translateX(-50%);
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
|
||||
animation: fadeInDown 0.2s ease;
|
||||
}
|
||||
|
||||
|
|
@ -314,25 +317,25 @@ onUnmounted(() => {
|
|||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 5px solid var(--el-border-color-light);
|
||||
border-right: 5px solid transparent;
|
||||
border-left: 5px solid transparent;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/* Tooltip 箭头伪元素 */
|
||||
.tooltip-arrow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 1px;
|
||||
left: -4px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 4px solid white;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
content: '';
|
||||
}
|
||||
|
||||
@keyframes fadeInDown {
|
||||
|
|
@ -340,6 +343,7 @@ onUnmounted(() => {
|
|||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
|
|
@ -351,6 +355,7 @@ onUnmounted(() => {
|
|||
opacity: 0;
|
||||
transform: translateX(-50%) translateY(4px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
|
|
@ -374,6 +379,7 @@ onUnmounted(() => {
|
|||
.file-list::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--el-border-color);
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.file-list::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
|
|
|
|||
|
|
@ -79,11 +79,11 @@ const toggleExpanded = () => {
|
|||
}
|
||||
|
||||
.max-h-300px::-webkit-scrollbar-thumb {
|
||||
background: rgba(156, 163, 175, 0.4);
|
||||
background: rgb(156 163 175 / 40%);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.max-h-300px::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(156, 163, 175, 0.6);
|
||||
background: rgb(156 163 175 / 60%);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -228,8 +228,8 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
.el-tabs__header {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.el-tabs__nav-wrap {
|
||||
|
|
@ -241,6 +241,6 @@ onMounted(async () => {
|
|||
}
|
||||
|
||||
.el-tab-pane {
|
||||
padding: 8px 0 0 0 !important;
|
||||
padding: 8px 0 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -57,16 +57,16 @@
|
|||
class="content-expand"
|
||||
style="
|
||||
padding: 10px 20px;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
border-left: 3px solid #409eff;
|
||||
border-radius: 4px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="content-title"
|
||||
style="margin-bottom: 8px; color: #606266; font-size: 14px; font-weight: bold"
|
||||
style="margin-bottom: 8px; font-size: 14px; font-weight: bold; color: #606266"
|
||||
>
|
||||
完整内容:
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -143,11 +143,12 @@ defineExpose({
|
|||
flex-direction: column;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
@extend .hide-scroll-bar;
|
||||
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
@extend .hide-scroll-bar;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div class="flex h-full items-stretch">
|
||||
<div class="flex h-full items-stretch">
|
||||
<!-- 模式 -->
|
||||
<Mode class="flex-none" @generate-music="generateMusic"/>
|
||||
<Mode class="flex-none" @generate-music="generateMusic" />
|
||||
<!-- 音频列表 -->
|
||||
<List ref="listRef" class="flex-auto"/>
|
||||
<List ref="listRef" class="flex-auto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -13,14 +13,14 @@ import List from './list/index.vue'
|
|||
|
||||
defineOptions({ name: 'Index' })
|
||||
|
||||
const listRef = ref<Nullable<{generateMusic: (...args) => void}>>(null)
|
||||
const listRef = ref<Nullable<{ generateMusic: (...args) => void }>>(null)
|
||||
|
||||
/*
|
||||
*@Description: 拿到左侧配置信息调用右侧音乐生成的方法
|
||||
*@MethodAuthor: xiaohong
|
||||
*@Date: 2024-07-19 11:13:38
|
||||
*/
|
||||
function generateMusic (args: {formData: Recordable}) {
|
||||
unref(listRef)?.generateMusic(args.formData)
|
||||
*/
|
||||
function generateMusic(args: { formData: Recordable }) {
|
||||
unref(listRef)?.generateMusic(args.formData)
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,34 +1,55 @@
|
|||
<template>
|
||||
<div class="flex items-center justify-between px-2 h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">
|
||||
<div
|
||||
class="flex items-center justify-between px-2 h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none"
|
||||
>
|
||||
<!-- 歌曲信息 -->
|
||||
<div class="flex gap-[10px]">
|
||||
<el-image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" class="w-[45px]"/>
|
||||
<el-image
|
||||
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
|
||||
class="w-[45px]"
|
||||
/>
|
||||
<div>
|
||||
<div>{{currentSong.name}}</div>
|
||||
<div class="text-[12px] text-gray-400">{{currentSong.singer}}</div>
|
||||
<div>{{ currentSong.name }}</div>
|
||||
<div class="text-[12px] text-gray-400">{{ currentSong.singer }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 音频controls -->
|
||||
<div class="flex gap-[12px] items-center">
|
||||
<Icon icon="majesticons:back-circle" :size="20" class="text-gray-300 cursor-pointer"/>
|
||||
<Icon :icon="audioProps.paused ? 'mdi:arrow-right-drop-circle' : 'solar:pause-circle-bold'" :size="30" class=" cursor-pointer" @click="toggleStatus('paused')"/>
|
||||
<Icon icon="majesticons:next-circle" :size="20" class="text-gray-300 cursor-pointer"/>
|
||||
<Icon icon="majesticons:back-circle" :size="20" class="text-gray-300 cursor-pointer" />
|
||||
<Icon
|
||||
:icon="audioProps.paused ? 'mdi:arrow-right-drop-circle' : 'solar:pause-circle-bold'"
|
||||
:size="30"
|
||||
class="cursor-pointer"
|
||||
@click="toggleStatus('paused')"
|
||||
/>
|
||||
<Icon icon="majesticons:next-circle" :size="20" class="text-gray-300 cursor-pointer" />
|
||||
<div class="flex gap-[16px] items-center">
|
||||
<span>{{audioProps.currentTime}}</span>
|
||||
<el-slider v-model="audioProps.duration" color="#409eff" class="w-[160px!important] "/>
|
||||
<span>{{ audioProps.currentTime }}</span>
|
||||
<el-slider v-model="audioProps.duration" color="#409eff" class="w-[160px!important]" />
|
||||
<span>{{ audioProps.duration }}</span>
|
||||
</div>
|
||||
<!-- 音频 -->
|
||||
<audio v-bind="audioProps" ref="audioRef" controls v-show="!audioProps" @timeupdate="audioTimeUpdate">
|
||||
<source :src="audioUrl"/>
|
||||
<audio
|
||||
v-bind="audioProps"
|
||||
ref="audioRef"
|
||||
controls
|
||||
v-show="!audioProps"
|
||||
@timeupdate="audioTimeUpdate"
|
||||
>
|
||||
<source :src="audioUrl" />
|
||||
</audio>
|
||||
</div>
|
||||
|
||||
<!-- 音量控制器 -->
|
||||
<div class="flex gap-[16px] items-center">
|
||||
<Icon :icon="audioProps.muted ? 'tabler:volume-off' : 'tabler:volume'" :size="20" class="cursor-pointer" @click="toggleStatus('muted')"/>
|
||||
<el-slider v-model="audioProps.volume" color="#409eff" class="w-[160px!important] "/>
|
||||
<Icon
|
||||
:icon="audioProps.muted ? 'tabler:volume-off' : 'tabler:volume'"
|
||||
:size="20"
|
||||
class="cursor-pointer"
|
||||
@click="toggleStatus('muted')"
|
||||
/>
|
||||
<el-slider v-model="audioProps.volume" color="#409eff" class="w-[160px!important]" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -42,17 +63,17 @@ defineOptions({ name: 'Index' })
|
|||
const currentSong = inject('currentSong', {})
|
||||
|
||||
const audioRef = ref<Nullable<HTMLElement>>(null)
|
||||
// 音频相关属性https://www.runoob.com/tags/ref-av-dom.html
|
||||
// 音频相关属性https://www.runoob.com/tags/ref-av-dom.html
|
||||
const audioProps = reactive({
|
||||
autoplay: true,
|
||||
paused: false,
|
||||
currentTime: '00:00',
|
||||
duration: '00:00',
|
||||
muted: false,
|
||||
volume: 50,
|
||||
muted: false,
|
||||
volume: 50
|
||||
})
|
||||
|
||||
function toggleStatus (type: string) {
|
||||
function toggleStatus(type: string) {
|
||||
audioProps[type] = !audioProps[type]
|
||||
if (type === 'paused' && audioRef.value) {
|
||||
if (audioProps[type]) {
|
||||
|
|
@ -64,7 +85,7 @@ function toggleStatus (type: string) {
|
|||
}
|
||||
|
||||
// 更新播放位置
|
||||
function audioTimeUpdate (args) {
|
||||
function audioTimeUpdate(args) {
|
||||
audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss')
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -6,26 +6,26 @@
|
|||
<el-tab-pane v-loading="loading" label="我的创作" name="mine">
|
||||
<el-row v-if="mySongList.length" :gutter="12">
|
||||
<el-col v-for="song in mySongList" :key="song.id" :span="24">
|
||||
<songCard :songInfo="song" @play="setCurrentSong(song)"/>
|
||||
<songCard :songInfo="song" @play="setCurrentSong(song)" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-empty v-else description="暂无音乐"/>
|
||||
<el-empty v-else description="暂无音乐" />
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 试听广场 -->
|
||||
<el-tab-pane v-loading="loading" label="试听广场" name="square">
|
||||
<el-row v-if="squareSongList.length" v-loading="loading" :gutter="12">
|
||||
<el-col v-for="song in squareSongList" :key="song.id" :span="24">
|
||||
<songCard :songInfo="song" @play="setCurrentSong(song)"/>
|
||||
<songCard :songInfo="song" @play="setCurrentSong(song)" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-empty v-else description="暂无音乐"/>
|
||||
<el-empty v-else description="暂无音乐" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!-- songInfo -->
|
||||
<songInfo class="flex-none"/>
|
||||
<songInfo class="flex-none" />
|
||||
</div>
|
||||
<audioBar class="flex-none"/>
|
||||
<audioBar class="flex-none" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -36,7 +36,6 @@ import audioBar from './audioBar/index.vue'
|
|||
|
||||
defineOptions({ name: 'Index' })
|
||||
|
||||
|
||||
const currentType = ref('mine')
|
||||
// loading 状态
|
||||
const loading = ref(false)
|
||||
|
|
@ -52,9 +51,9 @@ provide('currentSong', currentSong)
|
|||
*@Description: 调接口生成音乐列表
|
||||
*@MethodAuthor: xiaohong
|
||||
*@Date: 2024-06-27 17:06:44
|
||||
*/
|
||||
function generateMusic (formData: Recordable) {
|
||||
console.log(formData);
|
||||
*/
|
||||
function generateMusic(formData: Recordable) {
|
||||
console.log(formData)
|
||||
loading.value = true
|
||||
setTimeout(() => {
|
||||
mySongList.value = Array.from({ length: 20 }, (_, index) => {
|
||||
|
|
@ -63,7 +62,8 @@ function generateMusic (formData: Recordable) {
|
|||
audioUrl: '',
|
||||
videoUrl: '',
|
||||
title: '我走后' + index,
|
||||
imageUrl: 'https://www.carsmp3.com/data/attachment/forum/201909/19/091020q5kgre20fidreqyt.jpg',
|
||||
imageUrl:
|
||||
'https://www.carsmp3.com/data/attachment/forum/201909/19/091020q5kgre20fidreqyt.jpg',
|
||||
desc: 'Metal, symphony, film soundtrack, grand, majesticMetal, dtrack, grand, majestic',
|
||||
date: '2024年04月30日 14:02:57',
|
||||
lyric: `<div class="_words_17xen_66"><div>大江东去,浪淘尽,千古风流人物。
|
||||
|
|
@ -85,8 +85,8 @@ function generateMusic (formData: Recordable) {
|
|||
*@Description: 设置当前播放的音乐
|
||||
*@MethodAuthor: xiaohong
|
||||
*@Date: 2024-07-19 11:22:33
|
||||
*/
|
||||
function setCurrentSong (music: Recordable) {
|
||||
*/
|
||||
function setCurrentSong(music: Recordable) {
|
||||
currentSong.value = music
|
||||
}
|
||||
|
||||
|
|
@ -95,11 +95,11 @@ defineExpose({
|
|||
})
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-tabs__content {
|
||||
padding: 0 7px;
|
||||
overflow: auto;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
<template>
|
||||
<div class="flex bg-[var(--el-bg-color-overlay)] p-12px mb-12px rounded-1">
|
||||
<div class="relative" @click="playSong">
|
||||
<el-image :src="songInfo.imageUrl" class="flex-none w-80px"/>
|
||||
<div class="bg-black bg-op-40 absolute top-0 left-0 w-full h-full flex items-center justify-center cursor-pointer">
|
||||
<Icon :icon="currentSong.id === songInfo.id ? 'solar:pause-circle-bold':'mdi:arrow-right-drop-circle'" :size="30" />
|
||||
<el-image :src="songInfo.imageUrl" class="flex-none w-80px" />
|
||||
<div
|
||||
class="bg-black bg-op-40 absolute top-0 left-0 w-full h-full flex items-center justify-center cursor-pointer"
|
||||
>
|
||||
<Icon
|
||||
:icon="
|
||||
currentSong.id === songInfo.id
|
||||
? 'solar:pause-circle-bold'
|
||||
: 'mdi:arrow-right-drop-circle'
|
||||
"
|
||||
:size="30"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-8px">
|
||||
|
|
@ -16,7 +25,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
defineOptions({ name: 'Index' })
|
||||
|
||||
defineProps({
|
||||
|
|
@ -30,7 +38,7 @@ const emits = defineEmits(['play'])
|
|||
|
||||
const currentSong = inject('currentSong', {})
|
||||
|
||||
function playSong () {
|
||||
function playSong() {
|
||||
emits('play')
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<ContentWrap class="w-300px mb-[0!important] line-height-24px">
|
||||
<el-image :src="currentSong.imageUrl"/>
|
||||
<el-image :src="currentSong.imageUrl" />
|
||||
<div class="">{{ currentSong.title }}</div>
|
||||
<div class="text-[var(--el-text-color-secondary)] text-12px line-clamp-1">
|
||||
{{ currentSong.desc }}
|
||||
|
|
@ -14,9 +14,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
defineOptions({ name: 'Index' })
|
||||
|
||||
const currentSong = inject('currentSong', {})
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<template>
|
||||
<div>
|
||||
<Title title="音乐/歌词说明" desc="描述您想要的音乐风格和主题,使用流派和氛围而不是特定的艺术家和歌曲">
|
||||
<Title
|
||||
title="音乐/歌词说明"
|
||||
desc="描述您想要的音乐风格和主题,使用流派和氛围而不是特定的艺术家和歌曲"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.desc"
|
||||
:autosize="{ minRows: 6, maxRows: 6}"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
resize="none"
|
||||
type="textarea"
|
||||
maxlength="1200"
|
||||
|
|
@ -14,20 +17,23 @@
|
|||
|
||||
<Title title="纯音乐" desc="创建一首没有歌词的歌曲">
|
||||
<template #extra>
|
||||
<el-switch v-model="formData.pure" size="small"/>
|
||||
<el-switch v-model="formData.pure" size="small" />
|
||||
</template>
|
||||
</Title>
|
||||
|
||||
<Title title="版本" desc="描述您想要的音乐风格和主题,使用流派和氛围而不是特定的艺术家和歌曲">
|
||||
<el-select v-model="formData.version" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in [{
|
||||
value: '3',
|
||||
label: 'V3'
|
||||
}, {
|
||||
value: '2',
|
||||
label: 'V2'
|
||||
}]"
|
||||
v-for="item in [
|
||||
{
|
||||
value: '3',
|
||||
label: 'V3'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'V2'
|
||||
}
|
||||
]"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
|
|
@ -51,5 +57,4 @@ const formData = reactive({
|
|||
defineExpose({
|
||||
formData
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Title title="歌词" desc="自己编写歌词或使用Ai生成歌词,两节/8行效果最佳">
|
||||
<el-input
|
||||
v-model="formData.lyric"
|
||||
:autosize="{ minRows: 6, maxRows: 6}"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
resize="none"
|
||||
type="textarea"
|
||||
maxlength="1200"
|
||||
|
|
@ -14,23 +14,28 @@
|
|||
|
||||
<Title title="音乐风格">
|
||||
<el-space class="flex-wrap">
|
||||
<el-tag v-for="tag in tags" :key="tag" round class="mb-8px">{{tag}}</el-tag>
|
||||
<el-tag v-for="tag in tags" :key="tag" round class="mb-8px">{{ tag }}</el-tag>
|
||||
</el-space>
|
||||
|
||||
<el-button
|
||||
:type="showCustom ? 'primary': 'default'"
|
||||
round
|
||||
size="small"
|
||||
:type="showCustom ? 'primary' : 'default'"
|
||||
round
|
||||
size="small"
|
||||
class="mb-6px"
|
||||
@click="showCustom = !showCustom"
|
||||
>自定义风格
|
||||
>
|
||||
自定义风格
|
||||
</el-button>
|
||||
</Title>
|
||||
|
||||
<Title v-show="showCustom" desc="描述您想要的音乐风格,Suno无法识别艺术家的名字,但可以理解流派和氛围" class="-mt-12px">
|
||||
<Title
|
||||
v-show="showCustom"
|
||||
desc="描述您想要的音乐风格,Suno无法识别艺术家的名字,但可以理解流派和氛围"
|
||||
class="-mt-12px"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.style"
|
||||
:autosize="{ minRows: 4, maxRows: 4}"
|
||||
:autosize="{ minRows: 4, maxRows: 4 }"
|
||||
resize="none"
|
||||
type="textarea"
|
||||
maxlength="256"
|
||||
|
|
@ -40,19 +45,22 @@
|
|||
</Title>
|
||||
|
||||
<Title title="音乐/歌曲名称">
|
||||
<el-input v-model="formData.name" placeholder="请输入音乐/歌曲名称"/>
|
||||
<el-input v-model="formData.name" placeholder="请输入音乐/歌曲名称" />
|
||||
</Title>
|
||||
|
||||
<Title title="版本">
|
||||
<el-select v-model="formData.version" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in [{
|
||||
value: '3',
|
||||
label: 'V3'
|
||||
}, {
|
||||
value: '2',
|
||||
label: 'V2'
|
||||
}]"
|
||||
v-for="item in [
|
||||
{
|
||||
value: '3',
|
||||
label: 'V3'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'V2'
|
||||
}
|
||||
]"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div class="mb-12px">
|
||||
<div class="flex text-[var(--el-text-color-primary)] justify-between items-center">
|
||||
<span>{{title}}</span>
|
||||
<span>{{ title }}</span>
|
||||
<slot name="extra"></slot>
|
||||
</div>
|
||||
<div class="text-[var(--el-text-color-secondary)] text-12px my-8px">
|
||||
{{desc}}
|
||||
{{ desc }}
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@
|
|||
<div v-else-if="error">
|
||||
<el-text type="danger">{{ error }}</el-text>
|
||||
</div>
|
||||
<pre v-else-if="testResult" class="result-content"
|
||||
>{{ JSON.stringify(testResult, null, 2) }}
|
||||
<pre v-else-if="testResult" class="result-content">
|
||||
{{ JSON.stringify(testResult, null, 2) }}
|
||||
</pre>
|
||||
<div v-else> <el-text type="info">点击运行查看结果</el-text> </div>
|
||||
</div>
|
||||
|
|
@ -237,14 +237,14 @@ defineExpose({
|
|||
|
||||
<style lang="css" scoped>
|
||||
.result-content {
|
||||
background: white;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
max-height: 300px;
|
||||
padding: 12px;
|
||||
overflow: auto;
|
||||
font-family: Monaco, Consolas, monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -110,11 +110,12 @@ watch(copied, (val) => {
|
|||
flex-direction: column;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
@extend .hide-scroll-bar;
|
||||
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
@extend .hide-scroll-bar;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<script setup lang="ts">
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
tags: { label: string; value: string }[]
|
||||
tags?: { label: string; value: string }[]
|
||||
modelValue: string
|
||||
[k: string]: any
|
||||
}>(),
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@
|
|||
<div class="flex flex-col">
|
||||
<el-radio-group v-model="modelData.titleSetting.enable">
|
||||
<div class="flex flex-col">
|
||||
<el-radio :value="false"
|
||||
>系统默认 <el-text type="info"> 展示流程名称 </el-text></el-radio
|
||||
>
|
||||
<el-radio :value="false">
|
||||
系统默认 <el-text type="info"> 展示流程名称 </el-text>
|
||||
</el-radio>
|
||||
<el-radio :value="true">
|
||||
自定义标题
|
||||
<el-text>
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ onMounted(() => {
|
|||
<style>
|
||||
#mention-modal {
|
||||
position: absolute;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
padding: 5px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#mention-modal input {
|
||||
|
|
@ -98,10 +98,10 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
#mention-modal ul li {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
padding: 3px 0;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mention-modal ul li:hover {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ const view = ref({
|
|||
bpmnXml: ''
|
||||
}) // BPMN 流程图数据
|
||||
|
||||
|
||||
/** 只有 loading 完成时,才去加载流程列表 */
|
||||
watch(
|
||||
() => props.modelView,
|
||||
|
|
@ -42,8 +41,8 @@ watch(
|
|||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box-card {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-bottom: 0;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
|
|
@ -52,9 +51,9 @@ watch(
|
|||
}
|
||||
|
||||
:deep(.process-viewer) {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,16 +95,18 @@
|
|||
</el-table-column>
|
||||
<el-table-column label="字典类型" min-width="12%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.dictType" :value-on-clear="''" clearable filterable placeholder="请选择">
|
||||
<el-select
|
||||
v-model="scope.row.dictType"
|
||||
:value-on-clear="''"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex justify-end">
|
||||
<el-popover
|
||||
class="box-item"
|
||||
content="加载最新字典"
|
||||
placement="top-start"
|
||||
>
|
||||
<el-popover class="box-item" content="加载最新字典" placement="top-start">
|
||||
<template #reference>
|
||||
<el-button :icon="Refresh" size="small" circle @click="getDictOptions" class=""/>
|
||||
<el-button :icon="Refresh" size="small" circle @click="getDictOptions" class="" />
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,44 +3,44 @@
|
|||
<div>
|
||||
<ContentWrap>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item label="产品名称">{{ product.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="ProductKey">{{ product.productKey }}</el-descriptions-item>
|
||||
<el-descriptions-item label="设备类型">
|
||||
<dict-tag :type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE" :value="product.deviceType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="DeviceName">{{ device.deviceName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注名称">{{ device.nickname }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当前状态">
|
||||
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="device.state" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">
|
||||
{{ formatDate(device.createTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="激活时间">
|
||||
{{ formatDate(device.activeTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最后上线时间">
|
||||
{{ formatDate(device.onlineTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最后离线时间">
|
||||
{{ formatDate(device.offlineTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备位置">
|
||||
<template v-if="hasLocation">
|
||||
<span class="mr-2">{{ device.longitude }}, {{ device.latitude }}</span>
|
||||
<el-button type="primary" link @click="openMapDialog">
|
||||
<Icon icon="ep:location" class="mr-1" />
|
||||
查看地图
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-else class="text-[var(--el-text-color-secondary)]">暂无位置信息</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="认证信息">
|
||||
<el-button type="primary" @click="handleAuthInfoDialogOpen" plain size="small">
|
||||
查看
|
||||
<el-descriptions-item label="产品名称">{{ product.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="ProductKey">{{ product.productKey }}</el-descriptions-item>
|
||||
<el-descriptions-item label="设备类型">
|
||||
<dict-tag :type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE" :value="product.deviceType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="DeviceName">{{ device.deviceName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注名称">{{ device.nickname }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当前状态">
|
||||
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="device.state" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">
|
||||
{{ formatDate(device.createTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="激活时间">
|
||||
{{ formatDate(device.activeTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最后上线时间">
|
||||
{{ formatDate(device.onlineTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最后离线时间">
|
||||
{{ formatDate(device.offlineTime) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备位置">
|
||||
<template v-if="hasLocation">
|
||||
<span class="mr-2">{{ device.longitude }}, {{ device.latitude }}</span>
|
||||
<el-button type="primary" link @click="openMapDialog">
|
||||
<Icon icon="ep:location" class="mr-1" />
|
||||
查看地图
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
<span v-else class="text-[var(--el-text-color-secondary)]">暂无位置信息</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="认证信息">
|
||||
<el-button type="primary" @click="handleAuthInfoDialogOpen" plain size="small">
|
||||
查看
|
||||
</el-button>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</ContentWrap>
|
||||
|
||||
<!-- 认证信息弹框 -->
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
inline-prompt
|
||||
active-text="定时刷新"
|
||||
inactive-text="定时刷新"
|
||||
style="--el-switch-on-color: #13ce66"
|
||||
:style="{ '--el-switch-on-color': '#13ce66' }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
inline-prompt
|
||||
active-text="定时刷新"
|
||||
inactive-text="定时刷新"
|
||||
style="--el-switch-on-color: #13ce66"
|
||||
:style="{ '--el-switch-on-color': '#13ce66' }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
|
|
|||
|
|
@ -308,9 +308,9 @@
|
|||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设备状态" align="center" prop="status">
|
||||
<el-table-column label="设备状态" align="center" prop="state">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="scope.row.status" />
|
||||
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="scope.row.state" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
|
|
|
|||
|
|
@ -131,22 +131,22 @@ onMounted(() => {
|
|||
.terminal-card {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 12px;
|
||||
background-color: #1a1b26;
|
||||
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.4);
|
||||
border: 1px solid #24283b;
|
||||
overflow: hidden;
|
||||
font-family: 'Fira Code', 'JetBrains Mono', Consolas, Monaco, monospace;
|
||||
background-color: #1a1b26;
|
||||
border: 1px solid #24283b;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px -10px rgb(0 0 0 / 40%);
|
||||
}
|
||||
|
||||
.terminal-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background-color: #24283b;
|
||||
border-bottom: 1px solid #16161e;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.terminal-dots {
|
||||
|
|
@ -160,53 +160,59 @@ onMounted(() => {
|
|||
border-radius: 50%;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.dot:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.dot.red {
|
||||
background-color: #f7768e;
|
||||
box-shadow: 0 0 5px rgba(247, 118, 142, 0.4);
|
||||
box-shadow: 0 0 5px rgb(247 118 142 / 40%);
|
||||
}
|
||||
|
||||
.dot.yellow {
|
||||
background-color: #e0af68;
|
||||
box-shadow: 0 0 5px rgba(224, 175, 104, 0.4);
|
||||
box-shadow: 0 0 5px rgb(224 175 104 / 40%);
|
||||
}
|
||||
|
||||
.dot.green {
|
||||
background-color: #9ece6a;
|
||||
box-shadow: 0 0 5px rgba(158, 206, 106, 0.4);
|
||||
box-shadow: 0 0 5px rgb(158 206 106 / 40%);
|
||||
}
|
||||
|
||||
.terminal-title {
|
||||
color: #a9b1d6;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.8px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
color: #a9b1d6;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.terminal-copy-btn {
|
||||
display: flex;
|
||||
padding: 6px 12px;
|
||||
font-family: inherit;
|
||||
font-size: 12px;
|
||||
color: #a9b1d6;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 1px solid #414868;
|
||||
color: #a9b1d6;
|
||||
border-radius: 6px;
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.terminal-copy-btn:hover {
|
||||
color: #1a1b26;
|
||||
background: #bb9af7;
|
||||
border-color: #bb9af7;
|
||||
color: #1a1b26;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(187, 154, 247, 0.3);
|
||||
box-shadow: 0 4px 12px rgb(187 154 247 / 30%);
|
||||
}
|
||||
|
||||
.terminal-copy-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
|
@ -217,17 +223,17 @@ onMounted(() => {
|
|||
|
||||
.terminal-body {
|
||||
padding: 20px;
|
||||
color: #c0caf5;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: #c0caf5;
|
||||
}
|
||||
|
||||
.terminal-desc {
|
||||
color: #7dcfff;
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 16px;
|
||||
font-family: var(--el-font-family);
|
||||
font-size: 13px;
|
||||
padding-bottom: 16px;
|
||||
color: #7dcfff;
|
||||
border-bottom: 1px dashed #292e42;
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +243,9 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.terminal-code {
|
||||
min-width: max-content;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
min-width: max-content;
|
||||
}
|
||||
|
||||
.terminal-code code {
|
||||
|
|
@ -267,13 +273,16 @@ onMounted(() => {
|
|||
.terminal-code-wrapper::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.terminal-code-wrapper::-webkit-scrollbar-thumb {
|
||||
background: #414868;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.terminal-code-wrapper::-webkit-scrollbar-thumb:hover {
|
||||
background: #565f89;
|
||||
}
|
||||
|
||||
.terminal-code-wrapper::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,21 +56,28 @@ watch([urlPrefix, urlPath], () => {
|
|||
config.value.url = fullUrl.value
|
||||
})
|
||||
|
||||
const syncUrlFields = (url?: string) => {
|
||||
if (url?.startsWith('https://')) {
|
||||
urlPrefix.value = 'https://'
|
||||
urlPath.value = url.substring(8)
|
||||
} else if (url?.startsWith('http://')) {
|
||||
urlPrefix.value = 'http://'
|
||||
urlPath.value = url.substring(7)
|
||||
} else {
|
||||
urlPath.value = url ?? ''
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => config.value?.url,
|
||||
(url) => syncUrlFields(url),
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
/** 组件初始化 */
|
||||
onMounted(() => {
|
||||
if (!isEmpty(config.value)) {
|
||||
// 初始化 URL
|
||||
if (config.value.url) {
|
||||
if (config.value.url.startsWith('https://')) {
|
||||
urlPrefix.value = 'https://'
|
||||
urlPath.value = config.value.url.substring(8)
|
||||
} else if (config.value.url.startsWith('http://')) {
|
||||
urlPrefix.value = 'http://'
|
||||
urlPath.value = config.value.url.substring(7)
|
||||
} else {
|
||||
urlPath.value = config.value.url
|
||||
}
|
||||
}
|
||||
syncUrlFields(config.value.url)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@
|
|||
>
|
||||
{{ conditionIndex + 1 }}
|
||||
</div>
|
||||
<span class="text-12px font-500 text-[var(--el-text-color-primary)]"
|
||||
>条件 {{ conditionIndex + 1 }}</span
|
||||
>
|
||||
<span class="text-12px font-500 text-[var(--el-text-color-primary)]">
|
||||
条件 {{ conditionIndex + 1 }}
|
||||
</span>
|
||||
</div>
|
||||
<el-button
|
||||
type="danger"
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@
|
|||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core'
|
||||
import { InfoFilled } from '@element-plus/icons-vue'
|
||||
import { isEmptyVal } from '@/utils/is'
|
||||
import {
|
||||
IoTDataSpecsDataTypeEnum,
|
||||
JSON_PARAMS_INPUT_CONSTANTS,
|
||||
|
|
@ -329,7 +330,8 @@ const handleParamsChange = () => {
|
|||
|
||||
// 验证必填参数
|
||||
for (const param of paramsList.value) {
|
||||
if (param.required && (!parsed[param.identifier] || parsed[param.identifier] === '')) {
|
||||
const value = parsed[param.identifier]
|
||||
if (param.required && isEmptyVal(value)) {
|
||||
jsonError.value = JSON_PARAMS_INPUT_CONSTANTS.PARAM_REQUIRED_ERROR(param.name)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ const onActionTypeChange = (action: Action, type: number, index: number) => {
|
|||
action.params = ''
|
||||
}
|
||||
// 如果从其他类型切换到设备控制类型,清空identifier(让用户重新选择)
|
||||
if (action.identifier && type !== action.type) {
|
||||
if (action.identifier) {
|
||||
action.identifier = undefined
|
||||
}
|
||||
} else if (isAlertAction(type)) {
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@
|
|||
class="flex items-center gap-8px p-12px px-16px bg-[var(--el-fill-color-light)] rounded-6px border border-[var(--el-border-color-lighter)]"
|
||||
>
|
||||
<Icon icon="ep:timer" class="text-[var(--el-color-danger)] text-18px" />
|
||||
<span class="text-14px font-500 text-[var(--el-text-color-primary)]"
|
||||
>定时触发配置</span
|
||||
>
|
||||
<span class="text-14px font-500 text-[var(--el-text-color-primary)]">
|
||||
定时触发配置
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- CRON 表达式配置 -->
|
||||
|
|
|
|||
|
|
@ -438,12 +438,12 @@ export const IoTDeviceStatusEnum = {
|
|||
// 在线状态
|
||||
ONLINE: {
|
||||
label: '在线',
|
||||
value: 'online',
|
||||
value: '1',
|
||||
tagType: 'success'
|
||||
},
|
||||
OFFLINE: {
|
||||
label: '离线',
|
||||
value: 'offline',
|
||||
value: '2',
|
||||
tagType: 'danger'
|
||||
},
|
||||
// 启用状态
|
||||
|
|
|
|||
|
|
@ -578,8 +578,10 @@ const getSkuTableRef = () => {
|
|||
defineExpose({ generateTableData, validateSku, getSkuTableRef })
|
||||
</script>
|
||||
<style>
|
||||
// 避免滚动条遮挡最后一行数据
|
||||
/*noinspection CssUnusedSymbol*/
|
||||
/*
|
||||
* 避免滚动条遮挡最后一行数据
|
||||
* noinspection CssUnusedSymbol
|
||||
*/
|
||||
.el-table.tabNumWidth .el-scrollbar {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
<el-table v-loading="loading" :data="list" show-overflow-tooltip>
|
||||
<el-table-column label="#" width="55">
|
||||
<template #default="{ row }">
|
||||
<el-radio :value="row.id" v-model="selectedSkuId" @change="handleSelected(row)"
|
||||
>
|
||||
<el-radio :value="row.id" v-model="selectedSkuId" @change="handleSelected(row)">
|
||||
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
|
|||
|
|
@ -136,11 +136,11 @@ const emitActivityChange = () => {
|
|||
display: flex;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
border: 1px dashed var(--el-border-color-darker);
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.spu-pic {
|
||||
|
|
|
|||
|
|
@ -70,17 +70,17 @@
|
|||
~ {{ formatDate(scope.row.endTime, 'YYYY-MM-DD') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="商品图片" prop="spuName" min-width="80">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <el-image-->
|
||||
<!-- :src="scope.row.picUrl"-->
|
||||
<!-- class="h-40px w-40px"-->
|
||||
<!-- :preview-src-list="[scope.row.picUrl]"-->
|
||||
<!-- preview-teleported-->
|
||||
<!-- />-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column label="商品标题" prop="spuName" min-width="300" />-->
|
||||
<!-- <el-table-column label="商品图片" prop="spuName" min-width="80">-->
|
||||
<!-- <template #default="scope">-->
|
||||
<!-- <el-image-->
|
||||
<!-- :src="scope.row.picUrl"-->
|
||||
<!-- class="h-40px w-40px"-->
|
||||
<!-- :preview-src-list="[scope.row.picUrl]"-->
|
||||
<!-- preview-teleported-->
|
||||
<!-- />-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column label="商品标题" prop="spuName" min-width="300" />-->
|
||||
<el-table-column label="活动状态" align="center" prop="status" min-width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||
|
|
|
|||
|
|
@ -208,8 +208,8 @@ onBeforeUnmount(() => {
|
|||
//transition: border-left 0.05s ease-in-out; /* 设置过渡效果 */
|
||||
|
||||
.username {
|
||||
min-width: 0;
|
||||
max-width: 60%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.last-message {
|
||||
|
|
@ -218,27 +218,27 @@ onBeforeUnmount(() => {
|
|||
|
||||
.last-message,
|
||||
.username {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: rgba(128, 128, 128, 0.5); // 透明色,暗黑模式下也能体现
|
||||
background-color: rgb(128 128 128 / 50%); // 透明色,暗黑模式下也能体现
|
||||
}
|
||||
|
||||
.right-menu-ul {
|
||||
position: absolute;
|
||||
background-color: var(--app-content-bg-color);
|
||||
width: 130px;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
list-style-type: none; /* 移除默认的项目符号 */
|
||||
background-color: var(--app-content-bg-color);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 阴影效果 */
|
||||
width: 130px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 10%); /* 阴影效果 */
|
||||
|
||||
li {
|
||||
padding: 8px 16px;
|
||||
|
|
|
|||
|
|
@ -373,36 +373,36 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.kefu {
|
||||
background-color: var(--app-content-bg-color);
|
||||
position: relative;
|
||||
width: calc(100% - 300px - 260px);
|
||||
background-color: var(--app-content-bg-color);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1px; /* 实际宽度 */
|
||||
height: 100%;
|
||||
background-color: var(--el-border-color);
|
||||
content: '';
|
||||
transform: scaleX(0.3); /* 缩小宽度 */
|
||||
}
|
||||
|
||||
.kefu-header {
|
||||
background-color: var(--app-content-bg-color);
|
||||
position: relative;
|
||||
display: flex;
|
||||
background-color: var(--app-content-bg-color);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px; /* 初始宽度 */
|
||||
background-color: var(--el-border-color);
|
||||
content: '';
|
||||
transform: scaleY(0.3); /* 缩小视觉高度 */
|
||||
}
|
||||
|
||||
|
|
@ -413,30 +413,30 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
|||
}
|
||||
|
||||
&-content {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
|
||||
.newMessageTip {
|
||||
position: absolute;
|
||||
bottom: 35px;
|
||||
right: 35px;
|
||||
background-color: var(--app-content-bg-color);
|
||||
bottom: 35px;
|
||||
padding: 10px;
|
||||
border-radius: 30px;
|
||||
font-size: 12px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 阴影效果 */
|
||||
background-color: var(--app-content-bg-color);
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 10%); /* 阴影效果 */
|
||||
}
|
||||
|
||||
.ss-row-left {
|
||||
justify-content: flex-start;
|
||||
|
||||
.kefu-message {
|
||||
background-color: #fff;
|
||||
margin-left: 10px;
|
||||
margin-top: 3px;
|
||||
margin-left: 10px;
|
||||
background-color: #fff;
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
|
|
@ -447,22 +447,22 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
|||
justify-content: flex-end;
|
||||
|
||||
.kefu-message {
|
||||
background-color: rgb(206, 223, 255);
|
||||
margin-right: 10px;
|
||||
margin-top: 3px;
|
||||
border-top-left-radius: 10px;
|
||||
margin-right: 10px;
|
||||
background-color: rgb(206 223 255);
|
||||
border-bottom-right-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// 消息气泡
|
||||
.kefu-message {
|
||||
color: #414141;
|
||||
font-weight: 500;
|
||||
padding: 5px 10px;
|
||||
width: auto;
|
||||
max-width: 50%;
|
||||
padding: 5px 10px;
|
||||
font-weight: 500;
|
||||
color: #414141;
|
||||
//text-align: left;
|
||||
//display: inline-block !important;
|
||||
//word-break: break-all;
|
||||
|
|
@ -476,30 +476,30 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
|||
.date-message,
|
||||
.system-message {
|
||||
width: fit-content;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 0 5px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
color: #fff;
|
||||
background-color: rgb(0 0 0 / 10%);
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.kefu-footer {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
flex-direction: column;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px; /* 初始宽度 */
|
||||
background-color: var(--el-border-color);
|
||||
content: '';
|
||||
transform: scaleY(0.3); /* 缩小视觉高度 */
|
||||
}
|
||||
|
||||
|
|
@ -510,13 +510,13 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
|||
}
|
||||
|
||||
::v-deep(textarea) {
|
||||
resize: none;
|
||||
background-color: var(--app-content-bg-color);
|
||||
resize: none;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
box-shadow: none !important;
|
||||
border-radius: 0;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
::v-deep(.el-textarea__inner) {
|
||||
|
|
|
|||
|
|
@ -173,31 +173,31 @@ const getUserData = async () => {
|
|||
background-color: var(--app-content-bg-color);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1px; /* 实际宽度 */
|
||||
height: 100%;
|
||||
background-color: var(--el-border-color);
|
||||
content: '';
|
||||
transform: scaleX(0.3); /* 缩小宽度 */
|
||||
}
|
||||
|
||||
&-header {
|
||||
background-color: var(--app-content-bg-color);
|
||||
position: relative;
|
||||
display: flex;
|
||||
background-color: var(--app-content-bg-color);
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px; /* 初始宽度 */
|
||||
background-color: var(--el-border-color);
|
||||
content: '';
|
||||
transform: scaleY(0.3); /* 缩小视觉高度 */
|
||||
}
|
||||
|
||||
|
|
@ -207,45 +207,39 @@ const getUserData = async () => {
|
|||
}
|
||||
|
||||
&-item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&-activation::before {
|
||||
content: '';
|
||||
position: absolute; /* 绝对定位 */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0; /* 覆盖整个元素 */
|
||||
border-bottom: 2px solid rgba(128, 128, 128, 0.5); /* 边框样式 */
|
||||
inset: 0; /* 覆盖整个元素 */
|
||||
pointer-events: none; /* 确保点击事件不会被伪元素拦截 */
|
||||
border-bottom: 2px solid rgb(128 128 128 / 50%); /* 边框样式 */
|
||||
content: '';
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
content: '';
|
||||
position: absolute; /* 绝对定位 */
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0; /* 覆盖整个元素 */
|
||||
border-bottom: 2px solid rgba(128, 128, 128, 0.5); /* 边框样式 */
|
||||
inset: 0; /* 覆盖整个元素 */
|
||||
pointer-events: none; /* 确保点击事件不会被伪元素拦截 */
|
||||
border-bottom: 2px solid rgb(128 128 128 / 50%); /* 边框样式 */
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-tabs {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
</div>
|
||||
<div class="pay-box flex justify-end pr-5px">
|
||||
<div class="flex items-center">
|
||||
<div class="discounts-title pay-color"
|
||||
>共 {{ getMessageContent?.productCount }} 件商品,总金额:
|
||||
<div class="discounts-title pay-color">
|
||||
共 {{ getMessageContent?.productCount }} 件商品,总金额:
|
||||
</div>
|
||||
<div class="discounts-money pay-color">
|
||||
¥{{ fenToYuan(getMessageContent?.payPrice) }}
|
||||
|
|
@ -109,10 +109,10 @@ function formatOrderStatus(order: any) {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.order-list-card-box {
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
background-color: rgb(128 128 128 / 30%); // 透明色,暗黑模式下也能体现
|
||||
border: 1px var(--el-border-color) solid;
|
||||
background-color: rgba(128, 128, 128, 0.3); // 透明色,暗黑模式下也能体现
|
||||
border-radius: 10px;
|
||||
|
||||
.order-card-header {
|
||||
height: 28px;
|
||||
|
|
@ -123,8 +123,8 @@ function formatOrderStatus(order: any) {
|
|||
|
||||
span {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--left-menu-bg-active-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -144,9 +144,9 @@ function formatOrderStatus(order: any) {
|
|||
}
|
||||
|
||||
.discounts-money {
|
||||
font-family: OPPOSANS;
|
||||
font-size: 16px;
|
||||
line-height: normal;
|
||||
font-family: OPPOSANS;
|
||||
}
|
||||
|
||||
.pay-color {
|
||||
|
|
@ -156,26 +156,26 @@ function formatOrderStatus(order: any) {
|
|||
}
|
||||
|
||||
.warning-color {
|
||||
color: #faad14;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.danger-color {
|
||||
color: #ff3000;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #ff3000;
|
||||
}
|
||||
|
||||
.success-color {
|
||||
color: #52c41a;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.info-color {
|
||||
color: #999999;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -68,21 +68,21 @@ const openDetail = (spuId: number) => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
background-color: #007bff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.product-warp {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
background-color: rgba(128, 128, 128, 0.3);
|
||||
padding: 10px;
|
||||
background-color: rgb(128 128 128 / 30%);
|
||||
border: 1px solid var(--el-border-color);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
|
||||
&-left {
|
||||
width: 70px;
|
||||
|
|
@ -98,14 +98,14 @@ const openDetail = (spuId: number) => {
|
|||
flex: 1;
|
||||
|
||||
.description {
|
||||
display: -webkit-box;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1; /* 显示一行 */
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1; /* 显示一行 */
|
||||
}
|
||||
|
||||
.price {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue