解决冲突

v1.0.0
于肖磊 2024-08-19 17:20:24 +08:00
commit e477c59dde
30 changed files with 1006 additions and 447 deletions

View File

@ -1,6 +1,6 @@
## 模拟环境
NODE_ENV='staging'
VITE_APP_TITLE = 'vue3-element-admin'
VITE_APP_TITLE = 'shopxo'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/prod--api'

1
.gitignore vendored
View File

@ -28,4 +28,5 @@ coverage
*.njsproj
*.sln
*.sw?
pnpm-lock.yaml

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 ShopXO免费开源商城DIY
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,3 +1,4 @@
![输入图片说明](%E8%A3%85%E4%BF%AE-%E6%A0%87%E9%A2%981-%E9%A1%B5%E9%9D%A2%E8%AE%BE%E7%BD%AE.png)
# vue3-vite
This template should help get you started developing with Vue 3 in Vite.

View File

@ -1,57 +1,57 @@
{
"name": "shopxo-diy",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"build-pro": "vite build --mode production",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@types/dompurify": "^3.0.5",
"@vueuse/core": "^10.2.1",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.4.0",
"dompurify": "^3.1.6",
"element-plus": "^2.3.7",
"pinia": "^2.1.3",
"qrcode": "^1.5.3",
"swiper": "^11.1.5",
"terser": "^5.31.5",
"tsparticles": "^2.11.0",
"unocss": "^0.53.5",
"vue": "^3.3.4",
"vue-draggable-plus": "^0.5.0",
"vue-router": "^4.0.13",
"vue3-draggable-resizable": "^1.6.5"
},
"devDependencies": {
"@iconify-json/ep": "^1.1.11",
"@rushstack/eslint-patch": "^1.2.0",
"@tsconfig/node18": "^2.0.1",
"@types/sortablejs": "^1.15.8",
"@vitejs/plugin-vue": "^4.2.3",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/tsconfig": "^0.4.0",
"eslint": "^8.39.0",
"eslint-plugin-vue": "^9.11.0",
"fast-glob": "3.2.11",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.0",
"sass": "^1.63.6",
"typescript": "~5.0.4",
"unplugin-auto-import": "^0.16.6",
"unplugin-icons": "^0.16.3",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.3.9",
"vite-plugin-svg-icons": "2.0.1",
"vue-tsc": "^1.6.5",
"vue3-particles": "^2.10.1"
}
"name": "shopxo-diy",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build --mode development",
"preview": "vite preview",
"build-pro": "vite build --mode production",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@types/dompurify": "^3.0.5",
"@vueuse/core": "^10.2.1",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.4.0",
"dompurify": "^3.1.6",
"element-plus": "^2.3.7",
"pinia": "^2.1.3",
"qrcode": "^1.5.3",
"swiper": "^11.1.5",
"terser": "^5.31.5",
"tsparticles": "^2.11.0",
"unocss": "^0.53.5",
"vue": "^3.3.4",
"vue-draggable-plus": "^0.5.0",
"vue-router": "^4.0.13",
"vue3-draggable-resizable": "^1.6.5"
},
"devDependencies": {
"@iconify-json/ep": "^1.1.11",
"@rushstack/eslint-patch": "^1.2.0",
"@tsconfig/node18": "^2.0.1",
"@types/sortablejs": "^1.15.8",
"@vitejs/plugin-vue": "^4.2.3",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/tsconfig": "^0.4.0",
"eslint": "^8.39.0",
"eslint-plugin-vue": "^9.11.0",
"fast-glob": "3.2.11",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.0",
"sass": "^1.63.6",
"typescript": "~5.0.4",
"unplugin-auto-import": "^0.16.6",
"unplugin-icons": "^0.16.3",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.3.9",
"vite-plugin-svg-icons": "2.0.1",
"vue-tsc": "^1.6.5",
"vue3-particles": "^2.10.1"
}
}

View File

@ -1,23 +0,0 @@
/**
*
*/
export interface LoginData {
/**
*
*/
username: string;
/**
*
*/
password: string;
/**
* key
*/
// verifyCodeKey?: string;
/**
*
*/
// verifyCode?: string;
}

33
src/api/url-value.ts Normal file
View File

@ -0,0 +1,33 @@
import request from '@/utils/request';
class UrlValueAPI {
/** 链接初始化接口 */
static getInit() {
return request({
url: `diyapi/linkinit`,
method: 'post',
});
}
}
export default UrlValueAPI;
// 分类树结构
export interface Tree {
/** 主键 */
id: string;
/** 父级id */
pid: string;
/** 名称 */
name: string;
/** 路径 */
path: string;
/** 是否开启 */
is_enable: Number;
/** 排序 */
sort: number;
/** 下级 */
items?: Tree[];
/** 图标 */
icon?: string;
}

View File

@ -54,6 +54,132 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe635;</span>
<div class="name">三点</div>
<div class="code-name">&amp;#xe635;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe795;</span>
<div class="name">编辑 (2)</div>
<div class="code-name">&amp;#xe795;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe74a;</span>
<div class="name">问号</div>
<div class="code-name">&amp;#xe74a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe7b6;</span>
<div class="name">双箭头 右</div>
<div class="code-name">&amp;#xe7b6;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe782;</span>
<div class="name">EXE</div>
<div class="code-name">&amp;#xe782;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe786;</span>
<div class="name">TXT</div>
<div class="code-name">&amp;#xe786;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe794;</span>
<div class="name">1个</div>
<div class="code-name">&amp;#xe794;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe789;</span>
<div class="name">横2</div>
<div class="code-name">&amp;#xe789;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78a;</span>
<div class="name">4x4</div>
<div class="code-name">&amp;#xe78a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78b;</span>
<div class="name">左1右2</div>
<div class="code-name">&amp;#xe78b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78c;</span>
<div class="name">竖3</div>
<div class="code-name">&amp;#xe78c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78d;</span>
<div class="name">上2下1</div>
<div class="code-name">&amp;#xe78d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78e;</span>
<div class="name">左1右上1右下2</div>
<div class="code-name">&amp;#xe78e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe78f;</span>
<div class="name">上1下2</div>
<div class="code-name">&amp;#xe78f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe790;</span>
<div class="name">田字格</div>
<div class="code-name">&amp;#xe790;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe792;</span>
<div class="name">上2下3</div>
<div class="code-name">&amp;#xe792;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe793;</span>
<div class="name">左2右1</div>
<div class="code-name">&amp;#xe793;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe77b;</span>
<div class="name">竖2</div>
<div class="code-name">&amp;#xe77b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe72b;</span>
<div class="name">上传</div>
<div class="code-name">&amp;#xe72b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe741;</span>
<div class="name">进销存对号</div>
<div class="code-name">&amp;#xe741;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe791;</span>
<div class="name">购物车1</div>
<div class="code-name">&amp;#xe791;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe787;</span>
<div class="name">PDF</div>
@ -72,12 +198,6 @@
<div class="code-name">&amp;#xe785;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe786;</span>
<div class="name">THT</div>
<div class="code-name">&amp;#xe786;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe783;</span>
<div class="name">vsd</div>
@ -120,12 +240,6 @@
<div class="code-name">&amp;#xe781;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe782;</span>
<div class="name">EHE</div>
<div class="code-name">&amp;#xe782;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe77c;</span>
<div class="name">文件1</div>
@ -426,10 +540,10 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1721714218560') format('woff2'),
url('iconfont.woff?t=1721714218560') format('woff'),
url('iconfont.ttf?t=1721714218560') format('truetype'),
url('iconfont.svg?t=1721714218560#iconfont') format('svg');
src: url('iconfont.woff2?t=1724054334931') format('woff2'),
url('iconfont.woff?t=1724054334931') format('woff'),
url('iconfont.ttf?t=1724054334931') format('truetype'),
url('iconfont.svg?t=1724054334931#iconfont') format('svg');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -455,6 +569,195 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-ellipsis"></span>
<div class="name">
三点
</div>
<div class="code-name">.icon-ellipsis
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-commodity-edit"></span>
<div class="name">
编辑 (2)
</div>
<div class="code-name">.icon-commodity-edit
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tips"></span>
<div class="name">
问号
</div>
<div class="code-name">.icon-tips
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-arrow-right-dbl"></span>
<div class="name">
双箭头 右
</div>
<div class="code-name">.icon-arrow-right-dbl
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-EXE"></span>
<div class="name">
EXE
</div>
<div class="code-name">.icon-EXE
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-txt"></span>
<div class="name">
TXT
</div>
<div class="code-name">.icon-txt
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-a-1ge"></span>
<div class="name">
1个
</div>
<div class="code-name">.icon-a-1ge
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-heng2"></span>
<div class="name">
横2
</div>
<div class="code-name">.icon-heng2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-a-4x4"></span>
<div class="name">
4x4
</div>
<div class="code-name">.icon-a-4x4
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zuo1you2"></span>
<div class="name">
左1右2
</div>
<div class="code-name">.icon-zuo1you2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shu3"></span>
<div class="name">
竖3
</div>
<div class="code-name">.icon-shu3
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shang2xia1"></span>
<div class="name">
上2下1
</div>
<div class="code-name">.icon-shang2xia1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zuo1youshang1youxia2"></span>
<div class="name">
左1右上1右下2
</div>
<div class="code-name">.icon-zuo1youshang1youxia2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shang1xia2"></span>
<div class="name">
上1下2
</div>
<div class="code-name">.icon-shang1xia2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tianzige"></span>
<div class="name">
田字格
</div>
<div class="code-name">.icon-tianzige
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shang2xia3"></span>
<div class="name">
上2下3
</div>
<div class="code-name">.icon-shang2xia3
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zuo2you1"></span>
<div class="name">
左2右1
</div>
<div class="code-name">.icon-zuo2you1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shu2"></span>
<div class="name">
竖2
</div>
<div class="code-name">.icon-shu2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-upload"></span>
<div class="name">
上传
</div>
<div class="code-name">.icon-upload
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-true"></span>
<div class="name">
进销存对号
</div>
<div class="code-name">.icon-true
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-cart"></span>
<div class="name">
购物车1
</div>
<div class="code-name">.icon-cart
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-pdf"></span>
<div class="name">
@ -482,15 +785,6 @@
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tht"></span>
<div class="name">
THT
</div>
<div class="code-name">.icon-tht
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-vsd"></span>
<div class="name">
@ -554,15 +848,6 @@
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-ehe"></span>
<div class="name">
EHE
</div>
<div class="code-name">.icon-ehe
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-file"></span>
<div class="name">
@ -1013,6 +1298,174 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-ellipsis"></use>
</svg>
<div class="name">三点</div>
<div class="code-name">#icon-ellipsis</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-commodity-edit"></use>
</svg>
<div class="name">编辑 (2)</div>
<div class="code-name">#icon-commodity-edit</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tips"></use>
</svg>
<div class="name">问号</div>
<div class="code-name">#icon-tips</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-arrow-right-dbl"></use>
</svg>
<div class="name">双箭头 右</div>
<div class="code-name">#icon-arrow-right-dbl</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-EXE"></use>
</svg>
<div class="name">EXE</div>
<div class="code-name">#icon-EXE</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-txt"></use>
</svg>
<div class="name">TXT</div>
<div class="code-name">#icon-txt</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-a-1ge"></use>
</svg>
<div class="name">1个</div>
<div class="code-name">#icon-a-1ge</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-heng2"></use>
</svg>
<div class="name">横2</div>
<div class="code-name">#icon-heng2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-a-4x4"></use>
</svg>
<div class="name">4x4</div>
<div class="code-name">#icon-a-4x4</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zuo1you2"></use>
</svg>
<div class="name">左1右2</div>
<div class="code-name">#icon-zuo1you2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shu3"></use>
</svg>
<div class="name">竖3</div>
<div class="code-name">#icon-shu3</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shang2xia1"></use>
</svg>
<div class="name">上2下1</div>
<div class="code-name">#icon-shang2xia1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zuo1youshang1youxia2"></use>
</svg>
<div class="name">左1右上1右下2</div>
<div class="code-name">#icon-zuo1youshang1youxia2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shang1xia2"></use>
</svg>
<div class="name">上1下2</div>
<div class="code-name">#icon-shang1xia2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tianzige"></use>
</svg>
<div class="name">田字格</div>
<div class="code-name">#icon-tianzige</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shang2xia3"></use>
</svg>
<div class="name">上2下3</div>
<div class="code-name">#icon-shang2xia3</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zuo2you1"></use>
</svg>
<div class="name">左2右1</div>
<div class="code-name">#icon-zuo2you1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shu2"></use>
</svg>
<div class="name">竖2</div>
<div class="code-name">#icon-shu2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-upload"></use>
</svg>
<div class="name">上传</div>
<div class="code-name">#icon-upload</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-true"></use>
</svg>
<div class="name">进销存对号</div>
<div class="code-name">#icon-true</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-cart"></use>
</svg>
<div class="name">购物车1</div>
<div class="code-name">#icon-cart</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-pdf"></use>
@ -1037,14 +1490,6 @@
<div class="code-name">#icon-word</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tht"></use>
</svg>
<div class="name">THT</div>
<div class="code-name">#icon-tht</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-vsd"></use>
@ -1101,14 +1546,6 @@
<div class="code-name">#icon-excel</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-ehe"></use>
</svg>
<div class="name">EHE</div>
<div class="code-name">#icon-ehe</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-file"></use>

View File

@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont"; /* Project id 4607934 */
src: url('iconfont.woff2?t=1723603502806') format('woff2'),
url('iconfont.woff?t=1723603502806') format('woff'),
url('iconfont.ttf?t=1723603502806') format('truetype'),
url('iconfont.svg?t=1723603502806#iconfont') format('svg');
src: url('iconfont.woff2?t=1724054334931') format('woff2'),
url('iconfont.woff?t=1724054334931') format('woff'),
url('iconfont.ttf?t=1724054334931') format('truetype'),
url('iconfont.svg?t=1724054334931#iconfont') format('svg');
}
.iconfont {
@ -14,6 +14,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-ellipsis:before {
content: "\e635";
}
.icon-commodity-edit:before {
content: "\e795";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "web端",
"glyphs": [
{
"icon_id": "39793709",
"name": "三点",
"font_class": "ellipsis",
"unicode": "e635",
"unicode_decimal": 58933
},
{
"icon_id": "41451474",
"name": "编辑 (2)",

View File

@ -14,6 +14,8 @@
/>
<missing-glyph />
<glyph glyph-name="ellipsis" unicode="&#58933;" d="M169.319538 289.773795a94.226205 94.226205 0 1 0 0 188.45241 94.226205 94.226205 0 0 0 0-188.45241z m342.680462 0a94.226205 94.226205 0 1 0 0 188.45241 94.226205 94.226205 0 0 0 0-188.45241z m342.680462 0a94.226205 94.226205 0 1 0 0 188.45241 94.226205 94.226205 0 0 0 0-188.45241z" horiz-adv-x="1024" />
<glyph glyph-name="commodity-edit" unicode="&#59285;" d="M439.9616 156.5184a20.1216 20.1216 0 0 0-13.0048 4.7104l-139.264 113.664a20.6336 20.6336 0 0 0-2.56 29.5424l358.0416 417.792a20.5824 20.5824 0 0 0 28.8256 2.56l139.2128-113.7664a20.6336 20.6336 0 0 0 2.6112-29.4912l-358.0416-417.792a21.0944 21.0944 0 0 0-15.8208-7.2192z m-109.6704 137.1648l107.0592-87.552 331.2128 386.2528-107.1104 87.552-331.1616-386.2528zM259.072 77.2096a20.8384 20.8384 0 0 0-20.48 24.064l29.9008 183.3472a20.7872 20.7872 0 0 0 40.96-6.656l-24.064-147.8656 140.1856 53.0944a20.7872 20.7872 0 0 0 14.7456-38.7584l-173.7728-65.9456a20.736 20.736 0 0 0-7.424-1.28zM512.0512-128C229.7344-128 0 101.7344 0 384.0512 0 666.4192 229.7344 896 512.0512 896c282.368 0 512.0512-229.7344 512.0512-512.0512 0-282.368-229.6832-511.9488-512-511.9488z m0 982.5792C252.6208 854.5792 41.5232 643.584 41.5232 384.0512c0-259.4304 211.0976-470.528 470.528-470.528 259.4816 0 470.528 211.0976 470.528 470.528 0 259.4816-211.0464 470.528-470.528 470.528z" horiz-adv-x="1024" />
<glyph glyph-name="tips" unicode="&#59210;" d="M512 814.592a422.4 422.4 0 1 1 422.4-422.4A422.4 422.4 0 0 1 512 814.592z m26.624-629.76a45.056 45.056 0 0 0-31.232-12.288 42.496 42.496 0 0 0-31.232 12.8 41.984 41.984 0 0 0-12.8 30.72 39.424 39.424 0 0 0 12.8 30.72 42.496 42.496 0 0 0 31.232 12.288 43.008 43.008 0 0 0 31.744-12.288 39.424 39.424 0 0 0 12.8-30.72 43.008 43.008 0 0 0-13.312-31.744z m87.04 235.52a617.472 617.472 0 0 0-51.2-47.104 93.184 93.184 0 0 1-25.088-31.232 80.896 80.896 0 0 1-9.728-39.936v-10.24h-64v10.24a119.808 119.808 0 0 0 12.288 57.344A311.296 311.296 0 0 0 555.52 435.2l10.24 11.264a71.168 71.168 0 0 1 16.896 44.032A69.632 69.632 0 0 1 563.2 537.6a69.632 69.632 0 0 1-51.2 17.92 67.072 67.072 0 0 1-58.88-26.112 102.4 102.4 0 0 1-16.384-61.44h-61.44a140.288 140.288 0 0 0 37.888 102.4 140.8 140.8 0 0 0 104.96 38.4 135.68 135.68 0 0 0 96.256-29.184 108.032 108.032 0 0 0 36.352-86.528 116.736 116.736 0 0 0-25.088-73.216z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -57,7 +57,7 @@
</span>
</template>
</el-dialog>
<el-dialog v-model="hot_dialog_visible" width="560" append-to-body @close="hot_close_event">
<el-dialog v-model="hot_dialog_visible" width="560" append-to-body draggable @close="hot_close_event">
<template #header>
<div class="title re">
<div class="tc size-16 fw">设置热区</div>

View File

@ -1,5 +1,5 @@
<template>
<el-dialog v-model="dialog_visible_category_oprate" class="radius-lg" width="500" append-to-body>
<el-dialog v-model="dialog_visible_category_operate" class="radius-lg" width="500" draggable append-to-body>
<template #header>
<div class="title center re">
<div class="tc size-16 fw">{{ type == 'add' ? '添加' : '编辑' }}附件分类</div>
@ -60,7 +60,7 @@ const props = defineProps({
default: '',
},
});
const dialog_visible_category_oprate = defineModel({ type: Boolean, default: false });
const dialog_visible_category_operate = defineModel({ type: Boolean, default: false });
const form = ref<Tree>({
id: '',
pid: '',
@ -71,7 +71,7 @@ const form = ref<Tree>({
items: [],
});
watch(
() => dialog_visible_category_oprate.value,
() => dialog_visible_category_operate.value,
(newValue) => {
if (newValue && props.type !== 'add') {
form.value = cloneDeep(props.value);
@ -107,7 +107,7 @@ onMounted(() => {
});
const cancel_event = (formEl: FormInstance | undefined) => {
dialog_visible_category_oprate.value = false;
dialog_visible_category_operate.value = false;
formEl?.resetFields();
};
const emit = defineEmits(['update:modelValue', 'confirm']);
@ -136,4 +136,10 @@ const confirm_event = async (formEl: FormInstance | undefined) => {
});
};
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.el-dialog__header {
.title {
height: 2.8rem;
}
}
</style>

View File

@ -6,7 +6,7 @@
.el-tree {
--el-tree-node-content-height: 40px;
}
.category-oprate {
.category-operate {
.icon:hover {
color: $cr-primary;
}
@ -53,7 +53,7 @@
opacity: 1;
}
}
.oprate {
.operate {
position: absolute;
bottom: 0rem;
left: 0;
@ -61,7 +61,7 @@
z-index: 1;
height: 2.4rem;
overflow: hidden;
.oprate-content {
.operate-content {
opacity: 0;
transition: all 0.5s linear;
position: absolute;
@ -74,7 +74,7 @@
border-bottom-right-radius: 0.4rem;
height: 2.4rem;
}
.oprate-icon {
.operate-icon {
position: relative;
&::before {
content: '';
@ -106,7 +106,7 @@
line-height: 2.8rem;
}
&:hover {
.oprate-content {
.operate-content {
opacity: 1 !important;
bottom: 0 !important;
}
@ -165,3 +165,18 @@
line-height: normal;
}
}
.tree-operate-btn {
color: #999;
&:hover {
color: $cr-primary;
}
}
.tree-operate {
.item {
transition: all 0.3s linear;
&:hover {
color: $cr-primary;
}
}
}

View File

@ -1,6 +1,6 @@
<!-- 上传组件 -->
<template>
<el-dialog v-model="dialog_visible" class="radius-lg" width="1168" append-to-body>
<el-dialog v-model="dialog_visible" class="radius-lg" width="1168" draggable append-to-body>
<template #header>
<div class="title re">
<el-radio-group v-model="upload_type" is-button @change="upload_type_change">
@ -26,16 +26,19 @@
<template #default="{ node, data }">
<div class="custom-tree-node flex-row jc-sb gap-10 align-c w pr-10" :class="data.is_enable == 0 || node.parent.data.is_enable == 0 ? 'disabled bg-red' : ''">
<div class="flex-1 flex-width text-line-1 block">{{ data.name }}</div>
<div v-if="data.id" class="flex-row gap-10 cr-9 category-oprate c-pointer">
<div v-if="data.pid == 0" @click.stop="append_type_event(data)">
<icon class="icon" name="add" size="12"></icon>
</div>
<div @click.stop="edit_type_event(data)">
<icon class="icon" name="edit" size="12"></icon>
</div>
<div @click.stop="remove_type_event(node, data)">
<icon class="icon" name="del" size="12"></icon>
</div>
<div v-if="data.id" class="flex-row gap-10 cr-9 category-operate c-pointer">
<el-popover placement="bottom" width="70" trigger="hover">
<template #reference>
<div class="tree-operate-btn">
<icon name="ellipsis" size="14"></icon>
</div>
</template>
<div class="flex-col gap-12 tree-operate">
<div v-if="data.pid == 0" class="flex-row gap-5 c-pointer w item" @click.stop="append_type_event(data)"><icon class="icon" name="add" size="12"></icon></div>
<div class="flex-row gap-5 c-pointer w item" @click.stop="edit_type_event(data)"><icon class="icon" name="edit" size="12"></icon>编辑</div>
<div class="flex-row gap-5 c-pointer w item" @click.stop="remove_type_event(node, data)"><icon class="icon" name="del" size="12"></icon>删除</div>
</div>
</el-popover>
</div>
</div>
</template>
@ -44,7 +47,7 @@
</div>
<div class="right-content flex-1 flex-width">
<div class="flex-row jc-sb align-c mb-15">
<div class="right-oprate flex-row">
<div class="right-operate flex-row">
<el-button type="primary" plain @click="upload_model_open">{{ upload_type_name }}</el-button>
<el-button @click="mult_del_event">{{ upload_type_name }}</el-button>
<!-- <el-cascader :show-all-levels="false" clearable></el-cascader> -->
@ -55,7 +58,7 @@
<div class="right-search">
<el-input v-model="search_name" :placeholder="'请输入' + upload_type_name + '名称'" @change="get_attachment_list('1')">
<template #suffix>
<icon name="search" size="18"></icon>
<icon name="search" size="18" class="c-pointer" @click="get_attachment_list('1')"></icon>
</template>
</el-input>
</div>
@ -90,12 +93,12 @@
<div class="check-icon fill flex-row jc-c align-c" :class="view_list_value.findIndex((i) => i.id === item.id) !== -1 ? 'active' : ''">
<icon name="true-o" color="f" size="26"></icon>
</div>
<div class="oprate">
<div class="oprate-content flex-row jc-sa align-c">
<div class="operate">
<div class="operate-content flex-row jc-sa align-c">
<div class="flex-1 tc c-pointer" @click.stop="edit_event(item, index)">
<icon name="edit" class="flex-1" size="14" color="f"></icon>
</div>
<div v-if="upload_type !== 'file'" class="oprate-icon flex-1 tc c-pointer" @click.stop="preview_event(item, index)">
<div v-if="upload_type !== 'file'" class="operate-icon flex-1 tc c-pointer" @click.stop="preview_event(item, index)">
<icon name="eye" size="14" color="f"></icon>
</div>
<div class="flex-1 tc c-pointer" @click.stop="del_event(item)">
@ -187,8 +190,8 @@
<script lang="ts" setup>
import { ext_img_name_list, ext_video_name_list, ext_file_name_list, ext_file_name_list_map } from './index';
import UploadAPI, { Tree } from '@/api/upload';
import { uploadrStore } from '@/store';
const upload_store = uploadrStore();
import { uploadStore } from '@/store';
const upload_store = uploadStore();
const app = getCurrentInstance();
/**
* @description: 图片上传
@ -249,8 +252,7 @@ watch(
() => dialog_visible.value,
(val) => {
if (val) {
type_data_list.value = upload_store.category;
type_data.value = [all_tree, ...upload_store.category];
get_tree();
get_attachment_list();
}
}
@ -270,6 +272,7 @@ const upload_type_name = computed(() => {
// //
const upload_type_change = (type: any) => {
view_list_value.value = [];
get_attachment_list();
};
//
@ -304,12 +307,22 @@ const all_tree = {
const type_data_list = ref<Tree[]>([]);
//
const get_tree = () => {
UploadAPI.getTree().then((res) => {
// all_treeres.data.category_listtype_data.value,all_tree
type_data.value = [all_tree, ...res.data.category_list];
type_data_list.value = res.data.category_list;
upload_store.set_category(type_data_list.value);
});
if (!upload_store.is_upload_api) {
upload_store.set_is_upload_api(true);
UploadAPI.getTree()
.then((res) => {
// all_treeres.data.category_listtype_data.value,all_tree
type_data.value = [all_tree, ...res.data.category_list];
type_data_list.value = res.data.category_list;
upload_store.set_category(type_data_list.value);
})
.catch(() => {
upload_store.set_is_upload_api(false);
});
} else {
type_data_list.value = upload_store.category;
type_data.value = [all_tree, ...upload_store.category];
}
};
//
@ -483,6 +496,12 @@ const del_event = (item: uploadList) => {
ElMessage.success('删除成功!');
//
get_attachment_list();
//
view_list_value.value = view_list_value.value.filter((items: any) => {
return items.id !== item.id;
});
console.log(view_list_value.value);
});
});
};
@ -497,6 +516,7 @@ const mult_del_event = () => {
//
get_attachment_list();
check_img_ids.value = '';
view_list_value.value = [];
});
});
} else {
@ -587,12 +607,7 @@ const close_upload_model = (data: any) => {
onMounted(() => {
//
document.addEventListener('click', video_show);
if (!upload_store.is_upload_api) {
upload_store.set_is_upload_api(true);
get_tree();
} else {
type_data.value = upload_store.category;
}
get_tree();
});
onUnmounted(() => {
//

View File

@ -1,6 +1,6 @@
<!-- 上传组件 -->
<template>
<el-dialog v-model="dialogVisible" class="radius-lg" width="1168" append-to-body @close="close_dialog">
<el-dialog v-model="dialogVisible" class="radius-lg" width="1168" draggable append-to-body @close="close_dialog">
<template #header>
<div class="title center re">
<div class="tc size-16 fw">{{ upload_type_name }}上传</div>
@ -12,7 +12,7 @@
<el-radio-group v-model="form.type" @change="upload_type_change">
<el-radio value="loc">本地上传</el-radio>
<el-radio value="scan">扫码上传</el-radio>
<el-radio v-if="type !== 'file'" value="web"></el-radio>
<el-radio value="web">网络上传</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="上传至分组" prop="category_id">
@ -38,7 +38,7 @@
<div class="table-cell">文件名</div>
<div class="table-cell">文件大小</div>
<div class="table-cell">上传状态</div>
<div class="table-cell-oprate">操作</div>
<div class="table-cell-operate">操作</div>
</div>
</div>
<div id="dropzone" @dragover.prevent="handle_drag_in" @dragenter="handle_drag_in" @dragleave="handle_drag_leave" @drop.prevent="handle_drop">
@ -73,7 +73,7 @@
</div>
<div class="table-cell">{{ annex_size_to_unit(item.file.size) }}</div>
<div class="table-cell" :class="item.status">{{ item.status == 'loading' ? '上传中' : item.status == 'success' ? '上传成功' : item.status == 'error' ? '上传失败' : '等待上传' }}{{ item.status == 'loading' ? '(' + item.progress + '%)' : '' }}</div>
<div class="table-cell-oprate" @click="del_upload(index)"></div>
<div class="table-cell-operate" @click="del_upload(index)"></div>
</div>
</div>
</div>
@ -98,7 +98,7 @@
<div class="table-row">
<div class="table-cell">文件名</div>
<div class="table-cell">文件大小</div>
<div class="table-cell-oprate">操作</div>
<div class="table-cell-operate">操作</div>
</div>
</div>
<el-scrollbar height="224px">
@ -129,7 +129,7 @@
<div class="desc">{{ item.title }}</div>
</div>
<div class="table-cell">{{ annex_size_to_unit(item.size) }}</div>
<div class="table-cell-oprate" @click="del_already_upload(item.id, index)">删除</div>
<div class="table-cell-operate" @click="del_already_upload(item.id, index)">删除</div>
</div>
</div>
</el-scrollbar>
@ -157,8 +157,8 @@
</template>
<script lang="ts" setup>
import UploadAPI, { Tree } from '@/api/upload';
import { uploadrStore } from '@/store';
const upload_store = uploadrStore();
import { uploadStore } from '@/store';
const upload_store = uploadStore();
import type { UploadFile, UploadFiles, UploadUserFile, FormRules, FormInstance } from 'element-plus';
import { annex_size_to_unit, ext_name, get_math } from '@/utils';
import { ext_img_name_list, ext_video_name_list, ext_file_name_list, ext_file_name_list_map } from './index';
@ -634,7 +634,7 @@ const close_dialog = () => {
width: 0;
}
}
.table-cell-oprate {
.table-cell-operate {
padding: 1rem;
width: 5rem;
cursor: pointer;
@ -647,10 +647,10 @@ const close_dialog = () => {
}
.table-body {
.table-cell,
.table-cell-oprate {
.table-cell-operate {
padding: 1.5rem 1rem !important;
}
.table-cell-oprate {
.table-cell-operate {
color: $cr-primary;
}
}

View File

@ -1,59 +1,5 @@
<!-- 上传组件 -->
<template>
<el-dialog v-model="dialogVisible" class="radius-lg" width="1168" append-to-body @close="close_event">
<template #header>
<div class="title center re">
<div class="tc size-16 fw">选择链接</div>
</div>
</template>
<div class="url-value-content pa-20 flex-row">
<div class="left-content">
<el-menu :default-active="link_select" class="w br-none" @select="handle_select">
<el-menu-item v-for="item in base_data" :key="item.type" :index="item.type" :disabled="!(custom_link_type.length == 0 || custom_link_type.includes(item.type))">
<span>{{ item.name }}</span>
</el-menu-item>
</el-menu>
</div>
<div class="right-content flex-1">
<template v-if="link_select == 'shop'">
<link-list v-model="link_value" :reset="reset_compontent"></link-list>
</template>
<template v-else-if="link_select == 'goods-category'">
<link-goods-category v-model="link_value" :reset="reset_compontent"></link-goods-category>
</template>
<template v-else-if="link_select == 'goods-search'">
<link-goods-search :reset="reset_compontent" :status="component_status" @update:link="goods_category_link" @type="goods_category_type_change" @required="required_tips"></link-goods-search>
</template>
<template v-else-if="link_select == 'goods'">
<link-goods v-model="link_value" :reset="reset_compontent"></link-goods>
</template>
<template v-else-if="link_select == 'articles'">
<link-articles v-model="link_value" :reset="reset_compontent"></link-articles>
</template>
<template v-else-if="link_select == 'diy'">
<link-table v-model="link_value" :reset="reset_compontent"></link-table>
</template>
<template v-else-if="link_select == 'design'">
<link-table v-model="link_value" :reset="reset_compontent"></link-table>
</template>
<template v-else-if="link_select == 'custom-view'">
<link-table v-model="link_value" :reset="reset_compontent"></link-table>
</template>
<template v-else-if="link_select == 'custom'">
<link-custom :reset="reset_compontent" :status="component_status" @update:link="custom_link" @required="required_tips"></link-custom>
</template>
<template v-else-if="link_select == 'plugins'">
<link-list v-model="link_value" :reset="reset_compontent"></link-list>
</template>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button class="plr-28 ptb-10" @click="close_event"></el-button>
<el-button class="plr-28 ptb-10" type="primary" @click="confirm_event"></el-button>
</span>
</template>
</el-dialog>
<div class="flex-row align-c gap-10 br-d radius-sm plr-11 url-value-input" @click="dialogVisible = true">
<div class="flex-1 flex-width size-12 text-line-1">
<text v-if="!is_obj_empty(modelValue)">{{ modelValue.name }}</text>
@ -70,12 +16,10 @@
</template>
</div>
</div>
<url-value-dialog v-model:modelValue="modelValue" v-model:dialogVisible="dialogVisible" :type="type"></url-value-dialog>
</template>
<script lang="ts" setup>
import { MenuItemClicked } from 'element-plus/es/components/menu/src/types';
import { is_obj_empty } from '@/utils';
import { PropType } from 'vue';
const app = getCurrentInstance();
/**
* @description: 页面链接
@ -97,128 +41,6 @@ const props = defineProps({
});
const modelValue = defineModel({ type: Object, default: {} });
const dialogVisible = defineModel('visibleDialog', { type: Boolean, default: false });
const link_value = ref({});
const reset_compontent = ref(false);
const custom_link_type = ref(props.type);
const base_data = reactive([
{
name: '商城页面',
type: 'shop',
data: [{ name: '基础链接', data: [{ name: '', page: '' }] }],
},
{
name: '商品分类',
type: 'goods-category',
data: null,
},
{
name: '商品搜索',
type: 'goods-search',
data: null,
},
{
name: '商品页面',
type: 'goods',
data: null,
},
{
name: '文章页面',
type: 'articles',
data: null,
},
{
name: 'DIY页面',
type: 'diy',
data: null,
},
{
name: '页面设计',
type: 'design',
data: null,
},
{
name: '自定义页面',
type: 'custom-view',
data: null,
},
{
name: '自定义链接',
type: 'custom',
data: null,
},
{
name: '插件',
type: 'plugins',
data: [{ name: '多商户', data: [{ name: '1', page: '2' }] }],
},
]);
//
//#region -----------------------------------------------start
//
const link_select = ref(props.type.length == 0 ? 'shop' : props.type[0]);
const handle_select = (index: string, indexPath: string[], item: MenuItemClicked, routeResult: any) => {
// console.log(index, indexPath, item, routeResult);
link_select.value = index;
};
//#endregion -----------------------------------------------end
//@region -----------------------------------------------start
const component_status = ref(false);
//
const goods_category_type = ref(0);
const goods_category_type_change = (type: number) => {
goods_category_type.value = type;
};
const goods_category_link = (data: object, type: number) => {
if (type == 2) {
modelValue.value = data;
close_event();
} else {
link_value.value = data;
}
};
//
const custom_link = (data: object) => {
modelValue.value = data;
close_event();
};
//
const required_tips = () => {
ElMessage({
type: 'warning',
message: '必填项不能为空',
});
};
//#endregion -----------------------------------------------end
//#region -----------------------------------------------start
//
const close_event = () => {
link_select.value = props.type.length == 0 ? 'shop' : props.type[0];
dialogVisible.value = false;
link_value.value = {};
reset_compontent.value = !reset_compontent.value;
};
//
const confirm_event = () => {
//
if (link_select.value == 'custom' || (link_select.value == 'goods-search' && goods_category_type.value == 2)) {
component_status.value = !component_status.value;
} else {
if (is_obj_empty(link_value.value)) {
ElMessage({
type: 'warning',
message: '请先选择链接',
});
} else {
modelValue.value = link_value.value;
close_event();
}
}
};
//#endregion -----------------------------------------------end
//#endregion -------------------------------------------------start
const clear_model_value = () => {
modelValue.value = {};

View File

@ -5,7 +5,7 @@
<div class="search">
<el-input v-model="search_value" placeholder="请输入搜索内容" class="" @change="handle_search">
<template #suffix>
<icon name="search" size="16" color="9"></icon>
<icon name="search" size="16" color="9" class="c-pointer" @click="handle_search"></icon>
</template>
</el-input>
</div>
@ -13,10 +13,10 @@
<div class="content">
<el-scrollbar height="480px">
<div class="flex-col gap-30">
<div v-for="item in base_data" :key="item.id">
<div v-for="item in new_base_data" :key="item.type">
<div class="fw mb-15">{{ item.name }}</div>
<div class="flex-row flex-wrap gap-15">
<div v-for="child in item.data" :key="child.id" class="item" :class="menu_active == item.id + '-' + child.id ? 'active' : ''" @click="menu_link_event(child, item.id)">{{ child.name }}</div>
<div v-for="(child, index) in item.data" :key="index" class="item" :class="menu_active == item.page ? 'active' : ''" @click="menu_link_event(child)">{{ child.name }}</div>
</div>
</div>
</div>
@ -25,6 +25,8 @@
</div>
</template>
<script lang="ts" setup>
import { urlValueStore, urlValue, pageLinkList } from '@/store';
const url_value_store = urlValueStore();
const props = defineProps({
//
reset: {
@ -40,67 +42,52 @@ watch(
);
const modelValue = defineModel({ type: Object, default: {} });
const search_value = ref('');
const base_data = ref<linkData[]>([
{
id: 0,
name: '基础链接',
data: [
{ id: 0, name: '首页', link: '首页' },
{ id: 1, name: '商城分类', link: '商城分类' },
{ id: 2, name: '购物车', link: '购物车' },
{ id: 3, name: '分类商品列表', link: '分类商品列表' },
{ id: 4, name: '退款列表', link: '退款列表' },
{ id: 5, name: '我的订单', link: '我的订单' },
{ id: 6, name: '文章列表', link: '文章列表' },
{ id: 7, name: '供应商入驻', link: '供应商入驻' },
],
},
{
id: 1,
name: '个人中心',
data: [
{ id: 0, name: '付费会员', link: '付费会员' },
{ id: 1, name: '收银页面', link: '收银页面' },
{ id: 2, name: '我的订单', link: '我的订单' },
{ id: 3, name: '我的收藏', link: '我的收藏' },
{ id: 4, name: '我的地址', link: '我的地址' },
{ id: 5, name: '我的优惠券', link: '我的优惠券' },
{ id: 6, name: '我的消息', link: '我的消息' },
{ id: 7, name: '我的资料', link: '我的资料' },
{ id: 8, name: '我的积分', link: '我的积分' },
{ id: 9, name: '我的余额', link: '我的余额' },
{ id: 10, name: '我的红包', link: '我的红包' },
],
},
{
id: 2,
name: '分销',
data: [
{ id: 0, name: '分销中心', link: '分销中心' },
{ id: 1, name: '分销订单', link: '分销订单' },
{ id: 2, name: '分销商品', link: '分销商品' },
{ id: 3, name: '分销提现', link: '分销提现' },
{ id: 4, name: '分销佣金', link: '分销佣金' },
{ id: 5, name: '分销设置', link: '分销设置' },
{ id: 6, name: '分销关系', link: '分销关系' },
{ id: 7, name: '分销商列表', link: '分销商列表' },
{ id: 8, name: '分销商等级', link: '分销商等级' },
{ id: 9, name: '分销商统计', link: '分销商统计' },
{ id: 10, name: '分销商提现', link: '分销商提现' },
],
},
]);
const base_data = ref<pageLinkList[]>([]);
const new_base_data = ref<pageLinkList[]>([]);
onMounted(() => {
// url_value_store.url_value.page_link_listtypeshopdatadata
base_data.value = url_value_store.url_value.page_link_list.filter((item: any) => {
if (item.type == 'shop') {
return item.data;
}
});
new_base_data.value = base_data.value[0].data;
});
const handle_search = () => {
console.log(search_value.value);
// new_base_data,== ==
let bool = false;
if (search_value.value) {
new_base_data.value = new_base_data.value.filter((item: any) => {
if (item.name == search_value.value) {
bool = true;
console.log(1);
return item;
}
});
if (!true) {
new_base_data.value = new_base_data.value.filter((item: any) => {
item.filter((child: any) => {
if (child.name == search_value.value) {
bool = true;
return child;
}
});
});
}
} else {
new_base_data.value = base_data.value[0].data;
}
console.log(new_base_data.value);
};
const menu_active = ref('');
const emit = defineEmits(['update:link']);
const menu_link_event = (item: linkData, parent_id: number | undefined) => {
if (`${parent_id}-${item.id}` == menu_active.value) {
const menu_link_event = (item: any) => {
if (item.page == menu_active.value) {
menu_active.value = '';
modelValue.value = {};
} else {
menu_active.value = `${parent_id}-${item.id}`;
menu_active.value = item.page;
modelValue.value = item;
}
};

View File

@ -0,0 +1,185 @@
<template>
<el-dialog v-model="dialogVisible" class="radius-lg" width="1168" draggable append-to-body @close="close_event">
<template #header>
<div class="title center re">
<div class="tc size-16 fw">选择链接</div>
</div>
</template>
<div class="url-value-content pa-20 flex-row">
<div class="left-content">
<el-menu :default-active="link_select" class="w br-none" @select="handle_select">
<el-menu-item v-for="item in base_data" :key="item.type" :index="item.type" :disabled="!(custom_link_type.length == 0 || custom_link_type.includes(item.type))">
<span>{{ item.name }}</span>
</el-menu-item>
</el-menu>
</div>
<div class="right-content flex-1">
<template v-if="link_select == 'shop' || link_select == 'plugins'">
<link-list v-model="link_value" :reset="reset_compontent"></link-list>
</template>
<template v-else-if="link_select == 'goods-category'">
<link-goods-category v-model="link_value" :reset="reset_compontent"></link-goods-category>
</template>
<template v-else-if="link_select == 'goods-search'">
<link-goods-search :reset="reset_compontent" :status="component_status" @update:link="goods_category_link" @type="goods_category_type_change" @required="required_tips"></link-goods-search>
</template>
<template v-else-if="link_select == 'goods'">
<link-goods v-model="link_value" :reset="reset_compontent"></link-goods>
</template>
<template v-else-if="link_select == 'articles'">
<link-articles v-model="link_value" :reset="reset_compontent"></link-articles>
</template>
<template v-else-if="link_select == 'diy' || link_select == 'design' || link_select == 'custom-view'">
<link-table v-model="link_value" :reset="reset_compontent"></link-table>
</template>
<template v-else-if="link_select == 'custom'">
<link-custom :reset="reset_compontent" :status="component_status" @update:link="custom_link" @required="required_tips"></link-custom>
</template>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button class="plr-28 ptb-10" @click="close_event"></el-button>
<el-button class="plr-28 ptb-10" type="primary" @click="confirm_event"></el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { MenuItemClicked } from 'element-plus/es/components/menu/src/types';
import { is_obj_empty } from '@/utils';
import { PropType } from 'vue';
import UrlValueAPI from '@/api/url-value';
import { urlValueStore, urlValue } from '@/store';
const url_value_store = urlValueStore();
const app = getCurrentInstance();
/**
* @description: 页面链接
* @param modelValue{Object} 默认值
* @param dialogVisible {Boolean} 弹窗显示
* @param type{String} 链接类型为空数组则表示无限制全部可用传过来则表示传的值可用
* @return {*} update:modelValue
*/
const props = defineProps({
type: {
type: Array as PropType<string[]>,
default: () => [],
},
});
const modelValue = defineModel({ type: Object, default: {} });
const dialogVisible = defineModel('dialogVisible', { type: Boolean, default: false });
const link_value = ref({});
const reset_compontent = ref(false);
const custom_link_type = ref(props.type);
const base_data = ref<any[]>([]);
const init_data = ref({});
watch(
() => dialogVisible.value,
(val) => {
if (val) {
}
}
);
watch(
() => dialogVisible.value,
(val) => {
if (val) {
init();
}
}
);
onMounted(() => {
init();
});
const init = () => {
if (!url_value_store.is_url_value_api) {
url_value_store.set_is_url_value_api(true);
UrlValueAPI.getInit()
.then((res: any) => {
init_data.value = res.data;
base_data.value = res.data.page_link_list;
if (res.data.page_link_list.length > 0) {
link_select.value = res.data.page_link_list[0].type;
}
url_value_store.set_url_value(res.data);
})
.catch(() => {
url_value_store.set_is_url_value_api(false);
});
} else {
init_data.value = url_value_store.url_value;
base_data.value = url_value_store.url_value.page_link_list;
if (url_value_store.url_value.page_link_list.length > 0) {
link_select.value = url_value_store.url_value.page_link_list[0].type;
}
}
};
//#region -----------------------------------------------start
//
const link_select = ref('');
const handle_select = (index: string, indexPath: string[], item: MenuItemClicked, routeResult: any) => {
link_select.value = index;
};
//#endregion -----------------------------------------------end
//@region -----------------------------------------------start
const component_status = ref(false);
//
const goods_category_type = ref(0);
const goods_category_type_change = (type: number) => {
goods_category_type.value = type;
};
const goods_category_link = (data: object, type: number) => {
if (type == 2) {
modelValue.value = data;
close_event();
} else {
link_value.value = data;
}
};
//
const custom_link = (data: object) => {
modelValue.value = data;
close_event();
};
//
const required_tips = () => {
ElMessage({
type: 'warning',
message: '必填项不能为空',
});
};
//#endregion -----------------------------------------------end
//#region -----------------------------------------------start
//
const close_event = () => {
link_select.value = props.type.length == 0 ? 'shop' : props.type[0];
dialogVisible.value = false;
link_value.value = {};
reset_compontent.value = !reset_compontent.value;
};
//
const confirm_event = () => {
//
if (link_select.value == 'custom' || (link_select.value == 'goods-search' && goods_category_type.value == 2)) {
component_status.value = !component_status.value;
} else {
if (is_obj_empty(link_value.value)) {
ElMessage({
type: 'warning',
message: '请先选择链接',
});
} else {
modelValue.value = link_value.value;
close_event();
}
}
};
//#endregion -----------------------------------------------end
</script>
<style lang="scss" scoped>
@import 'index.scss';
</style>

View File

@ -17,7 +17,6 @@ const style_container = ref('');
watch(
props.value,
(newVal, oldValue) => {
console.log(1);
const new_content = newVal?.content || {};
const new_style = newVal?.style || {};
let border_content = `border-bottom-style: ${new_content?.styles || 'solid'};`;

View File

@ -38,7 +38,6 @@ watch(
img_height.value = new_content?.hot.img_height || 1;
style_container.value = common_styles_computer(new_style.common_style);
hot_data.value = new_content?.hot?.data || [];
console.log(1);
},
{ immediate: true, deep: true }
);

View File

@ -10,4 +10,5 @@ export function setupStore(app: App<Element>) {
export * from './modules/footer-nav-content';
export * from './modules/upload';
export * from './modules/shop';
export * from './modules/url-value';
export { store };

View File

@ -1,7 +1,7 @@
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
export const uploadrStore = defineStore('upload', () => {
export const uploadStore = defineStore('upload', () => {
// 上传是否需要调接口判断
const is_upload_api = ref(false);
// 上传分类列表

View File

@ -0,0 +1,44 @@
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
export const urlValueStore = defineStore('urlValue', () => {
// 链接是否需要调接口判断
const is_url_value_api = ref(false);
// 链接数据
const url_value = ref<urlValue>({
goods_category: [],
brand_list: [],
article_category_list: [],
page_link_list: [],
});
// 存储链接数据
const set_url_value = (data: urlValue) => {
url_value.value = data;
is_url_value_api.value = true;
};
// 如果为false 则转为true
const set_is_url_value_api = (bool: boolean) => {
is_url_value_api.value = bool;
};
return {
url_value,
is_url_value_api,
set_url_value,
set_is_url_value_api,
};
});
export interface pageLinkList {
name: string;
type: string;
data: pageLinkList[];
page?: string;
}
// 分类树结构
export interface urlValue {
goods_category: any[];
brand_list: any[];
article_category_list: any[];
page_link_list: pageLinkList[];
}

View File

@ -132,6 +132,8 @@ div:focus {
}
.el-dialog__headerbtn {
font-size: 2.4rem;
width: 3.4rem;
height: 3.4rem;
}
.title {
height: 3.8rem;
@ -168,3 +170,7 @@ div:focus {
right: -1.6rem;
}
}
.el-popover.el-popper {
min-width: 5rem;
}

View File

@ -4,12 +4,12 @@ import { get_cookie } from './index';
// 创建 axios 实例
const index = window.location.href.lastIndexOf('?s=');
const pro_url = window.location.href.substring(0, index);
console.log(import.meta.env.VITE_APP_BASE_API);
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API == '/dev-api' ? import.meta.env.VITE_APP_BASE_API : pro_url + '?s=',
timeout: 50000,
headers: { 'Content-Type': 'application/json;charset=utf-8' },
});
console.log('321');
// 请求拦截器
service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
@ -31,30 +31,27 @@ service.interceptors.request.use(
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
const { code, msg } = response.data;
// 登录成功
if (code == '0') {
const { code, msg, data } = response.data;
if (code == 0) {
return response.data;
} else if (code == -400) {
ElMessageBox.alert(msg, '温馨提示', {
confirmButtonText: '确定',
showClose: false,
type: 'warning',
}).then(() => {
localStorage.clear(); // @vueuse/core 自动导入
window.location.href = data;
});
} else {
ElMessage.error(msg || '系统出错');
return Promise.reject(new Error(msg || 'Error'));
}
ElMessage.error(msg || '系统出错');
return Promise.reject(new Error(msg || 'Error'));
},
(error: any) => {
if (error.response.data) {
const { code, msg } = error.response.data;
// token 过期,跳转登录页
if (code === '-400') {
ElMessageBox.confirm('当前页面已失效,请重新登录', '提示', {
confirmButtonText: '确定',
type: 'warning',
}).then(() => {
localStorage.clear(); // @vueuse/core 自动导入
window.location.href = '/';
});
} else {
ElMessage.error(msg || '系统出错');
}
const { msg } = error.response.data;
ElMessage.error(msg || '系统出错');
}
return Promise.reject(error.message);
}