Skip to content

Commit

Permalink
Merge branch 'app-store'
Browse files Browse the repository at this point in the history
  • Loading branch information
kanyxmo committed May 26, 2024
2 parents 3cd641d + 68eab19 commit d919bb9
Show file tree
Hide file tree
Showing 20 changed files with 1,661 additions and 18 deletions.
8 changes: 7 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="light">

<head>
<meta charset="UTF-8" />
Expand Down Expand Up @@ -41,6 +41,12 @@
</div>
</div>
<style>
:root {
--ui-background: 255 255 255;
}
.dark {
--ui-background: 49 49 50;
}
html, body, #app{
height: 100%; overflow: hidden;
transition-property: filter;
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
"autoprefixer": "^10.4.17",
"axios": "^0.27.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.2",
"dayjs": "^1.11.11",
"echarts": "^5.4.2",
"file2md5": "^1.3.0",
"lodash": "^4.17.21",
"md-editor-v3": "^4.13.5",
"monaco-editor": "^0.33.0",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
Expand All @@ -46,9 +47,9 @@
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"tailwind-config-viewer": "^1.7.3",
"less": "^4.1.3",
"less-loader": "^11.1.4",
"tailwind-config-viewer": "^1.7.3",
"typescript": "^4.7.4",
"vite": "^5.1.4"
}
Expand Down
87 changes: 87 additions & 0 deletions src/api/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { request } from '@/utils/request.js'

/**
* 检查是.env 是否设置了 access_token
*/
export const hasAccessToken = () => {
return request({
url: 'plugin/store/hasAccessToken',
method: 'get',
})
}

/**
* 请求应用列表
*/
export const getAppList = (params) => {
return request({
url: 'plugin/store/index',
method: 'get',
params
})
}

/**
* 已购买应用
*/
export const getPayApp = () => {
return request({
url: 'plugin/store/getPayApp',
method: 'get'
})
}

/**
* 本地应用安装状态
*/
export const getLocalAppInstallList = () => {
return request({
url: 'plugin/store/getLocalAppInstallList',
method: 'get'
})
}

/**
* 详情
*/
export const getDetail = (params) => {
return request({
url: 'plugin/store/detail',
method: 'get',
params
})
}

/**
* 下载应用
*/
export const download = (data) => {
return request({
url: 'plugin/store/download',
method: 'post',
timeout: 500000,
data,
})
}

/**
* 安装应用
*/
export const install = (data) => {
return request({
url: 'plugin/store/install',
method: 'post',
data,
})
}

/**
* 安装应用
*/
export const unInstall = (data) => {
return request({
url: 'plugin/store/unInstall',
method: 'post',
data,
})
}
1 change: 1 addition & 0 deletions src/i18n/en/sys.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default {
chinese: '简体中文',
english: 'English',
search: 'Search',
store: 'App Store',
fullScreen: 'Full Screen',
closeFullScreen: 'Close Full Screen',
changeSkin: 'Change Skin',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/zh_CN/sys.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default {
chinese: '简体中文',
english: 'English',
search: '搜索',
store: '应用市场',
fullScreen: '全屏',
closeFullScreen: '关闭全屏',
changeSkin: '换肤',
Expand Down
11 changes: 9 additions & 2 deletions src/layout/components/ma-operation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
<div class="mr-2 flex justify-end lg:justify-between w-full lg:w-auto">
<a-space class="mr-0 lg:mr-5" size="medium">

<a-tooltip :content="$t('sys.search')">
<a-tooltip :content="$t('sys.store')" v-if="isDev">
<a-button :shape="'circle'" class="hidden lg:inline" @click="$router.push('/store')">
<template #icon>
<icon-apps :size="16" :rotate="45" />
</template>
</a-button>
</a-tooltip>

<a-tooltip :content="$t('sys.search')" >
<a-button :shape="'circle'" @click="() => appStore.searchOpen = true" class="hidden lg:inline">
<template #icon>
<icon-search />
Expand Down Expand Up @@ -102,7 +110,6 @@
const isFullScreen = ref(false)
const showLogoutModal = ref(false)
const isDev = ref(import.meta.env.DEV)
const handleSelect = async (name) => {
if (name === 'userCenter') {
router.push({ name: 'userCenter'})
Expand Down
5 changes: 5 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import router from './router'
import store from './store'
import i18n from '@/i18n'
import directives from './directives'
import dayjs from 'dayjs'
import zhCn from 'dayjs/locale/zh-cn'
import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.locale(zhCn)
dayjs.extend(relativeTime)

// 官方样式
// import '@arco-design/web-vue/dist/arco.css'
Expand Down
7 changes: 6 additions & 1 deletion src/router/homePageRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ const homePageRoutes = [
type: 'M',
},
component: () => import('@/views/userCenter/message.vue'),
}
}, {
name: 'store',
path: '/store',
component: () => import('@/views/appStore/index.vue'),
meta: { title: '应用市场', hidden: true }
},
]

export const homePage = {
Expand Down
1 change: 1 addition & 0 deletions src/store/modules/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const useAppStore = defineStore('app', {

toggleMode(dark) {
this.mode = dark
document.getElementsByTagName('html')[0].className = this.mode
document.body.setAttribute('arco-theme', this.mode)
defaultSetting.mode = this.mode
this.changeColor(this.color)
Expand Down
16 changes: 7 additions & 9 deletions src/store/modules/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,13 @@ const useUserStore = defineStore('user', {
async setApp() {
const appStore = useAppStore()
const setting = typeof this.user.backend_setting === 'string' ? JSON.parse(this.user.backend_setting) : this.user.backend_setting
if (setting) {
appStore.toggleMode(setting.mode)
appStore.toggleMenu(setting.menuCollapse)
appStore.toggleTag(setting.tag)
appStore.changeMenuWidth(setting.menuWidth)
appStore.changeLayout(setting.layout)
appStore.useSkin(setting.skin)
appStore.changeColor(setting.color)
}
appStore.toggleMode(setting?.mode ?? appStore.mode)
appStore.toggleMenu(setting?.menuCollapse ?? appStore.menuCollapse)
appStore.toggleTag(setting?.tag ?? appStore.tag)
appStore.changeMenuWidth(setting?.menuWidth ?? appStore.menuWidth)
appStore.changeLayout(setting?.layout ?? appStore.layout)
appStore.useSkin(setting?.skin ?? appStore.skin)
appStore.changeColor(setting?.color ?? appStore.color)
}
}

Expand Down
23 changes: 23 additions & 0 deletions src/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,27 @@ export const loadCss = (href, callback) => {
}
}
document.body.appendChild(s)
}

export const discount = (discount, price) => {
return (price * ( (discount === '0.00' || discount === 0) ? 10 : discount ) / 10).toFixed(2)
}


export const versionCompare = (v1, v2) => {
// 将版本号转换成数字数组
v1 = v1.split('.');
v2 = v2.split('.');
// 对齐版本号的长度
while (v1.length < v2.length) v1.push('0');
while (v2.length < v1.length) v2.push('0');
// 转换成数字数组
v1 = v1.map(Number);
v2 = v2.map(Number);

for (let i = 0; i < v1.length; i++) {
if (v1[i] < v2[i]) return -1; // v1 < v2
if (v1[i] > v2[i]) return 1; // v1 > v2
}
return 0; // v1 == v2
}
95 changes: 95 additions & 0 deletions src/views/appStore/components/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script setup>
import { isUndefined } from "lodash"
import dayjs from "dayjs"
import {discount} from "@/utils/common"
const props = defineProps({
appList: Array,
myAppList: Array,
localInstallList: Object,
isOnlyShowLocalApp: Boolean,
})
const emit = defineEmits(['onOpenDetail'])
const openDetailModal = (item) => {
emit('onOpenDetail', item)
}
const checkInstallStatus = (space, identifier) => {
const name = `${space}/${identifier}`
return !isUndefined(props.localInstallList[name]) && props.localInstallList[name].status
}
</script>

<template>
<div
class="h-auto relative mt-8 sm:mt-0 border border-gray-150 dark:border-gray-600 hover:border-primary-500 dark:hover:border-gray-400 rounded-md top-0 hover:shadow-md hover:-top-1 dark:shadow-gray-600 transition-all duration-300 group overflow-hidden"
v-for="(item, idx) in props.appList"
>
<div
class="absolute z-10 w-auto bg-red-600 text-white px-5 origin-center rotate-45 -right-5 top-2.5"
v-if="myAppList.includes(item.identifier) && ! props.isOnlyShowLocalApp"
>
已购买
</div>
<div
class="absolute z-10 w-32 text-center bg-lime-600 text-white px-5 origin-center rotate-45 -right-7 top-6"
v-if="checkInstallStatus(item.space, item.identifier) && ! props.isOnlyShowLocalApp"
>
已安装
</div>
<div
class="absolute z-10 w-auto bg-green-600 text-white px-5 origin-center rotate-45 -right-6 top-3.5 text-sm"
v-if="props.isOnlyShowLocalApp && ! isUndefined(props.localInstallList[`${item.space}/${item.identifier}`])"
>
本地应用
</div>
<a class="h-44 w-full" href="javascript:" @click="openDetailModal(item)">
<div class="relative">
<img
class="!rounded-b-none !rounded-t-md pointer-events-none w-full object-cover sm:rounded-md h-48 transform transition-transform duration-200 group-hover:scale-105"
:src="item.homepage[0]"
/>
<div class="absolute bottom-2 right-2 space-x-2">
<a-tag :color="tag.color === 'primary' ? 'arcoblue' : tag.color" v-for="tag in item.tags">{{ tag.name }}</a-tag>
</div>
</div>
</a>
<div class="p-3 pb-2">
<div class="grid-cols-2 grid">
<div class="text-sm">
<a class="hover:underline" href="javascript:" @click="openDetailModal(item)">{{ item.name }}</a>
</div>
<div class="text-xs leading-5 text-gray-500 dark:text-gray-400 text-right">
{{ `${dayjs(item.created_at).fromNow()}更新` }}
</div>
</div>
<div class="text-xs mt-1 text-gray-500 dark:text-gray-400">
{{ item.description }}
</div>
<div class="text-xs mt-5 grid grid-cols-2">
<div class="leading-6 text-gray-700 dark:text-gray-300"><span class="hover:underline">X.Mo</span></div>
<div class="text-right">
<a-tag v-if="item.auth.type === 0" color="green">免费</a-tag>
<div v-else-if="item.auth.type === 1">
<div class="flex items-center justify-end leading-6">
<div class="line-through text-gray-400" v-if="item.auth.integral_discount !== '0.00'">{{ item.auth.integral_quota }} 积分</div>
<div class="ml-2 text-emerald-700">{{ discount(item.auth.integral_discount, item.auth.integral_quota) }} 积分</div>
</div>
</div>
<div v-else-if="item.auth.type === 2">
<div class="flex items-center justify-end leading-6">
<div class="line-through text-gray-400" v-if="item.auth.basic_discount !== '0.00'">¥{{ item.auth.basic_quota }}</div>
<div class="ml-2 text-blue-600">¥{{ discount(item.auth.basic_discount, item.auth.basic_quota) }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

<style scoped>
</style>
Loading

0 comments on commit d919bb9

Please sign in to comment.