<template>
  <div class="layout">
    <h1 style="margin-top: 10px;margin-bottom: 10px;">页面配置</h1>
    <div style="color: #505050;margin-bottom: 20px;">将表单内容进行分步可以提高用户处理的专注度,降低页面的复杂性</div>
    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="接口地址" style="width: 60%;">
            <el-input v-model="state.filter.name" placeholder="请输入接口地址" @keyup.enter="onQuery" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="查询页面接口来源" style="width: 70%;">
            <el-select v-model="state.filter.api"  placeholder="请选择页面接口来源" @change="onChange(state.filter.api)">
              <el-option v-for="(value, key) in state.api" :key="key" :label="value.api+' '+value.summary"  :value="value.api" />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
    </el-card>
    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="查询按钮" style="width: 100%;"></el-form-item>
          <el-form-item label="">
            <el-row :gutter="70">
              <el-col :xs="6" :sm="4" :md="4" :lg="4" :xl="4" v-for="(v, k) in state.selectBtn" :key="k">
                <span style="margin-right: 10px;">{{ v.name }}</span>
                <el-switch v-model="v.value" @change="change(k)"></el-switch>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="查询条件配置" style="width: 100%;"></el-form-item>
          <el-form-item label="">
            <el-row :gutter="100">
              <el-col :span="100" :xl="4" v-for="(v, k) in state.selectVal" :key="k">
                <span style="margin-right: 10px;">{{ v.description }}</span>
                <el-switch v-model="v.value" @change="change(k)"></el-switch>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
    </el-card>
    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="列表操作栏" style="width: 100%;"></el-form-item>
          <el-form-item label="">
            <el-row :gutter="100">
              <el-col :span="100" v-for="(v, k) in state.tableBtn" :key="k">
                <span style="margin-right: 10px;">{{ v.name }}</span>
                <el-switch v-model="v.value" @change="change(k)"></el-switch>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <el-form :inline="true" @submit.stop.prevent>
          <el-form-item label="列表元素配置" style="width: 100%;"></el-form-item>
          <el-form-item label="">
            <el-row :gutter="100">
              <el-col :span="100" v-for="(v, k) in state.tableVal" :key="k">
                <span style="margin-right: 10px;">{{ v.description }}</span>
                <el-switch v-model="v.value" @change="change(k)"></el-switch>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
      </div>
    </el-card>
    <div style="display: flex;justify-content: center;align-items: center;">
      <el-button style="margin-top: 20px;width: 264px;height: 42px;" type="primary" @click="onsubmit()">生成页面</el-button>
    </div>
  </div>
</template>

<script lang="ts" setup name="admin/code">
import { ref,reactive, onMounted, onBeforeMount } from 'vue'
import eventBus from '/@/utils/mitt'
import { ElMessage } from 'element-plus'

const state = reactive({
  loading: false,
  orgFormTitle: '',
  filter: {
    name: 'http://dev.hsfuel.com:8070/app/swagger/app/swagger.json',
    api:''
  },
  api:[],
  selectBtn:[{value:false,name:'查询',method:'onQuery'},
    {value:false,name:'添加',method:'onAdd'},
    {value:false,name:'批量删除',method:'ondelete'},
    {value:false,name:'重置',method:'onReset'},
    {value:false,name:'上传',method:'onUpload'},
    {value:false,name:'导出',method:'onExport'},
    {value:false,name:'批量导入',method:'onBatImport'},
    {value:false,name:'批量导出',method:'onBatExport'},
    {value:false,name:'批量审核',method:'onBatReview'}],
  selectVal:[],
  tableBtn:[{value:false,name:'编辑',method:'onDateUpdate'},
    {value:false,name:'详情',method:'onDataDetail'},
    {value:false,name:'删除',method:'onDataDelete'}],
  tableVal:[],
  isPage:false
})
const dataJson=ref('')
onMounted(() => {
  onQuery()
  eventBus.off('refreshOrg')
  eventBus.on('refreshOrg', () => {
    onQuery()
  })
})

onBeforeMount(() => {
  eventBus.off('refreshOrg')
})
const change=(k)=>{
  // console.log(k)
  // console.log(state.selectVal[k].value,state.selectVal[k].description)
}
//解析页面接口数据
const onQuery = async () => {
  fetch(state.filter.name)
    .then(response=>response.json())
    .then(swaggerJson=>{
      //console.log(swaggerJson)
      dataJson.value=swaggerJson
      const {paths} =dataJson.value
      //console.log(paths)
      for(const path in paths){
        if('get' in paths[path]){
          let api:any=path
          let summary:any=paths[path].get.summary?paths[path].get.summary:''
          let methods:any='GET'
          let isQuery:any=false
          let isBody:any=false
          if('parameters' in paths[path].get){
            isQuery=true
          }
          if('requestBody' in paths[path].get){
            isBody=true
          }
          state.api.push({api:api,summary:summary,methods:methods,isQuery:isQuery,isBody:isBody})
          //console.log(path)
          //console.log(paths[path].get.responses['200'].content['application/json'].schema['$ref'])
        }
        if('post' in paths[path]){
          let summary:any=paths[path].post.summary?paths[path].post.summary:''
          if(summary===''||summary.includes('查询')||summary.includes('获取')){
            let api:any=path
            let methods:any='POST'
            let isQuery:any=false
            let isBody:any=false
            if('parameters' in paths[path].post){
              isQuery=true
            }
            if('requestBody' in paths[path].post){
              isBody=true
            }
            state.api.push({api:api,summary:summary,methods:methods,isQuery:isQuery,isBody:isBody})
            //console.log(paths[path].post.responses['200'].content['application/json'].schema['$ref'])
            //console.log(paths[path].post.requestBody)
          }
          //console.log(path)
          //console.log(paths[path])
        }
      }
      //console.log(state.api)
    })
    .catch(error=>{
      console.log('Error fetch Swagger Json :',error)
    })
}
//解析查询页面查询条件及列表元素
const onChange=(api)=>{
  state.selectVal=[]
  state.tableVal=[]
  state.selectBtn=state.selectBtn.map(item=>{
    item.value=false
    return item
  })
  state.tableBtn=state.tableBtn.map(item=>{
    item.value=false
    return item
  })
  let data=dataJson.value.paths[api]
  const tableData=dataJson.value.components.schemas
  //console.log(data)
  if('get' in data){
    data=data.get
  }else{
    data=data.post
    //console.log(data)
  }
  if('parameters' in data){
    const parameters=data['parameters']
    //console.log(parameters)
    for(const val in parameters){
      if(!parameters[val].name.includes('Page')&&!parameters[val].name.includes('DynamicFilter')){
        let value:any=false
        let name:any=parameters[val].name
        let description:any=(parameters[val].description&&!parameters[val].description.includes(1)&&!(parameters[val].description===''))?parameters[val].description:parameters[val].name
        let type:any=parameters[val].schema.type
        let isDate:any=parameters[val].schema.format==='date-time'?true:false
        if(parameters[val].name.includes('.')){
          let s=parameters[val].name.split('.')
          let p=s[1].trim()
          name=p
          description=(parameters[val].description&&!parameters[val].description.includes(1)&&!(parameters[val].description===''))?parameters[val].description:p
        }
        state.selectVal.push({value:value,name:name,description:description,type:type,isDate:isDate})
      }
    }
  }
  if('requestBody' in data){
    const requestBody=data['requestBody']['content']['application/json'].schema['$ref']
    let s=requestBody.split('/')
    let p=s[3].trim()
    let properties=tableData[p]['properties']
    if('dynamicFilter' in properties){
      properties=properties.filter['$ref']
      s=properties.split('/')
      p=s[3].trim()
      properties=tableData[p]['properties']
    }
    //console.log(properties)
    for(const val in properties){
      let value:any=false
      let name:any=val
      let description:any=(properties[val].description&&!properties[val].description.includes(1)&&!(properties[val].description===''))?properties[val].description:val
      let type:any=properties[val].type
      let isDate:any=false
      if(properties[val].format==='date-time'||val.includes('Time')||val.includes('Date')){
        isDate=true
      }
      //console.log(value,name,description,type,isDate)
      state.selectVal.push({value:value,name:name,description:description,type:type,isDate:isDate})
    }
  }
  let form=data.responses['200'].content['application/json'].schema['$ref']
  let f=form.split('/')
  let r=f[3].trim()
  let formData=tableData[r].properties.data
  let dataName:any=r
  let list:any=''
  if(!('type' in formData)||formData.type==='array'){
    if(!('type' in formData)||'$ref' in formData.items){
      if(!('type' in formData)){
        formData=formData['$ref']
      }else{
        formData=formData.items['$ref']
      }
      f=formData.split('/')
      r=f[3].trim()
      list=r
      formData=tableData[r]['properties']
      let isList:any=false
      let isArray:any=true
      if('total' in formData){
        formData=formData.list.items['$ref']
        f=formData.split('/')
        r=f[3].trim()
        formData=tableData[r]['properties']
        isList=true
        state.isPage=true
      }
      for(const val in formData){
        let value:any=false
        let name:any=val
        let description:any=(formData[val].description&&!formData[val].description.includes(1)&&!(formData[val].description===''))?formData[val].description:val
        let type:any=formData[val].type
        //console.log(value,name,description,type)
        state.tableVal.push({value:value,name:name,description:description,type:type,belong:r,isList:isList,isArray:isArray,dataName:dataName,list:list})
      }
    }else{
      let value:any=false
      let isList:any=false
      let isArray:any=true
      let name:any=r
      let description:any=(formData.description&&!formData.description.includes(1)&&!(formData.description===''))?formData.description:r
      let type:any=formData.type
      //console.log(value,name,description,type)
      state.tableVal.push({value:value,name:name,description:description,type:type,belong:r,isList:isList,isArray:isArray,dataName:dataName,list:list})
    }
  }else{
    let value:any=false
    let name:any=r
    let isList:any=false
    let isArray:any=false
    let description:any=(formData.description&&!formData.description.includes(1)&&!(formData.description===''))?formData.description:r
    let type:any=formData.type
    //console.log(value,name,description,type)
    state.tableVal.push({value:value,name:name,description:description,type:type,belong:r,isList:isList,isArray:isArray,dataName:dataName,list:list})
  }
}
//生成查询页面主要代码文件
const onsubmit=()=>{
  let api=''
  if(state.filter.api===''){
    ElMessage.error('请选择查询页面接口来源')
  }else{
    api=state.api.filter(item=>item.api===state.filter.api)
  }
  let selBtn=state.selectBtn.filter(item=>item.value===true)
  let selVal=state.selectVal.filter(item=>item.value===true)
  let tabBtn=state.tableBtn.filter(item=>item.value===true)
  let tabVal=state.tableVal.filter(item=>item.value===true)
  //console.log(tabVal)
  let apiCode=`import { AxiosResponse } from 'axios'
  import { ContentType, HttpClient, RequestParams } from './http-client'
  export class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
    /**
   * No description
   *
   * @tags
   * @name GetList
   * @summary 查询列表
   * @request ${api[0].methods}:'${api[0].api}'
   * @secure
   */\n`
  if(api[0].methods==='GET'){
    apiCode=apiCode+`getList = (query:any ,params: RequestParams = {}) : any  =>
      this.request<AxiosResponse,any>({
        path:'${api[0].api}',
        method: 'GET',
        query:query,`
  }else{
    if(api[0].isQuery===true&&api[0].isBody===true){
      apiCode=apiCode+`getList = (data:any ,query:any ,params: RequestParams = {}) : any  =>
      this.request<AxiosResponse,any>({
        path:'${api[0].api}',
        method: 'POST',
        body:data,
        query:query,
        type: ContentType.Json,`
    }else if(api[0].isQuery===false&&api[0].isBody===true){
      apiCode=apiCode+`getList = (data:any ,params: RequestParams = {}) : any  =>
      this.request<AxiosResponse,any>({
        path:'${api[0].api}',
        method: 'POST',
        body:data,
        type: ContentType.Json,`
    }else{
      apiCode=apiCode+`getList = (query:any ,params: RequestParams = {}) : any  =>
      this.request<AxiosResponse,any>({
        path:'${api[0].api}',
        method: 'POST',
        query:query,
        type: ContentType.Json,`
    }
  }
  apiCode=apiCode+`
        secure: true,
        format: 'json',
        ...params
      })
    }`
  //console.log(apiCode)
  let dataCode=`/** 查询信息输出 */
  export interface ${state.tableVal[0].dataName}{
  /** 是否成功标记 */
  success?: boolean
  /** 编码 */
  code?: string | null
  /** 消息 */
  msg?: string | null
  /** 数据 */\n`
  if(state.tableVal[0].isArray===false&&state.tableVal[0].isList===false){
    dataCode=dataCode+`  data?:${state.tableVal[0].type} | null\n}`
    //console.log(dataCode)
  }else if(state.tableVal[0].isArray===true&&state.tableVal[0].isList===false){
    if(state.tableVal[0].list===''){
      dataCode=dataCode+` data?:${state.tableVal[0].list}[] | null\n}`
    }else{
      dataCode=dataCode+` data?:${state.tableVal[0].list}[] | null\n}
      export interface ${state.tableVal[0].list}{\n`
      for(let i=0;i<state.tableVal.length;i++){
        dataCode=dataCode+`   /** ${state.tableVal[i].description} */
        ${state.tableVal[i].name}?: ${state.tableVal[i].type}\n`
      }
      dataCode=dataCode+`\n}`
    }
    //console.log(dataCode)
  }else{
    dataCode=dataCode+` data?:${state.tableVal[0].list}[] | null\n}
    export interface ${state.tableVal[0].list}{
      /**
      * 数据总数
      * @format int64
      */
      total?: number
      /** 数据 */
      list?: ${state.tableVal[0].belong}[] | null
    }
    export interface ${state.tableVal[0].belong}{\n`
    for(let i=0;i<state.tableVal.length;i++){
      dataCode=dataCode+`   /** ${state.tableVal[i].description} */
      ${state.tableVal[i].name}?: ${state.tableVal[i].type}\n`
    }
    dataCode=dataCode+`\n}`
    //console.log(dataCode)
  }
  if(state.isPage===true){
    dataCode=dataCode+`\nexport interface pageInput {
      /**当前页数 */
      CurrentPage: number | any
      /**展示页数 */
      PageSize: number | any
    }`
  }
  let selection=false
  let indexCode=`\n<template>
  <div class="layout-pd">
    <el-row>`
  if(selBtn.length>0||selVal.length>0){
    indexCode=indexCode+`\n<!--操作-->
      <el-col :xs="24" >
        <el-card class="mt8"  shadow="hover" >`
    if(selVal.length>0){
      indexCode=indexCode+`\n<el-form :model="state.filter" :inline="true" @submit.stop.prevent>
            <el-form-item prop="name" style="width: 100%">`
      for(let i=0;i<selVal.length;i++){
        if(selVal[i].type==='interger'){
          indexCode=indexCode+`\n<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
                <el-form-item label="${selVal[i].description}">
                  <el-input-number v-model="state.filter.${selVal[i].name}" />
                </el-form-item>
              </el-col>`
        }else if(selVal[i].isDate===true){
          indexCode=indexCode+`\n<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
            <el-form-item label="选择时间">
                  <el-date-picker
                    v-model="state.filter.${selVal[i].name}"
                    type="datetimerange"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    range-separator="To"
                    start-placeholder="Start date"
                    end-placeholder="End date"
                  />
                </el-form-item>
              </el-col>`
        }else{
          indexCode=indexCode+`\n<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
                <el-form-item label="${selVal[i].description}">
                  <el-input v-model="state.filter.${selVal[i].name}" placeholder="单行输入" clearable></el-input>
                </el-form-item>
              </el-col>`
        }
      }
      indexCode=indexCode+`\n</el-form-item>
          </el-form>`
    }
    if(selBtn.length>0){
      indexCode=indexCode+`\n<div class="my-flex my-flex-start" >`
      for(let i=0;i<selBtn.length;i++){
        if(selBtn[i].name.includes('批量')){
          selection=true
        }
        indexCode=indexCode+`\n<el-button  type="primary" icon="ele-CirclePlus" @click="${selBtn[i].method}"> ${selBtn[i].name} </el-button>`
      }
      indexCode=indexCode+`\n</div>`
    }
    indexCode=indexCode+`\n</el-card>
      </el-col>`
  }
  if(tabVal.length>0){
    indexCode=indexCode+`\n<!--表格-->
      <el-col  :xs="24" >
        <el-card style="height: 70vh" class="my-fill mt8" shadow="hover">`
    if(selection){
      indexCode=indexCode+`\n<el-table-column type="selection" width="50"></el-table-column>`
    }
    indexCode=indexCode+`\n<el-table v-loading="state.loading" stripe :data="state.tableModel" row-key="id" style="width: 100%">
        <el-table-column v-for="column in state.dynamicColumns" :key="column.prop" :prop="column.prop" :label="column.label"  >
        </el-table-column>`
    if(tabBtn.length>0){
      indexCode=indexCode+` \n<el-table-column label="操作"  fixed="right" header-align="center" align="center" class="right-operation" width="140">
        <template #default="{ row }" >`
      for(let i=0;i<tabBtn.length;i++){
        indexCode=indexCode+`\n<el-link
                  class="my-el-link mr12 ml12"
                  type="primary"
                  icon="ele-Upload"
                  @click="${tabBtn[i].method}(row)"
                  :underline="false"
                  target="_blank"
                >${tabBtn[i].name}</el-link>`
      }
      indexCode=indexCode+`\n</template>
            </el-table-column>`
    }
    indexCode=indexCode+`\n</el-table>`
    if(state.isPage){
      indexCode=indexCode+`\n<div class="my-flex my-flex-end" style="margin-top: 20px">
            <el-pagination
              v-model:currentPage="state.pageInput.CurrentPage"
              v-model:page-size="state.pageInput.PageSize"
              :total="state.total"
              :page-sizes="[10, 20, 50, 100]"
              small
              background
              @size-change="onSizeChange"
              @current-change="onCurrentChange"
              layout="total, sizes, prev, pager, next, jumper"
            />
          </div>`
    }
    indexCode=indexCode+`\n</el-card>
      </el-col>`
  }
  indexCode=indexCode+`\n</el-row>
    </div>
  </template>
  <script setup lang="ts">
  import {onBeforeMount, onMounted, reactive, ref, watch} from "vue";
  import eventBus from "/@/utils/mitt";
  import {Api} from "/@/api/code/api";`
  if(state.isPage&&tabVal.length>0){
    indexCode=indexCode+`\nimport { pageInput,${tabVal[0].belong} } from "/@/api/code/dto";`
  }else if(tabVal.length>0){
    indexCode=indexCode+`\nimport { ${tabVal[0].belong} } from "/@/api/code/dto";`
  }
  indexCode=indexCode+`\n/**数据对象*/
  const state = reactive({
    /**加载显示 */
    loading: false,
    /**条件查询模块 */
      filter: {`
    if(selVal.length>0){
      for(let i=0;i<selVal.length;i++){
        indexCode=indexCode+`\n/**${selVal[i].description} */
        ${selVal[i].name}: "",`
      }
    }
  indexCode=indexCode+`},
  /**表格信息 */`
  if(tabVal.length>0){
    indexCode=indexCode+`\ntableModel: [] as ${tabVal[0].belong},
    /**动态表头 */
    dynamicColumns: [`
    for(let i=0;i<tabVal.length;i++){
      indexCode=indexCode+`\n{ prop: '${tabVal[i].name}', label: '${tabVal[i].description}' },`
    }
    indexCode =indexCode+`],`
  }else{
    indexCode=indexCode+`\ntableModel: [],
    /**动态表头 */
    dynamicColumns: [],`
  }
  if(state.isPage){
    indexCode=indexCode+`\n/**分页标识 */
    pageInput:{
      CurrentPage: 1,
      PageSize: 10,
    } as pageInput,
    /**分页总数 */
    total: 0,`
  }
  indexCode=indexCode+`\n})
  onMounted(() => {
    init()
    eventBus.off('refreshView')
    eventBus.on('refreshView', async () => {
      await init()
    })
    console.log()
  })
  onBeforeMount(() => {
    eventBus.off('refreshView')
  })
  /**
  * 监听变换
  */
  watch(() => {})`
  let isSel=false
  if(selBtn.length>0){
    for(let i=0;i<selBtn.length;i++){
      if(selBtn[i].name==='查询'){
        isSel=true
        indexCode=indexCode+`\n/**条件查询 */
          const onQuery = () => {
          init()
        }
        /**初始化 */
        const init = async () => {
          state.loading = true`
          if(state.isPage){
            indexCode=indexCode+`\nconst res:any = await new Api().getList({...state.pageInput, Filter:state.filter})
            state.total = res?.data?.total ?? 0`
          }else{
            indexCode=indexCode+`\nconst res:any = await new Api().getList({...state.filter})`
          }
          indexCode=indexCode+`\nstate.tableModel = res?.data?.list ?? []
          state.loading = false
        }`
      }else{
        indexCode=indexCode+`\n/**${selBtn[i].name} */
        const ${selBtn[i].method}=()=>{}`
      }
    }
  }
  if(!isSel){
    indexCode=indexCode+`\n/**初始化 */
      const init = async () => {
        state.loading = true
        state.loading = false
      }`
  }
  if(tabBtn.length>0){
    for(let i=0;i<tabBtn.length;i++){
      indexCode=indexCode+`\n/**${tabBtn[i].name} */
      const ${tabBtn[i].method}=(row)=>{}`
    }
  }
  indexCode=indexCode+`\n</`+`script>`+`\n<style scoped lang="scss">
  </style>`
  //console.log(indexCode)
  getCodeFile('api.ts',apiCode)
  getCodeFile('dto.ts',dataCode)
  getCodeFile('index.vue',indexCode)
}
const getCodeFile=(fileName,code) =>{
  const blob = new Blob([code], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  // 创建一个a标签并设置href为新文件的URL
  const downloadLink = document.createElement('a');
  downloadLink.href = url;
  downloadLink.download = fileName; // 设置下载文件名
  // 触发下载
  document.body.appendChild(downloadLink);
  downloadLink.click();
  // 清理
  document.body.removeChild(downloadLink);
  URL.revokeObjectURL(url);
}
</script>

<style scoped lang="scss">
.layout {
  position: absolute;
  left: 0;
  top: 0;
  overflow: hidden;
  padding: 0px 8px 8px 8px;
  display: flex;
  flex-direction: column;
}
</style>
