Bladeren bron

添加参数配置静态页面和静态弹窗

lm 1 week geleden
bovenliggende
commit
e990230e93

+ 2 - 1
src/baseComponents/Table.vue

@@ -19,7 +19,8 @@
                 <el-table-column 
                   v-if="!item.hidden"
                   :prop="item.name" 
-                  :min-width="item.width" 
+                  :min-width="item.width"
+                  :width="item.minWidth" 
                   :label="item.label" 
                   :fixed="item.fixed ? item.fixed : false" 
                   :align="item.align" >

+ 78 - 0
src/baseComponents/TableRowDragUpDown.vue

@@ -0,0 +1,78 @@
+<template>
+    <img
+        :draggable="true"
+        @dragstart="(e)=>HandleDragStart(e)"
+        @dragend="(e)=>HandleDragEnd(e,tableRow,currentIndex - 1)"
+        :src="moveIcon" alt="">
+</template>   
+
+
+<script setup lang="ts">
+import { ref,watch } from 'vue';
+import moveIcon from '@/assets/icon/move_up_down.png'
+import { number } from 'echarts';
+
+const props = defineProps({
+    defaultTableData:{
+        type:Array,
+        default:()=>[]
+    },
+    tableRow:{
+        type:Object,
+        required:true
+    },
+    currentIndex:{
+        type:Number,
+        required:true
+    },
+    rowHeight:{
+        type:number,
+        default:52
+    }
+})
+
+const emit = defineEmits(['moveChange'])
+
+const tableData = ref([])
+
+const startYPointer = ref(0)
+const HandleDragStart = (e)=>{
+    console.log('开始拖动了',e)
+    startYPointer.value = e.clientY
+}
+
+const HandleDragEnd = (e,row,currentIndex)=>{
+    console.log('结束拖动了',e)
+    let endYPointer = e.clientY
+    let moveNum = 0
+    if(endYPointer > startYPointer.value){
+        // 下移
+        moveNum =   Math.ceil((endYPointer - startYPointer.value) / props.rowHeight)
+        // 替换当前表格的内容
+        let maxLength = tableData.value.length
+        if(moveNum > 0){
+            tableData.value.splice(currentIndex,1)
+            tableData.value.splice(Math.min(currentIndex + moveNum - 1,maxLength),0,row)
+            emit('moveChange',tableData.value)
+        }
+    }else{
+        // 上移
+        moveNum = Math.ceil(( startYPointer.value - endYPointer) / props.rowHeight)
+        // 替换当前表格的内容
+        if(moveNum > 0){
+            tableData.value.splice(currentIndex,1)
+            tableData.value.splice(Math.max(currentIndex - moveNum,0),0,row)
+            emit('moveChange',tableData.value)
+        }
+    }
+}
+
+watch(()=>props.defaultTableData,(newVal)=>{
+    tableData.value = newVal
+},{immediate:true,deep:true})
+</script>
+
+
+<style lang="scss" scoped>
+
+</style>

+ 234 - 0
src/components/settingCard/SettingCard.vue

@@ -0,0 +1,234 @@
+<template>
+    <div class="setting_card" >
+        <div class="card_label">{{cardTitle}}</div>
+        <div class="tag_container">
+            <span class="tag_item" 
+                v-for="(item, index) in cardItems" 
+                :key="'region_' + index"
+            >{{ item?.[middleColumnItm?.name] }}</span>
+        </div>
+        <span class="button_editor" @click="formVisible= true">编辑</span>
+    </div>
+
+    <!-- 参数配置弹窗 -->
+    <FormDialog
+        class="parameter_setting_form_dialog"
+        v-if="formVisible"
+        :defaultFormData="{}" 
+        :visible="formVisible" 
+        :title="cardTitle"
+        :submitLoading="formSubmitLoading"
+        @close="formVisible = false"
+    >
+        <template #form_pre>
+            <div class="dictionary_box">
+                <!-- v-model:tableRef="dictionaryTableDom" -->
+                <Table
+                    :tableColumns="finalTableColumns" 
+                    :tableData="tableData"
+                    :hidePagination="true">
+                    <template #moveable="{row,currentIndex}">
+                        <TableRowDragUpDown :currentIndex="currentIndex" :tableRow="row" :defaultTableData="tableData" @moveChange="HandleRowMove"/>
+                    </template>
+
+                    <template #num="{row,currentIndex}">
+                        {{ currentIndex }}
+                    </template>
+
+                    <template v-slot:[middleColumnItm?.name]="{row}">
+                        {{ row?.[middleColumnItm?.name] }}
+                    </template>
+
+                    
+                    <template #dictName="{row}">
+                        <el-input v-model="row.dictName" v-if="row.tmpId" placeholder="请输入选项内容"></el-input>
+                        <span v-else>{{  row.dictName }}</span>
+                    </template>
+                    
+                    <template #dictType="{row}">
+                        <el-select v-model="row.dictType" v-if="row.tmpId" @change="(val)=>HandleRowTypeChange(row,val)">
+                            <el-option
+                                label="输入框"
+                                :value="1"
+                            />
+                            <el-option
+                                label="单选"
+                                :value="2"
+                            />
+                        </el-select>
+                        <span v-else>{{  DictTypeNumToName(row.dictType) }}</span>
+                    </template>
+
+
+                    <template #operation="{row}">
+                        <div class="table_row_option">
+                            <span :class="row.defaultStatus ? 'el_button_editor' : 'editor_disable'" @click="row.defaultStatus ? HandleDictionaryEditOrSave(row) : ''">{{row.tmpId ? '保存' : '编辑'}}</span>
+                            <span v-if="row.tmpId" class="el_button_editor" @click="HandleDictionaryCancel(row)">取消</span>
+                            <span v-else :class="row.defaultStatus ? 'el_button_delete' : 'editor_disable'" @click="row.defaultStatus ? HandleDictionaryDelete(row) : ''">删除</span>
+                        </div>
+                    </template>
+                </Table>
+                <div class="add_option" @click="HandleAddDictionary"> 
+                    <el-icon><CloseBold /></el-icon>
+                    <span>增加选项配置</span>
+                </div>
+            </div>
+        </template>
+    </FormDialog>
+</template>
+
+
+<script setup lang="ts">
+import { ref,watch } from 'vue';
+import FormDialog from '@/baseComponents/FormDialog.vue';
+import Table from '@/baseComponents/Table.vue';
+import TableRowDragUpDown from '@/baseComponents/TableRowDragUpDown.vue';
+
+import {tableColumns} from './table'
+
+const props = defineProps({
+    cardItems:{
+        type:Array,
+        detault:()=>[]
+    },
+    cardTitle:{
+        type:String,
+        default:''
+    },
+    middleColumnItm:{
+        type:Object
+    },
+    defaultTableData:{
+        type:Array,
+        default:()=>[]
+    },
+})
+
+const formVisible = defineModel('formVisible')
+const formSubmitLoading = ref(false)
+const finalTableColumns = ref([...tableColumns.value])  //最终渲染的表头
+const tableData = ref([])  //表数据
+
+
+
+// 处理表行的上下移动
+const HandleRowMove = (val)=>{
+    tableData.value = val
+}
+
+// 动态变更最终表列
+watch(()=>props.middleColumnItm,(newVal)=>{
+    if(newVal){
+       finalTableColumns.value = tableColumns.value.map((item,index)=>{
+        if(index == 2){
+            return [
+                {
+                    name:props.middleColumnItm?.name,
+                    label:props.middleColumnItm?.label,
+                    width:'100',
+                    fixed:'',
+                    align:'center',
+                    minWdth:'',
+                    custom:true,
+                },
+                item
+            ]
+        }
+        return item
+       }).flat()
+    }
+},{immediate:true,deep:true})
+
+
+// 动态变更表数据
+watch(()=>props.defaultTableData,(val)=>{
+    tableData.value = val || []
+},{immediate:true,deep:true})
+</script>
+
+
+<style lang="scss" scoped>
+.setting_card {
+    display: flex;
+    align-items: flex-start;
+    gap: 16px;
+
+    border-radius: 10px;
+    padding: 16px;
+    border: 1px solid #E4E7ED;
+    font-size: 14px;
+
+    .card_label {
+        width: 56px;
+        height: 32px;
+        line-height: 32px;
+        color: #333;
+    }
+
+    .tag_container {
+        flex: 1;
+        display: flex;
+        flex-wrap: wrap;
+        gap: 16px;
+
+        .tag_item {
+            height: 32px;
+            border-radius: 4px 4px 4px 4px;
+            border: 1px solid #DCDFE6;
+            padding: 6px 12px;
+            color: #666;
+        }
+    }
+
+    .button_editor{
+        height: 32px;
+        color: #2E64FA;
+        line-height: 32px;
+        cursor: pointer;
+    }
+}
+
+.dictionary_box{
+    width:100%;
+    height: 480px;
+    overflow: auto;
+    display: flex;
+    flex-direction: column;
+    gap:10px;
+    :deep(.page_table){
+        overflow: auto;
+    }
+
+    .add_option{
+        flex-shrink: 0;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        gap:8px;
+        background-color: rgba(46, 100, 250,0.1);
+        color:#2E64FA;
+        padding:4px auto;
+        text-align: center;
+        border-radius: 6px;
+
+        :deep(.el-icon){
+            transform: rotate(45deg);
+        }
+    }
+
+}
+
+.parameter_setting_form_dialog{
+     :deep(.el-dialog){
+        margin:0 !important;
+        top: 50% !important;
+        left: 50% !important; /* 若需水平居中可加上此行 */
+        transform: translate(-50%, -50%); /* 核心:基于自身宽高反向偏移 */
+    }
+    :deep(.el-dialog__body){
+        min-height: 500px !important;
+        max-height: 500px !important;
+    }
+}
+
+</style>

+ 35 - 0
src/components/settingCard/table.ts

@@ -0,0 +1,35 @@
+import { ref } from "vue"
+export const tableColumns = ref([
+    {
+        name:'moveable',
+        label:'',
+        width:'',
+        fixed:'',
+        align:'center',
+        minWdth:'30',
+        custom:true,
+        hidden:false,
+    },
+    {
+        name:'num',
+        label:'序号',
+        width:'',
+        fixed:'',
+        align:'center',
+        minWdth:'40',
+        custom:true,
+        customHeader:'',
+        hidden:false,
+    },
+    {
+        name:'operation',
+        label:'操作',
+        width:'',
+        fixed:'',
+        align:'center',
+        minWdth:'100',
+        custom:true,
+        customHeader:false,
+        hidden:false,
+    },
+])

+ 156 - 2
src/views/parameterConfig/index.vue

@@ -1,15 +1,169 @@
 <template>
-    <div>
-        参数配置
+    <div class="main_container">
+        <div class="page_item end_item">
+            <!-- 顶部公海设置 -->
+            <div class="page_search">
+                <div class="search_content">
+                    <div class="content_left">
+                        <div class="grade_title">公海设置</div>
+                    </div>
+                </div>
+            </div>
+
+            <!-- 公海设置的具体表单内容 -->
+            <div class="high_seas_config">
+                <div class="config_item">
+                    <span class="label_text">客户持有上限:</span>
+                    <el-input type="number" value="100"  />
+                    <span>个</span>
+                </div>
+                <div class="config_item">
+                    <span class="label_text">每日手动退回公海上限:</span>
+                    <el-input type="number" value="15"  />
+                    <span>个</span>
+                </div>
+                <div class="config_item">
+                    <span class="label_text">无跟进自动退回公海天数:</span>
+                    <el-input type="number" value="15" />
+                    <span>天</span>
+                </div>
+            </div>
+
+
+            <div class="page_search">
+                <div class="search_content">
+                    <div class="content_left">
+                        <div class="grade_title">字段设置</div>
+                    </div>
+                </div>
+            </div>
+
+            <!-- 字段设置区域 -->
+            <div class="field_settings_area">
+                <SettingCard cardTitle="地区管理" :cardItems="region_list"
+                    :middleColumnItm="{name:'province',label:'省份'}"
+                    :defaultTableData="region_list"/>
+                <SettingCard cardTitle="学段管理" :cardItems="stage_list"
+                    :middleColumnItm="{name:'phaseOfStudyingName',label:'学段名称'}"
+                    :defaultTableData="stage_list"/>
+                <SettingCard cardTitle="产品管理" :cardItems="product_list"
+                    :middleColumnItm="{name:'productName',label:'产品名称'}"
+                    :defaultTableData="product_list"/>
+                <SettingCard cardTitle="跟进状态" :cardItems="status_list" 
+                    :middleColumnItm="{name:'followUpStatus',label:'跟进状态'}"
+                    :defaultTableData="status_list"/>
+                <SettingCard cardTitle="职务管理" :cardItems="job_list"
+                    :middleColumnItm="{name:'positionName',label:'职务名称'}"
+                    :defaultTableData="job_list"/>
+            </div>
+        </div>
     </div>
 </template>
 
 
 <script setup lang="ts">
+import { ref } from 'vue';
+import SettingCard from '@/components/settingCard/SettingCard.vue';
 
+// 模拟图片中的数据
+const region_list = ref([
+    { province: '北京市' },
+    { province: '上海市' },
+    { province: '天津市' },
+    { province: '广东' },
+    { province: '辽宁' },
+    { province: '河南' },
+    { province: '河北' },
+    { province: '湖南' },
+    { province: '湖北' },
+    { province: '云南' },
+    { province: '福建' },
+    { province: '海南' },
+    { province: '四川' },
+    { province: '初中' },
+    { province: '初中' },
+    { province: '初中' },
+    { province: '初中' }
+]);
+const stage_list = ref([
+    { phaseOfStudyingName: '幼儿园' },
+    { phaseOfStudyingName: '小学' },
+    { phaseOfStudyingName: '初中' },
+    { phaseOfStudyingName: '高中' },
+    { phaseOfStudyingName: '完中' },
+    { phaseOfStudyingName: '九年一贯' },
+    { phaseOfStudyingName: '十二年一贯' },
+    { phaseOfStudyingName: '职高' },
+    { phaseOfStudyingName: '大学' },
+    { phaseOfStudyingName: '初中' }
+]);
+const product_list = ref([
+    { productName: '大数据精准教学诊断平台' },
+    { productName: '选择题智能判分' },
+    { productName: '教学材料采集' },
+    { productName: '教师校本研修' },
+    { productName: '学生校本课程学习' },
+    { productName: '智能校本选课' },
+    { productName: '教师专业发展' },
+    { productName: '协同教研备课' },
+    { productName: '校园信息发布' },
+    { productName: '智能评教评学' },
+    { productName: '智能考场编排' },
+    { productName: '智能听课评课' },
+    { productName: '基础数据管理' }
+]);
+const status_list = ref([
+    { followUpStatus: '线索建立' },
+    { followUpStatus: '需求调研' },
+    { followUpStatus: '方案演示' },
+    { followUpStatus: '试用测试' },
+    { followUpStatus: '项目搁置' },
+    { followUpStatus: '输单' },
+    { followUpStatus: '赢单' }
+]);
+
+const job_list = ref([
+    { positionName: '校长' },
+    { positionName: '副校长' },
+    { positionName: '执行校长' },
+    { positionName: '教学主任' },
+    { positionName: '教务主任' },
+    { positionName: '信息主任' }
+]);
 </script>
 
 
 <style lang="scss" scoped>
+.grade_title{
+    margin-bottom: 16px;
+}
+/* 公海配置行 */
+.high_seas_config {
+    display: flex;
+    flex-wrap: wrap;
+    gap:20px 100px;
+
+    margin-bottom: 48px;
+    font-size: 14px;
+    color: #333;
+
+    .config_item {
+        display: flex;
+        align-items: center;
+        gap:10px;
+        .label_text {
+            flex-shrink: 0;
+        }
+        .el-input{
+            width: 80px;
+        }
+    }
+}
 
+// 字段设置区域
+.field_settings_area {
+    display: flex;
+    flex-direction: column;
+    gap:16px;
+}
 </style>