Ver código fonte

setting global

zdl 10 meses atrás
pai
commit
bdafc31abd

+ 39 - 0
src/api/helper.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+export function addHelper(data) {
+  return request({
+    url: '/big_model/set_template',
+    method: 'post',
+    data
+  })
+}
+
+export function getRule() {
+  return request({
+    url: '/big_model/get_case_rule',
+    method: 'get'
+  })
+}
+
+export function getInputSelect() {
+  return request({
+    url: '/big_model/get_input_select',
+    method: 'get'
+  })
+}
+
+export function helperPage(params) {
+  return request({
+    url: '/big_model/get_template',
+    method: 'get',
+    params
+  })
+}
+
+export function deleteHelper(data) {
+  return request({
+    url: '/big_model/del_template',
+    method: 'post',
+    data
+  })
+}

+ 16 - 0
src/api/setting.js

@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+export function setSetting(data) {
+  return request({
+    url: '/setting/global_set',
+    method: 'post',
+    data
+  })
+}
+
+export function getSetting() {
+  return request({
+    url: '/setting/get_setting',
+    method: 'get'
+  })
+}

+ 36 - 0
src/views/helper/components/SearchBox.vue

@@ -0,0 +1,36 @@
+<template>
+  <div>
+    <el-form :inline="true" :model="data" class="demo-form-inline">
+      <el-form-item label="">
+        <el-input v-model="data.user" placeholder="应用名称" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="onSubmit">查询</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    data: {
+      type: Object,
+      default() {
+        return {
+          user: ''
+        }
+      }
+    }
+  },
+  methods: {
+    onSubmit() {
+      console.log('submit!')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 94 - 0
src/views/helper/components/TableBox.vue

@@ -0,0 +1,94 @@
+<template>
+  <div>
+    <div class="btn-box">
+      <el-button type="primary" icon="el-icon-plus" @click="onCreate">新增</el-button>
+    </div>
+    <el-table
+      v-loading="loading"
+      :data="data"
+      border
+      style="width: 100%"
+    >
+      <el-table-column
+        type="index"
+        label="序号"
+        width="100"
+        align="center"
+      />
+      <el-table-column
+        prop="app_name"
+        label="应用名称"
+        width="240"
+        show-overflow-tooltip
+      />
+      <el-table-column
+        prop="content"
+        label="任务描述"
+        show-overflow-tooltip
+      />
+      <el-table-column
+        prop=""
+        label="操作"
+        width="160"
+      >
+        <template slot-scope="scope">
+          <el-link :underline="false" type="primary" @click="onEdit(scope.row)">编辑</el-link>
+          <el-divider direction="vertical" />
+          <el-link :underline="false" type="danger" @click="onDel(scope.row)">删除</el-link>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { deleteHelper } from '@/api/helper'
+export default {
+  props: {
+    data: {
+      type: Array,
+      default() {
+        return []
+      }
+    },
+    loading: {
+      type: Boolean,
+      default() {
+        return false
+      }
+    }
+  },
+  methods: {
+    onCreate() {
+      localStorage.removeItem('helper')
+      this.$router.push({ path: '/helper/config' })
+    },
+    onEdit(row) {
+      localStorage.setItem('helper', JSON.stringify(row))
+      this.$router.push({ path: '/helper/config' })
+    },
+    onDel(row) {
+      this.$confirm('是否确认删除该数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteHelper({ id: row.id }).then((res) => {
+          this.$message.success(res.m || '操作成功')
+          this.$emit('refresh')
+        })
+      })
+    },
+    handleRefresh() {
+      this.$emit('refresh')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.btn-box {
+  text-align: right;
+  margin-bottom: 15px;
+}
+</style>

+ 129 - 0
src/views/helper/config.vue

@@ -0,0 +1,129 @@
+<template>
+  <div class="app-container">
+    <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="140px" class="demo-ruleForm">
+      <template>
+        <div style="font-size: 16px; color: #1b64b0; line-height: 40px; margin-bottom: 16px;">
+          病历质控AI助手
+        </div>
+      </template>
+      <el-form-item label="应用名称" prop="rule_id">
+        <el-select v-model="ruleForm.rule_id" filterable clearable style="width: 300px;" placeholder="请选择">
+          <el-option v-for="item of apps" :key="item.id" :label="item.notice" :value="item.id" />
+        </el-select>
+      </el-form-item>
+      <template>
+        <div style="font-size: 16px; color: #1b64b0; line-height: 40px; margin-bottom: 16px;">
+          AI配置
+        </div>
+      </template>
+      <el-form-item label="输入" prop="data_type">
+        <el-cascader
+          v-model="ruleForm.data_type"
+          :options="inputs"
+          filterable
+          collapse-tags
+          :props="{ expandTrigger: 'hover', label: 'name', children: 'child', value: 'key', multiple: true, checkStrictly: false, emitPath: false }"
+          placeholder="请选择"
+          style="width: 340px;"
+        />
+      </el-form-item>
+      <el-form-item label="提示词" prop="content">
+        <el-input v-model="ruleForm.content" type="textarea" :autosize="{ minRows: 8, maxRows: 12 }" placeholder="请输入" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="onSubmit">提交</el-button>
+        <el-button @click="onCancle">取消</el-button>
+        <el-button type="primary" plain style="float: right;" @click="onTest">测试</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { getRule, getInputSelect, addHelper } from '@/api/helper'
+export default {
+  data() {
+    return {
+      ruleForm: {
+        rule_id: '',
+        data_type: [],
+        content: ''
+      },
+      rules: {
+        rule_id: [
+          { required: true, message: '请选择', trigger: 'change' }
+        ],
+        data_type: [
+          { required: true, message: '请选择', trigger: 'change' }
+        ],
+        content: [
+          { required: true, message: '请输入', trigger: 'blur' }
+        ]
+      },
+      apps: [],
+      inputs: []
+    }
+  },
+  created() {
+    this.getRule()
+    this.getInputSelect()
+  },
+  mounted() {
+    const helper = localStorage.getItem('helper')
+    if (helper) {
+      setTimeout(() => {
+        this.ruleForm = JSON.parse(localStorage.getItem('helper'))
+        console.log(this.ruleForm)
+      }, 1500)
+    }
+  },
+  methods: {
+    onTest() {
+      const url = 'http://172.16.9.43:8001'
+      window.open(url, '_blank')
+    },
+    getRule() {
+      getRule().then((res) => {
+        const { p } = res
+        this.apps = p
+      })
+    },
+    getInputSelect() {
+      getInputSelect().then((res) => {
+        const { p } = res
+        this.inputs = p
+      })
+    },
+    onSubmit() {
+      this.$refs['ruleForm'].validate((valid) => {
+        if (valid) {
+          const { id, data_type, content, rule_id } = this.ruleForm
+          const params = {
+            data_type,
+            content,
+            rule_id
+          }
+          if (id) {
+            params.id = id
+          }
+          addHelper(params).then((res) => {
+            this.$message.success(res.m || '操作成功')
+            this.$router.push({ path: '/helper/index' })
+          })
+        } else {
+          return false
+        }
+      })
+    },
+    onCancle() {
+      this.$router.push({ path: '/helper/index' })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.demo-ruleForm {
+  width: 50%;
+}
+</style>

+ 97 - 0
src/views/helper/index.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="app-container">
+    <SearchBoxVue
+      :data="searchData"
+      @search="handleSearch"
+    />
+    <TableBoxVue
+      :loading="loading"
+      :data="tableData"
+      style="margin-top: -40px"
+      @refresh="handleRefresh"
+    />
+    <pagination
+      :auto-scroll="false"
+      :total="paginationData.total"
+      :page="paginationData.page"
+      :limit="paginationData.limit"
+      @pagination="handlePagination"
+    />
+  </div>
+</template>
+
+<script>
+import SearchBoxVue from './components/SearchBox.vue'
+import TableBoxVue from './components/TableBox.vue'
+import { helperPage } from '@/api/helper'
+export default {
+  components: {
+    SearchBoxVue,
+    TableBoxVue
+  },
+  data() {
+    return {
+      loading: false,
+      searchData: {
+        rule_id: ''
+      },
+      tableData: [],
+      paginationData: {
+        total: 0,
+        page: 1,
+        limit: 10
+      }
+    }
+  },
+  created() {
+    console.log('created')
+    this.getList()
+  },
+  activated() {
+    console.log('activated')
+    this.getList()
+  },
+  methods: {
+    async getList() {
+      const { page, limit } = this.paginationData
+      const params = {
+        ...this.searchData,
+        page,
+        page_size: limit
+      }
+      this.loading = true
+      helperPage(params)
+        .then((res) => {
+          const { p } = res
+          this.paginationData.total = p.count
+          this.tableData = p.list
+        })
+        .catch((error) => {
+          console.log(error)
+        })
+        .finally(() => {
+          this.loading = false
+        })
+    },
+    handlePagination(param) {
+      this.paginationData.page = param.page
+      this.paginationData.limit = param.limit
+      this.getList()
+    },
+    handleSearch() {
+      this.paginationData.page = 1
+      this.getList()
+    },
+    handleRefresh() {
+      this.paginationData.page = 1
+      this.getList()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.box-container {
+  padding: 20px;
+}
+</style>

+ 95 - 0
src/views/system/setting/components/ImgUploadLoginBg.vue

@@ -0,0 +1,95 @@
+<template>
+  <div>
+    <el-upload
+      ref="upload"
+      class="avatar-uploader"
+      action="#"
+      :show-file-list="false"
+      :before-upload="beforeUpload"
+      :auto-upload="true"
+    >
+      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,建议分辨率{{ size }}</div>
+      <img v-if="imageUrl" :src="imageUrl" class="avatar" alt>
+      <i v-else class="el-icon-plus avatar-uploader-icon" />
+    </el-upload>
+
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    size: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    code: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    imageUrl: {
+      type: String,
+      default() {
+        return ''
+      }
+    }
+  },
+  methods: {
+    beforeUpload(file) {
+      const imgType = ['image/jpeg', 'image/png'].includes(file.type)
+      if (!imgType) {
+        this.$message.error('上传头像图片只能是 JPG/PNG 格式!')
+        return false
+      }
+      const content = this.$refs.upload.uploadFiles[0].raw
+      const reader = new FileReader()
+      const _this = this
+      reader.onloadend = (e) => {
+        const base64 = reader.result
+        const params = {
+          type: this.code,
+          url: base64
+        }
+        _this.$emit('upload', params)
+        _this.imageUrl = e.target.result
+        // 处理 base64 格式的文件
+      }
+      reader.readAsDataURL(content)
+      return false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 20px;
+    color: #8c939d;
+    width: 192px;
+    height: 92px;
+    line-height: 92px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 192px;
+    height: 92px;
+    display: block;
+  }
+  ::v-deep .el-upload__tip {
+    margin-top: 0;
+  }
+</style>

+ 96 - 0
src/views/system/setting/components/ImgUploadLoginLogo.vue

@@ -0,0 +1,96 @@
+<template>
+  <div>
+    <el-upload
+      ref="upload"
+      class="avatar-uploader"
+      action="#"
+      :show-file-list="false"
+      :before-upload="beforeUpload"
+      :auto-upload="true"
+    >
+      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,建议分辨率{{ size }}</div>
+      <img v-if="imageUrl" :src="imageUrl" class="avatar" alt>
+      <i v-else class="el-icon-plus avatar-uploader-icon" />
+    </el-upload>
+
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    size: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    code: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    imageUrl: {
+      type: String,
+      default() {
+        return ''
+      }
+    }
+  },
+  methods: {
+    beforeUpload(file) {
+      const imgType = ['image/jpeg', 'image/png'].includes(file.type)
+      if (!imgType) {
+        this.$message.error('上传头像图片只能是 JPG/PNG 格式!')
+        return false
+      }
+      const content = this.$refs.upload.uploadFiles[0].raw
+      const reader = new FileReader()
+      const _this = this
+      reader.onloadend = (e) => {
+        const base64 = reader.result
+        const params = {
+          type: this.code,
+          url: base64
+        }
+        _this.$emit('upload', params)
+        _this.imageUrl = e.target.result
+        // 处理 base64 格式的文件
+      }
+      reader.readAsDataURL(content)
+      return false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 20px;
+    color: #8c939d;
+    width: 125px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 125px;
+    height: 40px;
+    display: block;
+    object-fit: contain;
+  }
+  ::v-deep .el-upload__tip {
+    margin-top: 0;
+  }
+</style>

+ 95 - 0
src/views/system/setting/components/ImgUploadMenuLogo.vue

@@ -0,0 +1,95 @@
+<template>
+  <div>
+    <el-upload
+      ref="upload"
+      class="avatar-uploader"
+      action="#"
+      :show-file-list="false"
+      :before-upload="beforeUpload"
+      :auto-upload="true"
+    >
+      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,建议分辨率{{ size }}</div>
+      <img v-if="imageUrl" :src="imageUrl" class="avatar" alt>
+      <i v-else class="el-icon-plus avatar-uploader-icon" />
+    </el-upload>
+
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    size: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    code: {
+      type: String,
+      default() {
+        return ''
+      }
+    },
+    imageUrl: {
+      type: String,
+      default() {
+        return ''
+      }
+    }
+  },
+  methods: {
+    beforeUpload(file) {
+      const imgType = ['image/jpeg', 'image/png'].includes(file.type)
+      if (!imgType) {
+        this.$message.error('上传头像图片只能是 JPG/PNG 格式!')
+        return false
+      }
+      const content = this.$refs.upload.uploadFiles[0].raw
+      const reader = new FileReader()
+      const _this = this
+      reader.onloadend = (e) => {
+        const base64 = reader.result
+        const params = {
+          type: this.code,
+          url: base64
+        }
+        _this.$emit('upload', params)
+        _this.imageUrl = e.target.result
+        // 处理 base64 格式的文件
+      }
+      reader.readAsDataURL(content)
+      return false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 20px;
+    color: #8c939d;
+    width: 120px;
+    height: 120px;
+    line-height: 120px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 120px;
+    height: 120px;
+    display: block;
+  }
+  ::v-deep .el-upload__tip {
+    margin-top: 0;
+  }
+</style>

+ 108 - 0
src/views/system/setting/index.vue

@@ -0,0 +1,108 @@
+<template>
+  <div class="box-container">
+    <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="180px" class="demo-ruleForm">
+      <el-form-item label="登录页背景图" prop="background_img">
+        <ImgUploadLoginBg :image-url="ruleForm.background_img" code="login_bg" size="1920*920" @upload="handleUpload" />
+      </el-form-item>
+      <el-form-item label="登录页logo" prop="logo">
+        <ImgUploadLoginLogo :image-url="ruleForm.logo" code="logo" size="800*127" @upload="handleUpload" />
+      </el-form-item>
+      <el-form-item label="系统logo" prop="menu_logo">
+        <ImgUploadMenuLogo :image-url="ruleForm.menu_logo" code="menu_logo" size="400*400" @upload="handleUpload" />
+      </el-form-item>
+      <el-form-item label="医院名称" prop="web_name">
+        <el-input v-model="ruleForm.web_name" placeholder="请输入" style="width: 300px;" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
+        <el-button @click="onCancel">取消</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import ImgUploadLoginBg from './components/ImgUploadLoginBg'
+import ImgUploadLoginLogo from './components/ImgUploadLoginLogo'
+import ImgUploadMenuLogo from './components/ImgUploadMenuLogo'
+import { setSetting, getSetting } from '@/api/setting'
+
+export default {
+  components: {
+    ImgUploadLoginBg,
+    ImgUploadLoginLogo,
+    ImgUploadMenuLogo
+  },
+  data() {
+    return {
+      ruleForm: {
+        background_img: '',
+        logo: '',
+        menu_logo: '',
+        web_name: ''
+      },
+      rules: {
+        background_img: [
+          { required: true, message: '请上传', trigger: 'blur' }
+        ],
+        logo: [
+          { required: true, message: '请上传', trigger: 'blur' }
+        ],
+        menu_logo: [
+          { required: true, message: '请上传', trigger: 'blur' }
+        ],
+        web_name: [
+          { required: true, message: '请输入', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  created() {
+    this.getSetting()
+  },
+  methods: {
+    handleUpload(val) {
+      const { type, url } = val
+      if (type === 'login_bg') {
+        this.ruleForm.background_img = url
+      }
+      if (type === 'logo') {
+        this.ruleForm.logo = url
+      }
+      if (type === 'menu_logo') {
+        this.ruleForm.menu_logo = url
+      }
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          setSetting(this.ruleForm).then(res => {
+            this.$message.success(res.message || '保存成功')
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    onCancel() {
+      this.$refs.ruleForm.clearValidate()
+    },
+    getSetting() {
+      getSetting().then(res => {
+        const { logo, menu_logo, background_img, web_name } = res.p
+        this.$set(this.ruleForm, 'logo', logo.content)
+        this.$set(this.ruleForm, 'menu_logo', menu_logo.content)
+        this.$set(this.ruleForm, 'background_img', background_img.content)
+        this.$set(this.ruleForm, 'web_name', web_name.content)
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.box-container {
+  padding: 20px;
+}
+</style>