From e32d17213665f032280db2f5fe85f3812670ec2d Mon Sep 17 00:00:00 2001
From: ai-coding <ai-coding@devgenie.local>
Date: 星期三, 29 七月 2026 14:50:07 +0800
Subject: [PATCH] Merge origin/feat/730-xywang into feat/deploy-uat
---
src/views/userContent/contentCenter/components/AgreementVersionModal.vue | 174 +++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 131 insertions(+), 43 deletions(-)
diff --git a/src/views/userContent/contentCenter/components/AgreementVersionModal.vue b/src/views/userContent/contentCenter/components/AgreementVersionModal.vue
index 4aba588..33d2b6d 100644
--- a/src/views/userContent/contentCenter/components/AgreementVersionModal.vue
+++ b/src/views/userContent/contentCenter/components/AgreementVersionModal.vue
@@ -1,13 +1,15 @@
<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import type { FormInst, FormRules } from 'naive-ui'
-import { NButton, NForm, NFormItem, NInput, NModal, NSpace } from 'naive-ui'
+import { NButton, NForm, NFormItem, NInput, NModal, NSelect, NSpace } from 'naive-ui'
import AiRichTextEditor from '@/components/custom/Editor/AiRichTextEditor/index.vue'
+import { AGREEMENT_CATEGORY_OPTIONS } from '../constants/agreementCategory'
export interface AgreementVersionFormValue {
id?: number
version: string
content: string
+ agreementCategory?: number | null
}
const props = withDefaults(defineProps<{
@@ -32,7 +34,9 @@
const formModel = reactive<AgreementVersionFormValue>({
version: '',
content: '',
+ agreementCategory: null,
})
+const contentErrorMessage = ref('')
const plainTextLength = computed(() => {
return formModel.content
@@ -43,17 +47,12 @@
})
const rules: FormRules = {
- content: [
+ agreementCategory: [
{
required: true,
- validator: () => {
- if (!plainTextLength.value)
- return new Error('请输入协议内容')
- // if (plainTextLength.value > 20000)
- // return new Error('协议内容最多输入20000个字符')
- return true
- },
- trigger: ['blur', 'change', 'input'],
+ type: 'number',
+ message: '请选择协议类型',
+ trigger: ['blur', 'change'],
},
],
}
@@ -62,6 +61,8 @@
formModel.id = props.rowData?.id
formModel.version = props.rowData?.version || ''
formModel.content = props.rowData?.content || ''
+ formModel.agreementCategory = props.rowData?.agreementCategory ?? null
+ contentErrorMessage.value = ''
formRef.value?.restoreValidation()
}
@@ -72,7 +73,9 @@
async function handleSave() {
if (props.readonly)
return
-
+
+ contentErrorMessage.value = plainTextLength.value ? '' : '请输入协议内容'
+
try {
await formRef.value?.validate()
} catch (errors) {
@@ -80,12 +83,21 @@
return
}
+ if (contentErrorMessage.value)
+ return
+
emit('save', {
id: formModel.id,
version: formModel.version,
content: formModel.content,
+ agreementCategory: formModel.agreementCategory,
})
}
+
+watch(() => formModel.content, () => {
+ if (contentErrorMessage.value && plainTextLength.value)
+ contentErrorMessage.value = ''
+})
watch(() => props.visible, (visible) => {
if (visible)
@@ -100,30 +112,52 @@
preset="card"
:title="title"
class="agreement-version-modal"
- :style="{ width: '1000px' }"
+ :style="{ width: '1000px', height: '90vh', maxHeight: '90vh', display: 'flex', flexDirection: 'column' }"
+ :header-style="{ flexShrink: '0' }"
:segmented="{ content: true, action: true }"
- :content-style="{ padding: '24px 24px 0 24px' }"
+ :content-style="{ padding: '24px 24px 0 24px', display: 'flex', flexDirection: 'column', flex: '1', minHeight: '0', overflow: 'hidden' }"
@close="handleClose"
>
- <NForm
- ref="formRef"
- :model="formModel"
- :rules="rules"
- label-placement="top"
- require-mark-placement="left"
- >
- <NFormItem label="版本号" required>
- <NInput v-model:value="formModel.version" disabled placeholder="系统自动生成" />
- </NFormItem>
- <NFormItem label="协议内容" path="content" required>
+ <div class="agreement-version-body">
+ <NForm
+ ref="formRef"
+ :model="formModel"
+ :rules="rules"
+ label-placement="top"
+ require-mark-placement="left"
+ class="agreement-fixed-form"
+ >
+ <div class="form-row">
+ <NFormItem label="版本号" required class="form-row-item">
+ <NInput v-model:value="formModel.version" disabled placeholder="系统自动生成" />
+ </NFormItem>
+ <NFormItem label="协议类型" path="agreementCategory" required class="form-row-item">
+ <NSelect
+ v-model:value="formModel.agreementCategory"
+ :options="AGREEMENT_CATEGORY_OPTIONS"
+ :disabled="readonly"
+ placeholder="请选择协议类型"
+ />
+ </NFormItem>
+ </div>
+ </NForm>
+
+ <div class="agreement-content-label">
+ 协议内容
+ <span v-if="!readonly" class="agreement-content-required">*</span>
+ </div>
+ <div class="agreement-content-area">
<div class="rich-text-wrapper">
<div class="editor-font-tip">
推荐字号:大标题(21)小标题(15)正文(14)
</div>
- <AiRichTextEditor v-model="formModel.content" :read-only="readonly" height="360px" />
+ <AiRichTextEditor v-model="formModel.content" :read-only="readonly" height="100%" />
</div>
- </NFormItem>
- </NForm>
+ <div v-if="contentErrorMessage" class="agreement-content-error">
+ {{ contentErrorMessage }}
+ </div>
+ </div>
+ </div>
<template #action>
<NSpace justify="end" :size="8">
@@ -139,9 +173,67 @@
</template>
<style scoped lang="scss">
+.agreement-version-body {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+ overflow: hidden;
+}
+
+.agreement-fixed-form {
+ flex-shrink: 0;
+}
+
+.form-row {
+ display: flex;
+ gap: 24px;
+}
+
+.form-row-item {
+ flex: 1;
+ min-width: 0;
+}
+
+.agreement-content-label {
+ flex-shrink: 0;
+ margin-bottom: 8px;
+ font-size: 14px;
+ color: #171f26;
+}
+
+.agreement-content-required {
+ margin-left: 4px;
+ color: #d03050;
+}
+
+.agreement-content-area {
+ flex: 1;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ padding-bottom: 24px;
+}
+
+.agreement-content-error {
+ flex-shrink: 0;
+ padding-top: 6px;
+ font-size: 12px;
+ color: #d03050;
+}
+
.rich-text-wrapper {
position: relative;
width: 100%;
+ flex: 1;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.rich-text-wrapper :deep(.ai-editor-container) {
+ flex: 1;
+ min-height: 0;
}
.editor-font-tip {
@@ -159,34 +251,30 @@
}
.rich-text-wrapper :deep(.aie-container) {
- min-height: 360px;
font-size: 14px;
}
+</style>
-.rich-text-wrapper :deep(.aie-main) {
- min-height: 360px;
-}
-
-.content-count {
- width: 100%;
- margin-top: 8px;
- text-align: right;
- font-size: 12px;
- color: rgba(23, 31, 38, 0.45);
-}
-
-:deep(.agreement-version-modal .n-card-header) {
+<style lang="scss">
+/*
+ * 以下规则不能加 scoped:preset="card" 的 NModal 实际渲染的 NCard/NCard 内部结构
+ * 是由 naive-ui 在组件外部独立创建的 DOM 节点,不带当前组件的 data-v-xxx 属性,
+ * scoped 下的 :deep() 选择器无法命中,必须用全局样式规则。
+ */
+.agreement-version-modal .n-card-header {
padding: 20px 24px;
+ flex-shrink: 0;
}
-:deep(.agreement-version-modal .n-card-header__main) {
+.agreement-version-modal .n-card-header__main {
font-size: 16px;
font-weight: 600;
color: #171f26;
}
-:deep(.agreement-version-modal .n-card__action) {
+.agreement-version-modal .n-card__action {
background-color: transparent !important;
padding: 16px 24px;
+ flex-shrink: 0;
}
</style>
--
Gitblit v1.7.1