mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	feat: add draw same image for midjourney page
This commit is contained in:
		@@ -35,38 +35,40 @@
 | 
				
			|||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item .image .el-image {
 | 
					.page-images-wall .inner .waterfall .list-item .image .el-image {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
  transition: transform 0.3s;
 | 
					  transition: transform 0.3s;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item .prompt {
 | 
					.page-images-wall .inner .waterfall .list-item .opt {
 | 
				
			||||||
  display: none;
 | 
					  display: none;
 | 
				
			||||||
  position: absolute;
 | 
					  position: absolute;
 | 
				
			||||||
  width: 180px;
 | 
					  width: 100%;
 | 
				
			||||||
  bottom: 0;
 | 
					  bottom: 0;
 | 
				
			||||||
  left: 0;
 | 
					  left: 0;
 | 
				
			||||||
  color: #fff;
 | 
					  color: #fff;
 | 
				
			||||||
  padding: 10px 10px 20px 10px;
 | 
					  padding: 8px 10px;
 | 
				
			||||||
  line-height: 1.2;
 | 
					  line-height: 1.2;
 | 
				
			||||||
  border-top-right-radius: 10px;
 | 
					  border-top-right-radius: 10px;
 | 
				
			||||||
  background-color: rgba(10,10,10,0.7);
 | 
					  background-color: rgba(10,10,10,0.7);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item .prompt span {
 | 
					.page-images-wall .inner .waterfall .list-item .opt span {
 | 
				
			||||||
  word-break: break-all;
 | 
					  word-break: break-all;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item .prompt .el-icon {
 | 
					.page-images-wall .inner .waterfall .list-item .opt .el-icon,
 | 
				
			||||||
  position: absolute;
 | 
					.page-images-wall .inner .waterfall .list-item .opt .iconfont {
 | 
				
			||||||
  bottom: 10px;
 | 
					  top: 2px;
 | 
				
			||||||
  right: 10px;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  border: 1px solid #fff;
 | 
					  border: 1px solid #fff;
 | 
				
			||||||
  border-radius: 5px;
 | 
					  border-radius: 5px;
 | 
				
			||||||
  padding: 2px;
 | 
					  padding: 2px;
 | 
				
			||||||
  font-size: 12px;
 | 
					  font-size: 16px;
 | 
				
			||||||
 | 
					  margin-right: 10px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item .prompt .el-icon:hover {
 | 
					.page-images-wall .inner .waterfall .list-item .opt .el-icon:hover,
 | 
				
			||||||
  background-color: #999;
 | 
					.page-images-wall .inner .waterfall .list-item .opt .iconfont:hover {
 | 
				
			||||||
 | 
					  background-color: #444;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.page-images-wall .inner .waterfall .list-item:hover .prompt {
 | 
					.page-images-wall .inner .waterfall .list-item:hover .opt {
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
  animation: expandUp 0.3s ease-in-out forwards;
 | 
					  animation: expandUp 0.3s ease-in-out forwards;
 | 
				
			||||||
  transform-origin: bottom center;
 | 
					  transform-origin: bottom center;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,19 +52,20 @@
 | 
				
			|||||||
          overflow hidden
 | 
					          overflow hidden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          .el-image {
 | 
					          .el-image {
 | 
				
			||||||
 | 
					            width 100%
 | 
				
			||||||
            transition: transform 0.3s;
 | 
					            transition: transform 0.3s;
 | 
				
			||||||
            cursor pointer
 | 
					            cursor pointer
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .prompt {
 | 
					        .opt {
 | 
				
			||||||
          display none
 | 
					          display none
 | 
				
			||||||
          position absolute
 | 
					          position absolute
 | 
				
			||||||
          width 180px
 | 
					          width 100%
 | 
				
			||||||
          bottom 0
 | 
					          bottom 0
 | 
				
			||||||
          left 0
 | 
					          left 0
 | 
				
			||||||
          color #ffffff
 | 
					          color #ffffff
 | 
				
			||||||
          padding 10px 10px 20px 10px
 | 
					          padding 8px 10px
 | 
				
			||||||
          line-height 1.2
 | 
					          line-height 1.2
 | 
				
			||||||
          border-top-right-radius 10px
 | 
					          border-top-right-radius 10px
 | 
				
			||||||
          background-color rgba(10, 10, 10, 0.7)
 | 
					          background-color rgba(10, 10, 10, 0.7)
 | 
				
			||||||
@@ -73,24 +74,23 @@
 | 
				
			|||||||
            word-break break-all
 | 
					            word-break break-all
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          .el-icon {
 | 
					          .el-icon, .iconfont {
 | 
				
			||||||
            position absolute
 | 
					            top 2px
 | 
				
			||||||
            bottom 10px
 | 
					 | 
				
			||||||
            right 10px
 | 
					 | 
				
			||||||
            cursor pointer
 | 
					            cursor pointer
 | 
				
			||||||
            border 1px solid #ffffff
 | 
					            border 1px solid #ffffff
 | 
				
			||||||
            border-radius 5px
 | 
					            border-radius 5px
 | 
				
			||||||
            padding 2px
 | 
					            padding 2px
 | 
				
			||||||
            font-size 12px;
 | 
					            font-size 16px;
 | 
				
			||||||
 | 
					            margin-right 10px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            &:hover {
 | 
					            &:hover {
 | 
				
			||||||
              background-color #999999
 | 
					              background-color #444444
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &:hover {
 | 
					        &:hover {
 | 
				
			||||||
          .prompt {
 | 
					          .opt {
 | 
				
			||||||
            display block
 | 
					            display block
 | 
				
			||||||
            animation: expandUp 0.3s ease-in-out forwards;
 | 
					            animation: expandUp 0.3s ease-in-out forwards;
 | 
				
			||||||
            transform-origin: bottom center;
 | 
					            transform-origin: bottom center;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -555,6 +555,7 @@ const options = [
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter()
 | 
				
			||||||
const params = ref({
 | 
					const params = ref({
 | 
				
			||||||
  task_type: "image",
 | 
					  task_type: "image",
 | 
				
			||||||
  rate: rates[0].value,
 | 
					  rate: rates[0].value,
 | 
				
			||||||
@@ -565,7 +566,7 @@ const params = ref({
 | 
				
			|||||||
  img_arr: [],
 | 
					  img_arr: [],
 | 
				
			||||||
  raw: false,
 | 
					  raw: false,
 | 
				
			||||||
  weight: 0.25,
 | 
					  weight: 0.25,
 | 
				
			||||||
  prompt: "",
 | 
					  prompt: router.currentRoute.value.params["prompt"] ?? "",
 | 
				
			||||||
  neg_prompt: "",
 | 
					  neg_prompt: "",
 | 
				
			||||||
  tile: false,
 | 
					  tile: false,
 | 
				
			||||||
  quality: 0
 | 
					  quality: 0
 | 
				
			||||||
@@ -577,7 +578,6 @@ const activeName = ref('image')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const runningJobs = ref([])
 | 
					const runningJobs = ref([])
 | 
				
			||||||
const finishedJobs = ref([])
 | 
					const finishedJobs = ref([])
 | 
				
			||||||
const router = useRouter()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const socket = ref(null)
 | 
					const socket = ref(null)
 | 
				
			||||||
const imgCalls = ref(0)
 | 
					const imgCalls = ref(0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
      <div class="waterfall" :style="{ height:listBoxHeight + 'px' }" id="waterfall-box">
 | 
					      <div class="waterfall" :style="{ height:listBoxHeight + 'px' }" id="waterfall-box">
 | 
				
			||||||
        <v3-waterfall v-if="imgType === 'mj'"
 | 
					        <v3-waterfall v-if="imgType === 'mj'"
 | 
				
			||||||
                      id="waterfall"
 | 
					                      id="waterfall"
 | 
				
			||||||
                      :list="list"
 | 
					                      :list="data['mj']"
 | 
				
			||||||
                      srcKey="img_thumb"
 | 
					                      srcKey="img_thumb"
 | 
				
			||||||
                      :gap="12"
 | 
					                      :gap="12"
 | 
				
			||||||
                      :bottomGap="-5"
 | 
					                      :bottomGap="-5"
 | 
				
			||||||
@@ -46,11 +46,26 @@
 | 
				
			|||||||
                  </template>
 | 
					                  </template>
 | 
				
			||||||
                </el-image>
 | 
					                </el-image>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <div class="prompt">
 | 
					              <div class="opt">
 | 
				
			||||||
                <span>{{ slotProp.item.prompt }}</span>
 | 
					                <el-tooltip
 | 
				
			||||||
                <el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt">
 | 
					                    class="box-item"
 | 
				
			||||||
                  <DocumentCopy/>
 | 
					                    effect="light"
 | 
				
			||||||
                </el-icon>
 | 
					                    content="复制提示词"
 | 
				
			||||||
 | 
					                    placement="top"
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                  <el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt">
 | 
				
			||||||
 | 
					                    <DocumentCopy/>
 | 
				
			||||||
 | 
					                  </el-icon>
 | 
				
			||||||
 | 
					                </el-tooltip>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <el-tooltip
 | 
				
			||||||
 | 
					                    class="box-item"
 | 
				
			||||||
 | 
					                    effect="light"
 | 
				
			||||||
 | 
					                    content="画同款"
 | 
				
			||||||
 | 
					                    placement="top"
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					                  <i class="iconfont icon-palette-pen" @click="drawSameMj(slotProp.item)"></i>
 | 
				
			||||||
 | 
					                </el-tooltip>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
@@ -58,7 +73,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <v3-waterfall v-else
 | 
					        <v3-waterfall v-else
 | 
				
			||||||
                      id="waterfall"
 | 
					                      id="waterfall"
 | 
				
			||||||
                      :list="list"
 | 
					                      :list="data['sd']"
 | 
				
			||||||
                      srcKey="img_thumb"
 | 
					                      srcKey="img_thumb"
 | 
				
			||||||
                      :gap="12"
 | 
					                      :gap="12"
 | 
				
			||||||
                      :bottomGap="-5"
 | 
					                      :bottomGap="-5"
 | 
				
			||||||
@@ -87,13 +102,6 @@
 | 
				
			|||||||
                  </template>
 | 
					                  </template>
 | 
				
			||||||
                </el-image>
 | 
					                </el-image>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
              <div class="prompt">
 | 
					 | 
				
			||||||
                <span>{{ slotProp.item.prompt }}</span>
 | 
					 | 
				
			||||||
                <el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt">
 | 
					 | 
				
			||||||
                  <DocumentCopy/>
 | 
					 | 
				
			||||||
                </el-icon>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
        </v3-waterfall>
 | 
					        </v3-waterfall>
 | 
				
			||||||
@@ -223,7 +231,7 @@
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="copy-params">
 | 
					            <div class="copy-params">
 | 
				
			||||||
              <el-button type="primary" round @click="copyParams(item)">画一张同款的</el-button>
 | 
					              <el-button type="primary" round @click="drawSameSd(item)">画一张同款的</el-button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
@@ -242,7 +250,10 @@ import {ElMessage} from "element-plus";
 | 
				
			|||||||
import Clipboard from "clipboard";
 | 
					import Clipboard from "clipboard";
 | 
				
			||||||
import {useRouter} from "vue-router";
 | 
					import {useRouter} from "vue-router";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const list = ref([])
 | 
					const data = ref({
 | 
				
			||||||
 | 
					  "mj": [],
 | 
				
			||||||
 | 
					  "sd": []
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
const loading = ref(true)
 | 
					const loading = ref(true)
 | 
				
			||||||
const isOver = ref(false)
 | 
					const isOver = ref(false)
 | 
				
			||||||
const imgType = ref("mj") // 图片类别
 | 
					const imgType = ref("mj") // 图片类别
 | 
				
			||||||
@@ -264,7 +275,7 @@ window.onresize = () => {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const page = ref(0)
 | 
					const page = ref(0)
 | 
				
			||||||
const pageSize = ref(20)
 | 
					const pageSize = ref(15)
 | 
				
			||||||
// 获取下一页数据
 | 
					// 获取下一页数据
 | 
				
			||||||
const getNext = () => {
 | 
					const getNext = () => {
 | 
				
			||||||
  if (isOver.value) {
 | 
					  if (isOver.value) {
 | 
				
			||||||
@@ -286,15 +297,15 @@ const getNext = () => {
 | 
				
			|||||||
    for (let i = 0; i < imageList.length; i++) {
 | 
					    for (let i = 0; i < imageList.length; i++) {
 | 
				
			||||||
      imageList[i]["img_thumb"] = imageList[i]["img_url"] + "?imageView2/4/w/300/h/0/q/75"
 | 
					      imageList[i]["img_thumb"] = imageList[i]["img_url"] + "?imageView2/4/w/300/h/0/q/75"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (list.value.length === 0) {
 | 
					    if (data.value[imgType.value].length === 0) {
 | 
				
			||||||
      list.value = imageList
 | 
					      data.value[imgType.value] = imageList
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (imageList.length < pageSize.value) {
 | 
					    if (imageList.length < pageSize.value) {
 | 
				
			||||||
      isOver.value = true
 | 
					      isOver.value = true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    list.value = list.value.concat(imageList)
 | 
					    data.value[imgType.value] = data.value[imgType.value].concat(imageList)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }).catch(e => {
 | 
					  }).catch(e => {
 | 
				
			||||||
    ElMessage.error("获取图片失败:" + e.message)
 | 
					    ElMessage.error("获取图片失败:" + e.message)
 | 
				
			||||||
@@ -317,7 +328,10 @@ onMounted(() => {
 | 
				
			|||||||
const changeImgType = () => {
 | 
					const changeImgType = () => {
 | 
				
			||||||
  document.getElementById('waterfall-box').scrollTo(0, 0)
 | 
					  document.getElementById('waterfall-box').scrollTo(0, 0)
 | 
				
			||||||
  page.value = 0
 | 
					  page.value = 0
 | 
				
			||||||
  list.value = []
 | 
					  data.value = {
 | 
				
			||||||
 | 
					    "mj": [],
 | 
				
			||||||
 | 
					    "sd": []
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  loading.value = true
 | 
					  loading.value = true
 | 
				
			||||||
  isOver.value = false
 | 
					  isOver.value = false
 | 
				
			||||||
  nextTick(() => getNext())
 | 
					  nextTick(() => getNext())
 | 
				
			||||||
@@ -330,10 +344,13 @@ const showTask = (row) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter()
 | 
					const router = useRouter()
 | 
				
			||||||
const copyParams = (row) => {
 | 
					const drawSameSd = (row) => {
 | 
				
			||||||
  router.push({name: "image-sd", params: {copyParams: JSON.stringify(row.params)}})
 | 
					  router.push({name: "image-sd", params: {copyParams: JSON.stringify(row.params)}})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const drawSameMj = (row) => {
 | 
				
			||||||
 | 
					  router.push({name: "image-mj", params: {prompt: row.prompt}})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="stylus">
 | 
					<style lang="stylus">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user