提交 4daba8a9 authored 作者: 王鹏飞's avatar 王鹏飞

build: 构建工具升级到vite; vue 2.7

上级 01996729
module.exports = {
domain: 'dev.ezijing.com',
url: 'https://shop-admin2.ezijing.com/api',
webpack: {
externals: {
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime',
wx: 'window.wx',
WeixinJSBridge: 'window.WeixinJSBridge'
}
// devServer: {
// proxy: {
// '/api/shop': {
// target: 'http://172.16.3.11:8089',
// changeOrigin: true,
// pathRewrite: { '^/api/shop': '' }
// }
// }
// }
},
ProvidePlugin: {},
others: {
loginUrl: 'https://login2.ezijing.com/auth/login/index',
pcPreviewUrl: 'https://shop2.ezijing.com',
h5PreviewUrl: 'https://h5-shop2.ezijing.com'
}
}
module.exports = {
url: '/',
DesDir: './client-dist',
isUploadStatic: false,
webpack: {
externals: {
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime',
wx: 'window.wx',
WeixinJSBridge: 'window.WeixinJSBridge'
}
},
ProvidePlugin: {},
others: {
loginUrl: 'https://login.ezijing.com/auth/login/index',
pcPreviewUrl: 'https://shop.ezijing.com',
h5PreviewUrl: 'https://h5-shop.ezijing.com'
}
}
module.exports = {
url: '/',
DesDir: './client-dist',
isUploadStatic: false,
webpack: {
externals: {
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime',
wx: 'window.wx',
WeixinJSBridge: 'window.WeixinJSBridge'
}
},
ProvidePlugin: {},
others: {
loginUrl: 'https://login2.ezijing.com/auth/login/index',
pcPreviewUrl: 'https://shop2.ezijing.com',
h5PreviewUrl: 'https://h5-shop2.ezijing.com'
}
}
# 查到当前目录就可以了,不用再往下查找
root = true
# 对所有文件制定规范
[*]
charset = utf-8 # 字符编码
end_of_line = lf # 从左往右写
indent_size = 2 # tab键长度2个空格
indent_style = space
insert_final_newline = true # 保存自动加上一个空行
trim_trailing_whitespace = true # 每行最后空格去掉
VITE_LOGIN_URL=https://login2.ezijing.com/auth/login/index VITE_LOGIN_URL=https://login.ezijing.com/auth/login/index
VITE_PC_PREVIEW_URL=https://shop2.ezijing.com VITE_PC_PREVIEW_URL=https://shop.ezijing.com
VITE_H5_PREVIEW_URL=https://h5-shop2.ezijing.com VITE_H5_PREVIEW_URL=https://h5-shop.ezijing.com
{
"extends": "standard",
"plugins": ["html"],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "babel-eslint",
"sourceType": "module"
},
"rules": {
"no-new": "off",
"no-debugger": "off",
"space-before-function-paren": "off"
},
"globals": {
"CKEDITOR": false,
"Base64": false,
"md5": false,
"$": false,
"window": false,
"webConf": false,
"wx": false,
"WeixinJSBridge": false,
"Aliplayer": false
}
}
module.exports = {
root: true,
env: {
node: true
},
extends: ['eslint:recommended', 'plugin:vue/essential'],
rules: {
'vue/no-mutating-props': 'off', // 暂时关闭
'vue/multi-word-component-names': 'off'
}
}
.DS_Store
node_modules node_modules
npm-debug.log .DS_Store
upload_tmp dist
client-dist
# code protect - prevent submit code below dist-ssr
/dist *.local
/client-dist \ No newline at end of file
.DS_Store
node_modules
npm-debug.log
# code protect - prevent submit code below
var semver = require('semver')
var requiredVersion = require('../package.json').engines.node
function checkNodeVersion (wanted, id) {
if (!semver.satisfies(process.version, wanted)) {
console.log('\x1b[91m%s\x1B[0m',
'You are using Node ' + process.version + ', but this version of ' + id +
' requires Node ' + wanted + '.\nPlease upgrade your Node version.'
)
process.exit(1)
}
}
checkNodeVersion(requiredVersion, '`node uploadAliyunCDN.js`')
const isDev = process.env.NODE_ENV
const RegStrs = require('./regExpStr.js')
let config = {
isDev: isDev,
ResDir: 'src',
DesDir: '../client-dist',
HtmlPath: 'src/index.html',
IcoPath: 'src/assets/favicon.ico',
JsPath: 'src/main.js',
isHttps: true,
isEnableToIphoneDebugger: false,
CDN_BASE: 'https://zws-imgs-pub.ezijing.com/',
CDN_DIR: 'static/build/learn-mba/',
isUploadStatic: false,
webpack: {}
}
config.RegStrs = RegStrs
let vueClientConfig = {}
config.domain = ''
if (config.isDev === 'development') {
config.url = 'http://' + config.domain + ':12002'
try {
vueClientConfig = require('../.config.dev.js')
} catch (error) {
vueClientConfig = {}
console.error('没有开发环境配置文件 -- `.config.dev.js`,正在使用默认配置')
}
} else if(config.isDev === 'test') {
config.url = '//api.ezijing.com'
try {
vueClientConfig = require('../.config.test.js')
} catch (error) {
vueClientConfig = {}
console.error('没有测试环境配置文件 -- `.config.test.js`,正在使用默认配置')
}
} else {
config.url = '//api.ezijing.com'
try {
vueClientConfig = require('../.config.pro.js')
} catch (error) {
vueClientConfig = {}
console.error('没有生产环境配置文件 -- `.config.pro.js`,正在使用默认配置')
}
}
for (let k in vueClientConfig) {
config[k] = vueClientConfig[k]
}
module.exports = config
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA9MjUExxOj6tfMUaU+t/k0+VokVkh1GVZACLPdxR2VcjjOkaI
qloY4TK4/uybncLhoqu9ggyiJFNmXVLxe2TxReGXhR8tAc0RTCuaFv0oHJ7HXI48
CZ/zc8sgjyd7XsuyRurKwpHWXfy9FMHE7r/9R+IUHAkIPmZ17qlwqphlePK8I1fn
DU/LOvglXPIlR55TUe6NKVoCPZXQEHHPZClH0qdnXFiUq5I1f6GMUoGCbV5DLECb
OAndCP/snqakw8oeLmoBGSig/FGrc/41l2DJxyIxm/CfaEhfnSN4hvOTAFXcro9c
gyy88H1BfT/bEhM7OO+RRaKUrV5CieeIOEmvGQIDAQABAoIBAGmkcsJ8qPsgPskJ
aSqMjjlU/Lgd+5eq1apVW6xMzHVhaY+w+TJsB+jI90Yt30tK3A5UiEkkIqYCyF7m
eQmEGwzJu5bcSZRJaHmzJ6FcSH9xlyC+0fJlcbA7riWaKIhU6O/qTO+D+Tw+42ud
5NwVR75KN9uRmlkz5xnFTraRZtm3MJmA7dwXK3hrN+dFJR2vLO3KBAtpgtpPdkK1
ObpJQ1Q7jsnEmODVRZ7n1CKZEDmXd8GBPA/jCVqgiEbVVCdkhHkyxyIMQenBReyy
tJIPf7CdL3O3PPsThhMa1P2CP/xehS4bcQSLw9wtNTJcvVPHTvffHKOKUfhUxkHu
0cpl+zECgYEA/jzySW/br7W+xS2e4VBHzY+UZJwxd/3mY3d/kasMV1zuipr6WOhQ
FVsd5uJXPRr+rHBypwyOIlP205V2K5oQEK0yT+tF+IBvKGdJv89wskCgrXcD3Kfb
dCFbt014pHw89A8jb8LBbGOPH6jhZhGkxP33CJdVPtncUc4m0hj4HHcCgYEA9nsc
KcCZOIYRlZmJ93DoukhjxaouGFDTOZoujaqasrfXUaWRnpZYekDZWa1NneOzLBEz
h1RwPcmeYLCVRmXtpRzLOKXfJY0gGSJr979I0AVkzj8A9NZcU/HxUP0GqpwBbzAp
EEShQVhjYppQ62KAwZ1tbsVWX2V1SBsa3McExO8CgYEA6kVy5aTDhOgugDeHnguB
/rN9hDBBjVZTQ/jLfolld+NUlDg21FJN6T/rD+Qli1MitfdwTupM1ukUGugw2gC/
KP7Py8D62wBObaav2KXoLPlMlkuDLYMnv501jHVA5CDvcd25Q7Ts01nyerP97zX2
5Oc5CZuZm67ZTDBwqU0E5AUCgYBIC2wL+DPRBb8WDy74mJQt/wLKwBeBG/7hk2OQ
HRHis0HIp7CMvj1WXqYpRDKvt+KjOtPo9pFoPgqBEJxRW3G/FU+BW1qCS2HadulA
HTVXOHxinJ/W8OFD2DBFD/Bm5fq1WUpnaugHhaJnK9wDMWOZND7MZfn9IFbLoMCV
T8bhGQKBgG7qsZhI9ldAqooZQ1xSua/2SBc8GI8d03g7y8kZkkx/XclbEz6X6wUu
U3PVL+neY8Qw3JxC1cHS++KIdHR2ZSoTpF00A4QvDJL0+eo1KgI88vRV8QaWLxPB
ahvXwmkKW2+jgvCAqFtepZx/KsKpQW+x3GOJyhl2tIT8sZwRmE6u
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIFhzCCBG+gAwIBAgIQCzEi4VmynSzbyBV1UEXGojANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMjAxMTA5MDAwMDAwWhcNMjExMTA5MjM1OTU5WjAa
MRgwFgYDVQQDEw9kZXYuZXppamluZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQD0yNQTHE6Pq18xRpT63+TT5WiRWSHUZVkAIs93FHZVyOM6Roiq
WhjhMrj+7JudwuGiq72CDKIkU2ZdUvF7ZPFF4ZeFHy0BzRFMK5oW/SgcnsdcjjwJ
n/NzyyCPJ3tey7JG6srCkdZd/L0UwcTuv/1H4hQcCQg+ZnXuqXCqmGV48rwjV+cN
T8s6+CVc8iVHnlNR7o0pWgI9ldAQcc9kKUfSp2dcWJSrkjV/oYxSgYJtXkMsQJs4
Cd0I/+yepqTDyh4uagEZKKD8Uatz/jWXYMnHIjGb8J9oSF+dI3iG85MAVdyuj1yD
LLzwfUF9P9sSEzs475FFopStXkKJ54g4Sa8ZAgMBAAGjggJzMIICbzAfBgNVHSME
GDAWgBRVdE+yck/1YLpQ0dfmUVyaAYca1zAdBgNVHQ4EFgQUkRHkmubxZAvEWtCY
IBT9sw/3Yb8wGgYDVR0RBBMwEYIPZGV2LmV6aWppbmcuY29tMA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTAYDVR0gBEUwQzA3
BglghkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
Y29tL0NQUzAIBgZngQwBAgEwgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEoGCCsGAQUFBzAChj5odHRwOi8vY2Fj
ZXJ0cy5kaWdpY2VydC5jb20vRW5jcnlwdGlvbkV2ZXJ5d2hlcmVEVlRMU0NBLUcx
LmNydDAJBgNVHRMEAjAAMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA9lyUL9F3
MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF1qpa6jQAABAMARzBFAiAwHOcp
Ua1H0WK4OZUHiQ1rndqnYxPHhP9XWunwpRMoagIhAOB2MPSW9M4qj6Yih7eQkydl
lgawpoBZzRzhisU+TN67AHYAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbH
DsoAAAF1qpa63gAABAMARzBFAiEA92ZeW0PgyWW3j+3wypLS0O/wI63C+x0WTvMZ
Vngp6AMCIBoThjaKif+XY11YbaV89ndqs1nDlzbEfBrFftoB9fchMA0GCSqGSIb3
DQEBCwUAA4IBAQA2geo9wQAd+vx+lwAafVRxCBQyBiS0qT413ewYpZYDnSkLX0l1
5kRdxDGWQhPzOio0ckj/jOtOlbbSsiovBBVTyYPB8WfkNjMd0psMNx2e6Wy/WKkQ
X3DqEOB4XGg0RwpebiAmz6lWxyFwIAbCrwCntkkaIF4LnIvczn6pvPFBtK2nXJJC
HL0Igbxo+xJLt3Hql7TcwkFDXz/LIB8AwhhkkhhwW45r3Eyjw8eOyzvflDPwSNH+
ByadQ+AH4H4vYYVo0ILNIPCdaokLQ+u4FttB9VQ+iGmpJ56Yg2muxWh8Qckca+vH
40RbC5aK1RSy2RIRpC5fwvq2JuV/CksP5G5Q
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
-----END CERTIFICATE-----
const fs = require('fs')
const path = require('path')
const request = require('request')
const _conf = require('./config')
fs.writeFileSync(path.join(__dirname, _conf.domain + '.key'), '', { encoding: 'utf8', mode: 0o755 })
fs.writeFileSync(path.join(__dirname, _conf.domain + '.pem'), '', { encoding: 'utf8', mode: 0o755 })
request('https://ssl.godzyx.com/' + _conf.domain + '/' + _conf.domain + '.key?get=allow').pipe(fs.createWriteStream(path.join(__dirname, _conf.domain + '.key')))
request('https://ssl.godzyx.com/' + _conf.domain + '/' + _conf.domain + '.pem?get=allow').pipe(fs.createWriteStream(path.join(__dirname, _conf.domain + '.pem')))
/* 由于正则表达式,不能进行跟 gulpfile 中 去注释 在一起 */
module.exports = {
regExp_static: /('|"|`)[\.|\/]*?static\/(.*?\.(png|jpe?g|gif|svg|ico)(\?.*)?)\1/g
}
const _conf = require('./config')
module.exports = function (source) {
if (_conf.isDev !== 'development') {
return source
.replace(_conf.RegStrs.regExp_static, '$1' + _conf.CDN_BASE + _conf.CDN_DIR + 'static/$2$1')
} else {
return source
}
}
const fs = require('fs')
const path = require('path')
const OSS = require('ali-oss')
const conf = require('./config')
const client = new OSS({
region: 'oss-cn-beijing',
accessKeyId: 'LTAIOTuuLTaWoGJj',
accessKeySecret: 'dE5tTGm2lh35eItct2krW2DeH2lf2I',
bucket: 'zws-imgs-pub'
})
const headers = {
'x-oss-traffic-limit': 8 * 1024 * 100 * 100
}
const DIR_PATH = path.join(__dirname, '../' + conf.DesDir)
const PREFIX_PATH = conf.CDN_DIR
const isUploadStatic = conf.isUploadStatic
let fileCount = 1
async function uploadFile (prefixPath, dirFileName) {
try {
const upFilePath = prefixPath.replace(new RegExp(DIR_PATH, 'gi'), '') + path.basename(dirFileName)
const result = await client.put(prefixPath + path.basename(dirFileName), dirFileName, {
headers,
timeout: 600000
})
if (result.res.status === 200) {
console.log('第' + fileCount++ + '个文件,已上传:' + conf.CDN_BASE + upFilePath)
return { status: 200 }
}
} catch (err) {
console.log('第' + fileCount++ + '个文件,上传失败:' + conf.CDN_BASE + upFilePath)
return { status: 500, err: err }
}
}
function uploadfiles (dirPath, callback) {
const files = fs.readdirSync(dirPath)
files.forEach(function (filename, i) {
const filedir = path.join(dirPath, filename)
const info = fs.statSync(filedir)
if (info.isDirectory()) {
if (!(isUploadStatic ? true : filename !== 'static')) { return }
const morePath = filedir.replace(new RegExp(DIR_PATH, 'gi'), '') + '/'
uploadfiles(filedir, function (filedir) {
uploadFile(path.join(PREFIX_PATH, morePath), filedir)
})
} else {
if (typeof callback === 'function') {
callback(filedir)
} else {
uploadFile(PREFIX_PATH, filedir)
}
}
})
return true
}
uploadfiles(DIR_PATH, null)
const path = require('path')
const webpack = require('webpack')
const WebpackMerge = require('webpack-merge')
const _conf = require('./config')
const $GLOBAL = {
isDev: _conf.isDev,
ResDir: _conf.ResDir,
'isEnableToIphoneDebugger': _conf.isEnableToIphoneDebugger,
templatePath: path.resolve(__dirname, '../' + _conf.HtmlPath),
icoPath: _conf.IcoPath,
EntryPath: path.resolve(__dirname, '../' + _conf.JsPath),
OutputPath: path.resolve(__dirname, '../' + _conf.DesDir),
jsName: 'resources/[name].[chunkhash:8].js',
cssName: 'resources/[name].[contenthash:12].css',
resName: 'resources/[name].[hash:8].[ext]',
EntryStaticPath: path.resolve(__dirname, '../' + 'static'),
OutputStaticPath: path.resolve(__dirname, '../' + _conf.DesDir + '/static'),
RegStrs: _conf.RegStrs,
webConf: {
'isDev': _conf.isDev,
'serverPort': process.env.SERVER_PORT || 8000,
'isEnableToIphoneDebugger': _conf.isEnableToIphoneDebugger,
'domain': _conf.domain,
'url': _conf.url,
'isHttps': _conf.isHttps,
'apiBaseURL': _conf.apiBaseURL || '/api',
'CDN_PATH': _conf.CDN_BASE + _conf.CDN_DIR,
'others': _conf.others || {}
},
externals: _conf.webpack.externals || {},
ProvidePlugin: _conf.webpack.ProvidePlugin || {},
BaseConfig: {}
}
$GLOBAL.BaseConfig = {
target: 'web',
entry: $GLOBAL.EntryPath,
output: {
filename: $GLOBAL.jsName,
path: $GLOBAL.OutputPath,
publicPath: $GLOBAL.isDev === 'development' ? '/' : $GLOBAL.webConf.CDN_PATH
},
resolve: {
alias: {
'@': path.resolve(__dirname, '../' + $GLOBAL.ResDir),
'@api': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/api'),
'@action': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/action'),
'@tool': path.resolve(__dirname, '../' + $GLOBAL.ResDir + '/tool')
},
extensions: ['.js', '.json', '.jsx', '.vue']
},
module: {
rules: [
{
test: /\.(vue|js|jsx)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
enforce: 'pre'
},
{
test: /\.(vue|js|jsx)|((sa|sc|c)ss)$/,
loader: './build/stringReplaceLoader.js',
exclude: /node_modules/,
enforce: 'pre'
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /(\.jsx|\.js)$/,
exclude: /(node_modules)|(dist)/,
loader: 'babel-loader',
options: {
presets: [[
'@babel/preset-env',
{
"targets": {
"browsers": [
"last 2 versions",
"ie >= 11"
],
},
corejs: '3.6.5',
useBuiltIns: 'usage'
}
]],
plugins: [
'@babel/plugin-syntax-jsx',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-syntax-dynamic-import',
[
'@babel/plugin-transform-runtime',
{
corejs: 3,
helpers: true,
regenerator: true,
useESModules: false
}
]
]
}
},
{
test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,
use: {
loader: 'url-loader',
options: {
esModule: false,
limit: 4096,
name: $GLOBAL.resName
}
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: $GLOBAL.resName
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: $GLOBAL.resName
}
}
]
},
externals: {
},
plugins: [
new webpack.DefinePlugin({
'webConf': JSON.stringify($GLOBAL.webConf)
}),
new webpack.ProvidePlugin($GLOBAL.ProvidePlugin)
]
}
$GLOBAL.BaseConfig = WebpackMerge($GLOBAL.BaseConfig, _conf.webpack)
module.exports = $GLOBAL
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const WebpackMerge = require('webpack-merge')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const AutoPrefixer = require('autoprefixer')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlReplaceWebpackPlugin = require('html-replace-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const VconsoleWebpackPlugin = require('vconsole-webpack-plugin')
const $GLOBAL = require('./webpack.base.conf')
let config = null
if ($GLOBAL.isDev === 'development') {
config = WebpackMerge($GLOBAL.BaseConfig, {
mode: 'development',
devtool: '#cheap-module-eval-source-map',
output: {
filename: '[name].js'
},
devServer: {
port: $GLOBAL.webConf.serverPort,
disableHostCheck: false,
host: $GLOBAL.webConf.domain || 'localhost',
http2: false,
https: $GLOBAL.webConf.isHttps && {
key: fs.readFileSync(path.join(__dirname, $GLOBAL.webConf.domain + '.key')),
cert: fs.readFileSync(path.join(__dirname, $GLOBAL.webConf.domain + '.pem'))
},
overlay: {
errors: true
},
historyApiFallback: {
index: '/index.html'
},
proxy: {
'/api': {
target: $GLOBAL.webConf.url,
selfHandleResponse: false,
secure: false,
changeOrigin: true,
followRedirects: true,
logLevel: 'info',
headers: {
'Referer': $GLOBAL.webConf.url
},
pathRewrite: {
'^/api': '/'
}
}
},
open: true,
hot: true
},
module: {
rules: [{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
AutoPrefixer({
'overrideBrowserslist': [
'cover 99.5%',
'ie 6-8',
'since 2015',
'last 10 iOS versions'
]
})
]
}
},
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
charset: false
}
}
}
]
}]
},
plugins: [
new VueLoaderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: $GLOBAL.templatePath,
inject: true,
favicon: $GLOBAL.icoPath
}),
new VconsoleWebpackPlugin({
filter: [],
enable: $GLOBAL.isEnableToIphoneDebugger
})
]
})
} else {
config = WebpackMerge($GLOBAL.BaseConfig, {
mode: 'production',
entry: {
app: $GLOBAL.EntryPath,
vendor: ['vue', 'vue-router', 'vue-i18n']
},
module: {
rules: [{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
}
},
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
AutoPrefixer({
'overrideBrowserslist': [
'cover 99.5%',
'ie 6-8',
'since 2015',
'last 10 iOS versions'
]
})
]
}
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass')
}
}
]
}]
},
plugins: [
new CleanWebpackPlugin(['**/*'], { root: $GLOBAL.OutputPath }),
new MiniCssExtractPlugin({
filename: '[name].[contenthash:12].css',
chunkFilename: $GLOBAL.cssName
}),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: $GLOBAL.templatePath,
inject: true,
favicon: $GLOBAL.icoPath,
minify: {
removeComments: true,
collapseWhitespace: true
}
}),
new HtmlReplaceWebpackPlugin([
{
pattern: $GLOBAL.RegStrs.regExp_static,
replacement: '$1' + $GLOBAL.webConf.CDN_PATH + 'static/$2$1'
}
]),
new CopyWebpackPlugin([
{
from: $GLOBAL.EntryStaticPath,
to: $GLOBAL.OutputStaticPath,
ignore: ['.*'],
transform: function (content) {
return content
}
}
]),
new VconsoleWebpackPlugin({
filter: [],
enable: $GLOBAL.isEnableToIphoneDebugger
})
],
optimization: {
runtimeChunk: {
name: 'manifest'
},
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 400000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: false,
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'initial',
priority: -10,
reuseExistingChunk: false,
test: /node_modules\/(.*)\.js/
},
}
}
}
})
}
module.exports = config
const fs = require('fs')
const path = require('path')
const axios = require('axios')
const domain = 'ezijing.com'
const outputPath = './https'
// 生成文件夹
function genOutputDir() {
if (fs.existsSync(outputPath)) {
console.log('The path exists.')
} else {
fs.mkdir(outputPath, { recursive: true }, err => {
if (err) throw err
})
}
}
function downloadCertFile() {
genOutputDir()
axios.get(`https://ssl.godzyx.com/${domain}/${domain}.key?get=allow`, { responseType: 'stream' }).then(response => {
response.data.pipe(fs.createWriteStream(path.join(__dirname, `${outputPath}/${domain}.key`)))
})
axios.get(`https://ssl.godzyx.com/${domain}/${domain}.pem?get=allow`, { responseType: 'stream' }).then(response => {
response.data.pipe(fs.createWriteStream(path.join(__dirname, `${outputPath}/${domain}.pem`)))
})
}
downloadCertFile()
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const OSS = require('ali-oss')
const log = console.log
const client = new OSS({
region: 'oss-cn-beijing',
accessKeyId: 'LTAIOTuuLTaWoGJj',
accessKeySecret: 'dE5tTGm2lh35eItct2krW2DeH2lf2I',
bucket: 'webapp-pub'
})
async function uploadTarget(src, dist) {
try {
const result = await client.put(dist, path.join(__dirname, src))
log(chalk.green('上传成功', result.url))
} catch (e) {
log(chalk.red('上传失败', src))
log(e)
}
}
function generateUploadTarget(src, dist) {
fs.readdir(path.join(__dirname, src), function (err, files) {
if (err) {
log(err)
return
}
files.forEach(function (file) {
const _src = src + '/' + file
const _dist = dist + '/' + file
const stats = fs.statSync(path.join(__dirname, _src))
// 判断是否为文件
stats.isFile() && uploadTarget(_src, _dist)
// 判断是否为文件夹
stats.isDirectory() && generateUploadTarget(_src, _dist)
})
})
}
generateUploadTarget('./dist', '/website/prod/shop-center')
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpgI5jWzjG7wmk8
V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAflET2EpILLera
I1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5ClzgnSptMenXFyhw
5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4HhCt7T7sA/UN
ahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqyrwjN3gkaa+1T
jLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABAoIBACuMmaXYz6OHmroI
HNCIH9E+F0UIUyVg4/1gj9uoqKvdAx04WPphRyRo8AXhgSOWmfb/UnCqX1fqVvj2
BfzwehsEzO9wp/aBT/3IzM6RQHPoI5DXX98prSY0SlRqr4RXi3CSOFN4duoLMOOI
mlzdXUKttVpSvJixerqQPeT7HnC18NBKOydFMYPdXsgWcMXvu2BuvRClIzsjlXKM
VP00BNRY3Oje6T9yl8N051jIZh48YD3yyEAVFKPOWaJVzUU/RRPOOdTb2Y3A1bek
IbCdurdzoEQoJxkeTuColnuL1jj2mpxIBskKYhPAMV5arYS0pZ0VAtjoGGCyn7gT
l/bkTVkCgYEA6EB15hzRD2iTTIFMtDBqw0l3vJWcuWPvwFZl6zculO8Cdsvx0cDZ
VbEXByA0+CG3q47/UrVqETRhtyuVnxuKrceKU8/zib1dvvTMNjeYLKosjyG49xO6
gDx7nVBwYHmQN/iEuWTobLg1vtSNyd99WgG4cFHvqF7kIJb2W0IaGrsCgYEAzL70
VHn9BUP3CGecoU8Fnck9/7GWhvGgFU58Q/dU3Jr8g6lroeDas9zQU2tCnJN0e7cr
13thq2kQQHTYCY4J6EUtjO89sNVx4bO83xqQhobZBwZXkE5QDWIKCbiYGRLAb1+f
AAEwIEdPBgM88YFHOU5YbPTYH8TLkJfxyvMonu0CgYEArGWE3n3PdVeT1zs3O52g
8jrrpVGNF1QmWCgJ2VKJwkW0F4iFhMRYzzH3vPNcPj+Q/cjUn4lIJWMzkWrJ0mP4
ScyPUm1PApRNLPy7RRd5XtYm40wN52F+k8fRnlFiSUqTEejoZFGR8Xm/c1qFsS6y
9ofGZ6F6ewmM3uAQGGd1xxcCgYBFhjoVTW8bkJ6b3gMTy2+Oyr0gzD7fB8FiOsp7
kcrhNke0tZz01ROuq7aZ/Pwbiv6s2+ApRZ4+xGheWs7ZP8AhfQwgpUR/fZs0FwJ1
h+G3rKaZeg/V0qHgSYA7GNGdAf8SUpf9OmoLK+urkQHqyAlVbkMcjG+vKfYt3Uqf
rb4HaQKBgQCxm1oz9QrmxWKJ4eYKHSsD9UPu4QZhltBECH1btgvTwAEmwuXaCcta
RaFNhMe609sQ+YVIxa9fK0MXBiq7DG6nSLGvnLfVEYo4nGe6EvL9nQ7IFZywJjTb
/Fw4rTMwT59VSWJdv8BPznV7Gk7p17fcXM55iJxxu65r3ZuOXjQSGA==
-----END RSA PRIVATE KEY-----
\ No newline at end of file
-----BEGIN CERTIFICATE-----
MIIGtjCCBZ6gAwIBAgIQDjUArTRdZ4P5wtQVmCqJGjANBgkqhkiG9w0BAQsFADBj
MQswCQYDVQQGEwJDTjE2MDQGA1UECgwtQmVpamluZyBYaW5jaGFjaGEgQ3JlZGl0
IE1hbmFnZW1lbnQgQ28uLCBMdGQuMRwwGgYDVQQDDBNYY2MgVHJ1c3QgT1YgU1NM
IENBMB4XDTIyMDgxODE0MDAzMVoXDTIzMDkxNzE0MDAzMFowgY4xCzAJBgNVBAYT
AkNOMRIwEAYDVQQIDAnljJfkuqzluIIxEjAQBgNVBAcMCeWMl+S6rOW4gjE/MD0G
A1UECgw25riF5o6n57Sr6I2G77yI5YyX5Lqs77yJ5pWZ6IKy56eR5oqA6IKh5Lu9
5pyJ6ZmQ5YWs5Y+4MRYwFAYDVQQDDA0qLmV6aWppbmcuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAucCbdPPyAp6vmnr5XObuPsctUhVLyXwqbIpg
I5jWzjG7wmk8V6z8WJKPO9KZM6D9ejtN/bbbd3j1cRiw7NSl8AUykiVHJWz9TXAf
lET2EpILLeraI1B2XAcBsc8dZBGGJD/LT97ZvNLYzuQOr7R1wytWH1uisAK5Clzg
nSptMenXFyhw5Xw0Lm3zoeeqYF/KMQ1McAYMGxgu6s6dxXKiA0BcgWQ31yZey0c4
HhCt7T7sA/UNahUsxtCcSNSvdgXay5Pu/l3N88TwW2QzaCzrueILHWRFwkREhpqy
rwjN3gkaa+1TjLxzCsk/pTnPccxlFwc3YQ3hYLMl36NJ/OIpHwIDAQABo4IDODCC
AzQwDAYDVR0TAQH/BAIwADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8veGluY2hh
Y2hhMm92LmNybC5jZXJ0dW0ucGwveGluY2hhY2hhMm92LmNybDB5BggrBgEFBQcB
AQRtMGswLwYIKwYBBQUHMAGGI2h0dHA6Ly94aW5jaGFjaGEyb3Yub2NzcC1jZXJ0
dW0uY29tMDgGCCsGAQUFBzAChixodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwv
eGluY2hhY2hhMm92LmNlcjAfBgNVHSMEGDAWgBT6oMvCx12BtSCSByALtjtwOwkO
VTAdBgNVHQ4EFgQUEJufsd5nLNR+wqR2GsFWDn7qTn0wTAYDVR0gBEUwQzAIBgZn
gQwBAgIwNwYMKoRoAYb2dwIFARYCMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8vd3d3
LmNlcnR1bS5wbC9DUFMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4G
A1UdDwEB/wQEAwIFoDAlBgNVHREEHjAcgg0qLmV6aWppbmcuY29tggtlemlqaW5n
LmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYAVYHUwhaQNgFK6gubVzxT
8MDkOHhwJQgXL6OqHQcT0wwAAAGCsUFwdgAABAMARzBFAiAc51lynft4sehXTgyw
tjQ83PAVmfZ3FC55eIpIETe2hgIhANvo5ZtGQpcZQ5HSGbRLy4Y9/MbUrS8dtkwP
l7I/lRj7AHYArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooAAAGCsUFw
TwAABAMARzBFAiATnQDMw1wykBdnTIRfSSXPj7HZfDdRRq6VaiTbSpYKYQIhAMTp
V6K0W9gtdYGdeg4j6n17S1yMODYvLJxd3kAFFNDTAHYAejKMVNi3LbYg6jjgUh7p
hBZwMhOFTTvSK8E6V6NS61IAAAGCsUFwrQAABAMARzBFAiEAwWKXKxp6DcKG7R/d
rxmPUg8uNbUcdxysrpB3gOzkIlACICWpx7/+2ulDG2EC9m4RqGcXbts3VWu/yxpE
0pAYuAP8MA0GCSqGSIb3DQEBCwUAA4IBAQCf3AdKLO8EUntMjKaRa0lncwh/pBIQ
bcQfkJBfiTpo6tnRphR+DE50oYOX1TSQRm4cDgP2JURYiTK6Z2+ljqMbUx4mNLqe
+6yG+PGCUX6rX4BsJqlRP2W7WONE/I3/3S6MRfclKmakHSyrGFi8O/JJyNqm+5z9
8tnk8c1Cn7FboJZonhX0yszHkXLLeA93xm5+Etkw0+DvRcZGiEqKQivO3CnUh1gs
LZg27a8s3dtmAAHbb2icm5jloK9Jgpx/NkGL/cCoNZ8Ng2TZkRvo6GzIp43uS332
R07dQ6rNWZkPzdxKUdNcT0v3yJJyxD1H3Rk4/bxp78giw4JGHp52Df+U
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEzzCCA7egAwIBAgIRAPJECC2rqQ2ljHLp8pqTQK4wDQYJKoZIhvcNAQELBQAw
fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTAeFw0yMjA3MDEwNzQ4NDda
Fw0yNzA2MzAwNzQ4NDdaMGMxCzAJBgNVBAYTAkNOMTYwNAYDVQQKDC1CZWlqaW5n
IFhpbmNoYWNoYSBDcmVkaXQgTWFuYWdlbWVudCBDby4sIEx0ZC4xHDAaBgNVBAMM
E1hjYyBUcnVzdCBPViBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCz2nxSPEsMeRBdunf+KZ8CrJIj9DUWGVu05WWyES+QkMHzVHCZt8cB2Blp
qzHHqFsXSDHVzcMxDeXBbudmQwYbg5NpSwY9vJHPTl6vlAlK4UWN4+oPTgP9//RN
N6KLmK3kjZ2Zc9F3kFKVaziSwVNjVvneacoUnz6blwLLBc5QelQ8oDT0eEv0QBAY
I0T8pHDgcvWQqTBaRrOb80plDhYju464XbVhtOHvFCiBIkKnfUBnBfptWjGM8Kis
sq4r8YX35B/pioj9g1YX34MLt+5L3vvWXEb2aMiwwB1Z3bSeeiU3N8aMuSb9E9jp
zd0uhzRameU7jAIAr8uuunb7GUJ7AgMBAAGjggFhMIIBXTASBgNVHRMBAf8ECDAG
AQH/AgEAMB0GA1UdDgQWBBT6oMvCx12BtSCSByALtjtwOwkOVTAfBgNVHSMEGDAW
gBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0lBBYw
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9j
cmwuY2VydHVtLnBsL2N0bmNhLmNybDBrBggrBgEFBQcBAQRfMF0wKAYIKwYBBQUH
MAGGHGh0dHA6Ly9zdWJjYS5vY3NwLWNlcnR1bS5jb20wMQYIKwYBBQUHMAKGJWh0
dHA6Ly9yZXBvc2l0b3J5LmNlcnR1bS5wbC9jdG5jYS5jZXIwOgYDVR0gBDMwMTAv
BgRVHSAAMCcwJQYIKwYBBQUHAgEWGWh0dHBzOi8vd3d3LmNlcnR1bS5wbC9DUFMw
DQYJKoZIhvcNAQELBQADggEBACWzdb59JyYc/WivKUcTEZ+H8WOTuv3AiR6rPljB
QUEB/1kxIeBK+276WLJn0nFNFuT9QMUBo/iUvNvuRQqVjouuYB0Oea6zKQpeMWry
oYtbheW+5NYAbdl9tYE4MRRK9zBLMRrQz35q+XfgMInozidhNHCvuulWk38OMM51
O73z53+R1879nnoZZznoYnrnkISVDjlhe6OSMifvIJAwSYwH2z79Y6CTVgtqTDR9
793Gr7UUmk5ydoxClxnku7voTX8iJUPcuAjElxFrhSQoxm6uXXOfItEqGvLkWAcq
IC5mcyU9VpUg1YP+KkDMh+KQM7/k+2ka1em9hO+QHvJ08UQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEtDCCA5ygAwIBAgIRAJOShUABZXFflH8oj+/JmygwDQYJKoZIhvcNAQELBQAw
PjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHogby5vLjESMBAG
A1UEAxMJQ2VydHVtIENBMB4XDTA4MTAyMjEyMDczN1oXDTI3MDYxMDEwNDYzOVow
fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAOP7faNyusLwyRSH9WsBTuFuQAe6bSddf/dbLbNax1Ff
q6QypmGHtm4PhtIwApf412lXoRg5XWpkecYBWaw8MUo4fNIE0kso6CBfOweizE1z
2/OuT8dW1Vqnlon686to1COGWSfPCSe8rG5ygxwwct/gounS4XR1Gb0qnnsVVAQb
10M5rVUoxeIau/TA5K44STPMdoWfOUXSpJ7yEoxR+HzkLX/1rF/rFp+xLdG6zJFC
d0wlyZA4b9vwzPuOHpdZPtVgTuYFKO1JeRNLukjbL/ly0znK/h/YNHL1tEDPMQHD
7N4RLRddH7hQ0V4Zp2neBzMoylCV+adUy1SGUEWp+UkCAwEAAaOCAWswggFnMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAh2zcsH/yT2xc3tu5C84oQ3RnX3MFIG
A1UdIwRLMEmhQqRAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNw
LiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQYIDAQAgMA4GA1UdDwEB/wQEAwIB
BjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vY3JsLmNlcnR1bS5wbC9jYS5jcmww
aAYIKwYBBQUHAQEEXDBaMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1j
ZXJ0dW0uY29tMC4GCCsGAQUFBzAChiJodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0u
cGwvY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw
Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAI3m/UBmo0yc
p6uh2oTdHDAH5tvHLeyDoVbkHTwmoaUJK+h9Yr6ydZTdCPJ/KEHkgGcCToqPwzXQ
1aknKOrS9KsGhkOujOP5iH3g271CgYACEnWy6BdxqyGVMUZCDYgQOdNv7C9C6kBT
Yr/rynieq6LVLgXqM6vp1peUQl4E7Sztapx6lX0FKgV/CF1mrWHUdqx1lpdzY70a
QVkppV4ig8OLWfqaova9ML9yHRyZhpzyhTwd9yaWLy75ArG1qVDoOPqbCl60BMDO
TjksygtbYvBNWFA0meaaLNKQ1wmB1sCqXs7+0vehukvZ1oaOGR+mBkdCcuBWCgAc
eLmNzJkEN0k=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
...@@ -2,26 +2,19 @@ ...@@ -2,26 +2,19 @@
<html lang="zh-cn"> <html lang="zh-cn">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <link rel="icon" href="https://zws-imgs-pub.ezijing.com/pc/base/favicon.ico" />
<meta content="origin" name="referrer" /> <meta name="theme-color" content="#3276fc" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>紫荆商城管理系统</title> <title>紫荆商城管理系统</title>
<meta <meta
name="viewport" name="viewport"
id="viewport" id="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no, viewport-fit=cover" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no, viewport-fit=cover" />
/>
<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>
<script src="https://webapp-pub.ezijing.com/plugins/tinymce/tinymce.min.js"></script> <script src="https://webapp-pub.ezijing.com/plugins/tinymce/tinymce.min.js"></script>
<script <script src="https://webapi.amap.com/maps?v=2.0&key=572e880cdfcfc420c7a2604e337e4e39"></script>
type="text/javascript"
src="https://webapi.amap.com/maps?v=2.0&key=572e880cdfcfc420c7a2604e337e4e39"
></script>
</body> </body>
</html> </html>
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist"],
"vueCompilerOptions": {
"target": 2.7
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "@god/vue-client", "name": "shop-admin",
"version": "3.0.14",
"description": "适应于公司全系统的纯客户端开发模型",
"main": "index.js",
"scripts": { "scripts": {
"lint": "eslint --ext .js --ext .jsx --ext .vue src/", "build": "vite build --mode prod && npm run deploy",
"lint:fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/", "build:pre": "vite build --mode pre",
"dev": "vite",
"build": "vite build --mode test",
"build:test": "vite build --mode test", "build:test": "vite build --mode test",
"build:pro": "npm run check:node && cross-env NODE_ENV=production webpack --progress --config build/webpack.client.conf.js && cross-env NODE_ENV=production node ./build/uploadAliyunCDN.js", "cert": "node ./cert.js",
"check:node": "node build/checkNodeVersion.js" "deploy": "node ./deploy.js",
}, "dev": "vite --mode dev",
"repository": { "lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"type": "git", "preview": "vite preview"
"url": ""
},
"keywords": [
"vue-client"
],
"author": "zhangyanxin",
"license": "ISC",
"eslintIgnore": [
"client-dist/",
"node_modules/",
"assets/font-icons/"
],
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-jsx": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.11.5",
"@babel/preset-env": "^7.11.5",
"@babel/runtime-corejs3": "^7.11.2",
"acorn": "^7.1.1",
"ali-oss": "^6.15.2",
"autoprefixer": "^9.8.6",
"babel-eslint": "^10.1.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^1.0.1",
"copy-webpack-plugin": "^5.1.2",
"css-loader": "^4.3.0",
"dart-sass": "^1.25.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.1",
"eslint-loader": "^3.0.4",
"eslint-plugin-html": "^6.1.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"file-loader": "^6.1.1",
"html-replace-webpack-plugin": "^2.5.6",
"html-webpack-plugin": "^4.5.0",
"mini-css-extract-plugin": "^0.9.0",
"postcss-loader": "^3.0.0",
"request": "^2.88.2",
"sass-loader": "^10.0.3",
"semver": "^1.1.4",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"vconsole-webpack-plugin": "^1.5.2",
"vite": "^2.4.1",
"vite-plugin-vue2": "^1.7.2",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2"
}, },
"dependencies": { "dependencies": {
"@tinymce/tinymce-vue": "^3.2.8", "@tinymce/tinymce-vue": "^3.2.8",
"axios": "^0.21.1", "axios": "^0.21.4",
"blueimp-md5": "^2.18.0", "blueimp-md5": "^2.19.0",
"clipboard": "^2.0.8", "clipboard": "^2.0.11",
"core-js": "^3.12.1", "dayjs": "^1.11.6",
"cross-env": "^7.0.3", "element-ui": "^2.15.10",
"dayjs": "^1.10.5",
"element-ui": "^2.15.2",
"js-file-download": "^0.4.12", "js-file-download": "^0.4.12",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"qrcode.vue": "^1.7.0", "qrcode.vue": "^1.7.0",
"vue": "^2.6.12", "vue": "^2.7.13",
"vue-i18n": "^8.24.4", "vue-i18n": "^8.28.2",
"vue-loader": "^15.9.7", "vue-router": "^3.6.5",
"vue-router": "^3.5.1",
"vue-template-compiler": "^2.6.12",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"engines": { "devDependencies": {
"node": ">=8.9" "@vitejs/plugin-vue2": "^2.0.0",
"ali-oss": "^6.17.1",
"chalk": "^5.1.2",
"eslint": "^8.26.0",
"eslint-plugin-vue": "^9.7.0",
"sass": "^1.55.0",
"vite": "^3.2.2",
"vite-plugin-checker": "^0.5.1"
} }
} }
...@@ -102,6 +102,6 @@ export function getSkuList(data) { ...@@ -102,6 +102,6 @@ export function getSkuList(data) {
/** /**
* 获取费用类型 * 获取费用类型
*/ */
export function getFeeTypes(data) { export function getFeeTypes(params) {
return httpRequest.get('/api/zws/v1/finance/payments/payments-type') return httpRequest.get('/api/zws/v1/finance/payments/payments-type', { params })
} }
@import '@/assets/theme/index.css'; html * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
outline: none;
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body, body,
h1, h1,
h2, h2,
...@@ -49,6 +55,10 @@ em, ...@@ -49,6 +55,10 @@ em,
i { i {
font-style: normal; font-style: normal;
} }
strong,
b {
font-weight: normal;
}
img { img {
border: none; border: none;
} }
...@@ -69,31 +79,8 @@ textarea { ...@@ -69,31 +79,8 @@ textarea {
-webkit-appearance: none; -webkit-appearance: none;
border: 0; border: 0;
border-radius: 0; border-radius: 0;
font: inherit;
} }
textarea:focus { textarea:focus {
outline: 0; outline: 0;
} }
html {
font-size: 100px;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
:root {
--main-color: #5b91fd;
}
body {
font-size: 14px;
line-height: 1.4;
color: #222;
font-family: 'PingFang SC', 'Source Han Sans CN', -apple-system, 'Microsoft YaHei', 'Helvetica', 'Arial', Verdana,
'Hiragino Sans GB', 'Wenquanyi Micro Hei', sans-serif;
}
.empty {
padding: 120px;
text-align: center;
font-size: 18px;
color: #999;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
$--color-primary: #3276fc;
$--color-info: #3c4043;
// border
$--border-radius-small: 8px !default;
// dialog
$--message-close-size: 20px !default;
/* 改变 icon 字体路径变量,必需 */
$--font-path: 'element-ui/lib/theme-chalk/fonts';
@import 'element-ui/packages/theme-chalk/src/index';
<template> <template>
<div class="info-list"> <div class="info-list" v-if="data">
<div class="item" v-for="(item, index) in options" :key="index" v-if="data"> <div class="item" v-for="(item, index) in options" :key="index">
<div class="title">{{item.label}}</div> <div class="title">{{ item.label }}</div>
<div class="content"> <div class="content">
<!-- html --> <!-- html -->
<template v-if="item.isHtml"> <template v-if="item.isHtml">
...@@ -10,25 +10,40 @@ ...@@ -10,25 +10,40 @@
</template> </template>
<template v-else> <template v-else>
<div v-if="item.type === 'image'"> <div v-if="item.type === 'image'">
<img v-if="item.computed" height="100" width="100" :data-src="item.computed($lodash.get(data, item.code))" :src="item.computed($lodash.get(data, item.code))" /> <img
<img v-else height="100" width="100" :data-src="$lodash.get(data, item.code)" :src="$lodash.get(data, item.code)" /> v-if="item.computed"
height="100"
width="100"
:data-src="item.computed($lodash.get(data, item.code))"
:src="item.computed($lodash.get(data, item.code))" />
<img
v-else
height="100"
width="100"
:data-src="$lodash.get(data, item.code)"
:src="$lodash.get(data, item.code)" />
</div> </div>
<div v-else-if="item.type === 'tree'"> <div v-else-if="item.type === 'tree'">
<el-tree class="filter-tree" :data="$lodash.get(data, item.code)" :props="item.props" default-expand-all ref="tree"></el-tree> <el-tree
class="filter-tree"
:data="$lodash.get(data, item.code)"
:props="item.props"
default-expand-all
ref="tree"></el-tree>
</div> </div>
<div v-else-if="item.type === 'a'"> <div v-else-if="item.type === 'a'">
<p> <p>
{{$lodash.get(data, item.code)}} {{ $lodash.get(data, item.code) }}
</p> </p>
<a v-if="item.computed" @click="item.computed()"> <a v-if="item.computed" @click="item.computed()">
{{item.text}} {{ item.text }}
</a> </a>
<a v-else target="_blank" :href="item.href"> <a v-else target="_blank" :href="item.href">
{{item.text}} {{ item.text }}
</a> </a>
</div> </div>
<div v-else-if="item.computed">{{item.computed($lodash.get(data, item.code))}}</div> <div v-else-if="item.computed">{{ item.computed($lodash.get(data, item.code)) }}</div>
<div v-else>{{$lodash.get(data, item.code)}}</div> <div v-else>{{ $lodash.get(data, item.code) }}</div>
</template> </template>
</div> </div>
</div> </div>
...@@ -44,7 +59,7 @@ export default { ...@@ -44,7 +59,7 @@ export default {
} }
</script> </script>
<style scoped> <style scoped>
.info-list { .info-list {
padding: 10px; padding: 10px;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<script> <script>
export default { export default {
props: { data: { type: Object, default: () => [] } }, props: { data: { type: Object } },
data() { data() {
return { return {
list: [ list: [
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
<td <td
:key="`tbody_td_${tdIndex}`" :key="`tbody_td_${tdIndex}`"
:rowspan="td.rowspan" :rowspan="td.rowspan"
v-if="td.rowspan === 1 || (trIndex === 0 ? true : trIndex % td.rowspan === 0)" v-if="td.rowspan === 1 || (trIndex === 0 ? true : trIndex % td.rowspan === 0)">
>
<div class="cell">{{ td.spec_value }}</div> <div class="cell">{{ td.spec_value }}</div>
</td> </td>
</template> </template>
...@@ -28,8 +27,7 @@ ...@@ -28,8 +27,7 @@
size="small" size="small"
v-model="tr.stock[td.key]" v-model="tr.stock[td.key]"
class="sku-input" class="sku-input"
v-if="tr.stock" v-if="tr.stock"></el-input>
></el-input>
</template> </template>
<template v-else>{{ tr.stock[td.key] }}</template> <template v-else>{{ tr.stock[td.key] }}</template>
</td> </td>
...@@ -208,7 +206,7 @@ export default { ...@@ -208,7 +206,7 @@ export default {
}, },
// 批量保存 // 批量保存
primaryBatchUpdate() { primaryBatchUpdate() {
this.stockList.forEach((item, index) => { this.stockList.forEach(item => {
item[this.batchKey] = this.batchInputValue item[this.batchKey] = this.batchInputValue
}) })
this.closeBatchUpdate() this.closeBatchUpdate()
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
ref="input" ref="input"
@blur="onInputBlur" @blur="onInputBlur"
@keyup.enter.native="onInputBlur" @keyup.enter.native="onInputBlur"
v-if="inputVisible" v-if="inputVisible" />
/>
<el-button type="text" @click="addSkuValue" v-if="!inputVisible"> <el-button type="text" @click="addSkuValue" v-if="!inputVisible">
<i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;添加规格值 <i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;添加规格值
</el-button> </el-button>
...@@ -76,14 +75,14 @@ export default { ...@@ -76,14 +75,14 @@ export default {
return return
} }
const params = { shop_id: this.shopId, spec_id: this.data.spec_id, spec_value: value } const params = { shop_id: this.shopId, spec_id: this.data.spec_id, spec_value: value }
addSkuValue({ data: [params] }).then(res => { addSkuValue({ data: [params] }).then(() => {
this.toggleInputVisible() this.toggleInputVisible()
this.$emit('update') this.$emit('update')
}) })
}, },
// 删除规格 // 删除规格
removeSku(data) { removeSku(data) {
deleteSku({ shop_id: this.shopId, spec_id: data.spec_id }).then(response => { deleteSku({ shop_id: this.shopId, spec_id: data.spec_id }).then(() => {
this.$message({ type: 'success', message: '删除成功' }) this.$message({ type: 'success', message: '删除成功' })
this.$emit('update') this.$emit('update')
}) })
...@@ -91,7 +90,7 @@ export default { ...@@ -91,7 +90,7 @@ export default {
// 删除规格值 // 删除规格值
removeSkuValue(data) { removeSkuValue(data) {
deleteSkuValue({ shop_id: this.shopId, spec_id: this.data.spec_id, spec_value_id: data.spec_value_id }).then( deleteSkuValue({ shop_id: this.shopId, spec_id: this.data.spec_id, spec_value_id: data.spec_value_id }).then(
response => { () => {
this.$message({ type: 'success', message: '删除成功' }) this.$message({ type: 'success', message: '删除成功' })
this.$emit('update') this.$emit('update')
} }
......
import { getSignature, uploadFile } from '@/api/base' import { getSignature, uploadFile } from '@/api/base'
import md5 from 'blueimp-md5' import md5 from 'blueimp-md5'
export default function(blobInfo, succFun, failFun) { export default function (blobInfo, succFun, failFun) {
const file = blobInfo.blob() const file = blobInfo.blob()
getSignature() getSignature()
.then(response => { .then(response => {
...@@ -19,7 +19,7 @@ export default function(blobInfo, succFun, failFun) { ...@@ -19,7 +19,7 @@ export default function(blobInfo, succFun, failFun) {
failFun('上传失败') failFun('上传失败')
}) })
}) })
.catch(response => { .catch(() => {
failFun('获取Signature失败') failFun('获取Signature失败')
}) })
} }
...@@ -2,20 +2,19 @@ import Vue from 'vue' ...@@ -2,20 +2,19 @@ import Vue from 'vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
import App from './app.vue' import App from './app.vue'
// 公共css
import './assets/css/base.css'
// Element-UI
import ElementUI from 'element-ui' import ElementUI from 'element-ui'
import './style.scss' import './assets/theme/style.scss'
import BeforeEnter from './utils/beforeEnter' import beforeEnter from './utils/beforeEnter'
const before = new BeforeEnter()
Vue.use(ElementUI) Vue.use(ElementUI)
/* 导航守卫 */ /* 导航守卫 */
router.beforeEach((to, from, next) => { router.beforeEach(beforeEnter)
before.update(to, from, next)
})
Vue.prototype.msgCenter = new Vue()
new Vue({ new Vue({
store, store,
......
<template></template> <template>
<div></div>
</template>
<script> <script>
export default {} export default {}
</script> </script>
<style>
</style>
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
label-position="top" label-position="top"
ref="ruleForm" ref="ruleForm"
@submit.native.prevent @submit.native.prevent
v-show="stepActive === 1" v-show="stepActive === 1">
>
<app-card title="商品类型"> <app-card title="商品类型">
<el-radio-group v-model="ruleForm.category_id"> <el-radio-group v-model="ruleForm.category_id">
<el-radio :label="item.id" border v-for="item in categoryList" :key="item.id">{{ item.name }}</el-radio> <el-radio :label="item.id" border v-for="item in categoryList" :key="item.id">{{ item.name }}</el-radio>
...@@ -41,8 +40,7 @@ ...@@ -41,8 +40,7 @@
list-type="picture-card" list-type="picture-card"
accept="image/*" accept="image/*"
multiple multiple
:limit="15" :limit="15"></app-upload>
></app-upload>
<p class="form-tips">建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张</p> <p class="form-tips">建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张</p>
</el-form-item> </el-form-item>
<el-form-item label="主图视频" prop="main_chart_oss"> <el-form-item label="主图视频" prop="main_chart_oss">
...@@ -70,8 +68,7 @@ ...@@ -70,8 +68,7 @@
<el-form-item <el-form-item
label="规格明细" label="规格明细"
prop="goodStockList" prop="goodStockList"
v-show="ruleForm.skuKeyValueList && ruleForm.skuKeyValueList.length" v-show="ruleForm.skuKeyValueList && ruleForm.skuKeyValueList.length">
>
<sku-view :sku="ruleForm.skuKeyValueList" v-model="ruleForm.goodStockList"></sku-view> <sku-view :sku="ruleForm.skuKeyValueList" v-model="ruleForm.goodStockList"></sku-view>
</el-form-item> </el-form-item>
</app-card> </app-card>
...@@ -91,8 +88,7 @@ ...@@ -91,8 +88,7 @@
size="mini" size="mini"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择开售时间" placeholder="请选择开售时间"
v-if="ruleForm.sales_type === '2'" v-if="ruleForm.sales_type === '2'" />
/>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="购买按钮" prop="buy_button_text"> <el-form-item label="购买按钮" prop="buy_button_text">
...@@ -104,8 +100,7 @@ ...@@ -104,8 +100,7 @@
v-if="buyButtonTextRadio === '2'" v-if="buyButtonTextRadio === '2'"
size="mini" size="mini"
class="buy-button-input" class="buy-button-input"
maxlength="10" maxlength="10" />
/>
</el-radio-group> </el-radio-group>
<div class="form-tips"> <div class="form-tips">
默认名称为立即购买,可自定义名称,中文最大6个字内,英文10个字内,如:马上抢购,设置仅对当前商品有效。 默认名称为立即购买,可自定义名称,中文最大6个字内,英文10个字内,如:马上抢购,设置仅对当前商品有效。
...@@ -343,7 +338,7 @@ export default { ...@@ -343,7 +338,7 @@ export default {
// 基本信息表单校验 // 基本信息表单校验
this.$refs.ruleForm this.$refs.ruleForm
.validate() .validate()
.then(valid => { .then(() => {
// 规格明细校验 // 规格明细校验
const goodStockList = this.ruleForm.goodStockList const goodStockList = this.ruleForm.goodStockList
if (goodStockList && goodStockList.length) { if (goodStockList && goodStockList.length) {
......
...@@ -28,13 +28,13 @@ ...@@ -28,13 +28,13 @@
<p>浏览量:{{ row.page_view }}</p> <p>浏览量:{{ row.page_view }}</p>
</template> </template>
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<router-link :to="{ name: 'goodsEdit', params: { id: row.spu_id } }"> <el-button type="text">
<el-button type="text">编辑</el-button> <router-link :to="{ name: 'goodsEdit', params: { id: row.spu_id } }">编辑</router-link>
</router-link> </el-button>
<el-button type="text" @click="handlePromote(row)">推广</el-button> <el-button type="text" @click="handlePromote(row)">推广</el-button>
<router-link :to="{ name: 'goodsAdd', query: { id: row.spu_id } }"> <el-button type="text">
<el-button type="text">复制</el-button> <router-link :to="{ name: 'goodsAdd', query: { id: row.spu_id } }">复制</router-link>
</router-link> </el-button>
</template> </template>
</table-list> </table-list>
<div class="footer" style="padding: 10px 0"> <div class="footer" style="padding: 10px 0">
...@@ -155,7 +155,7 @@ export default { ...@@ -155,7 +155,7 @@ export default {
// 删除 // 删除
handleRemove() { handleRemove() {
const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id })) const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id }))
deleteGoods({ shop_id: this.shopId, data }).then(res => { deleteGoods({ shop_id: this.shopId, data }).then(() => {
this.$refs.list.refetch(true) this.$refs.list.refetch(true)
}) })
}, },
...@@ -175,7 +175,7 @@ export default { ...@@ -175,7 +175,7 @@ export default {
// 上架 // 上架
handleUpdateStatus(status) { handleUpdateStatus(status) {
const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id, status })) const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id, status }))
updateGoodsStatus({ shop_id: this.shopId, data }).then(res => { updateGoodsStatus({ shop_id: this.shopId, data }).then(() => {
this.$refs.list.refetch() this.$refs.list.refetch()
}) })
} }
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
:data="editRaw" :data="editRaw"
@success="handleSuccess" @success="handleSuccess"
@cancel="dialogVisible = false" @cancel="dialogVisible = false"
v-if="dialogVisible" v-if="dialogVisible" />
/>
</el-dialog> </el-dialog>
<!-- 推广 --> <!-- 推广 -->
...@@ -92,7 +91,7 @@ export default { ...@@ -92,7 +91,7 @@ export default {
}, },
// 删除 // 删除
handleRemove(row) { handleRemove(row) {
deleteGroup({ shop_id: this.shopId, group_id: row.group_id }).then(res => { deleteGroup({ shop_id: this.shopId, group_id: row.group_id }).then(() => {
this.$refs.list.refetch() this.$refs.list.refetch()
}) })
}, },
......
...@@ -98,7 +98,7 @@ export default { ...@@ -98,7 +98,7 @@ export default {
if (this.telRadio === 1) { if (this.telRadio === 1) {
params.shop_tel = `${this.telCode}-${this.telNumber}` params.shop_tel = `${this.telCode}-${this.telNumber}`
} }
updateShop(params).then(resp => { updateShop(params).then(() => {
this.$message({ type: 'success', message: '修改成功' }) this.$message({ type: 'success', message: '修改成功' })
this.dialogVisible = false this.dialogVisible = false
this.$store.dispatch('getShop') this.$store.dispatch('getShop')
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
v-model="ruleForm.end_time" v-model="ruleForm.end_time"
type="datetime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择店铺有效期" placeholder="请选择店铺有效期">
>
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -47,7 +46,7 @@ export default { ...@@ -47,7 +46,7 @@ export default {
this.$refs.ruleForm.validate().then(this.updateShop) this.$refs.ruleForm.validate().then(this.updateShop)
}, },
updateShop() { updateShop() {
updateShop(this.ruleForm).then(resp => { updateShop(this.ruleForm).then(() => {
this.$message({ type: 'success', message: '修改成功' }) this.$message({ type: 'success', message: '修改成功' })
this.$store.dispatch('getShop') this.$store.dispatch('getShop')
}) })
...@@ -56,5 +55,4 @@ export default { ...@@ -56,5 +55,4 @@ export default {
} }
</script> </script>
<style> <style></style>
</style>
...@@ -5,16 +5,14 @@ ...@@ -5,16 +5,14 @@
:data="item" :data="item"
:index="index" :index="index"
:key="index" :key="index"
@update="getSkuNameList" @update="getSkuNameList"></sku-group>
></sku-group>
<el-input <el-input
placeholder="规格名" placeholder="规格名"
v-model="inputValue" v-model="inputValue"
ref="input" ref="input"
@blur="onInputBlur" @blur="onInputBlur"
@keyup.enter.native="onInputBlur" @keyup.enter.native="onInputBlur"
v-if="inputVisible" v-if="inputVisible" />
/>
<el-button type="text" @click="addSku" v-if="!inputVisible"> <el-button type="text" @click="addSku" v-if="!inputVisible">
<i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;创建新规格 <i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;创建新规格
</el-button> </el-button>
...@@ -60,14 +58,14 @@ export default { ...@@ -60,14 +58,14 @@ export default {
this.inputVisible = !this.inputVisible this.inputVisible = !this.inputVisible
this.inputValue = '' this.inputValue = ''
}, },
onInputBlur(item) { onInputBlur() {
const value = this.inputValue.trim() const value = this.inputValue.trim()
// 空内容 // 空内容
if (!value) { if (!value) {
this.toggleInputVisible() this.toggleInputVisible()
return return
} }
addSku({ shop_id: this.shopId, spec_name: value }).then(res => { addSku({ shop_id: this.shopId, spec_name: value }).then(() => {
this.toggleInputVisible() this.toggleInputVisible()
this.getSkuNameList() this.getSkuNameList()
}) })
......
...@@ -33,8 +33,7 @@ ...@@ -33,8 +33,7 @@
v-model="ruleForm.end_time" v-model="ruleForm.end_time"
type="datetime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择店铺有效期" placeholder="请选择店铺有效期">
>
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="店铺简介" prop="shop_desc"> <el-form-item label="店铺简介" prop="shop_desc">
...@@ -42,8 +41,7 @@ ...@@ -42,8 +41,7 @@
type="textarea" type="textarea"
v-model="ruleForm.shop_desc" v-model="ruleForm.shop_desc"
:autosize="{ minRows: 4, maxRows: 6 }" :autosize="{ minRows: 4, maxRows: 6 }"
maxlength="100" maxlength="100"></el-input>
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="联系电话" prop="shop_tel"> <el-form-item label="联系电话" prop="shop_tel">
<el-input v-model="ruleForm.shop_tel"></el-input> <el-input v-model="ruleForm.shop_tel"></el-input>
...@@ -54,8 +52,7 @@ ...@@ -54,8 +52,7 @@
v-for="(item, index) in projectList" v-for="(item, index) in projectList"
:key="index" :key="index"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"></el-option>
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
...@@ -111,7 +108,7 @@ export default { ...@@ -111,7 +108,7 @@ export default {
this.$refs.ruleForm.validate().then(this.updateShop) this.$refs.ruleForm.validate().then(this.updateShop)
}, },
updateShop() { updateShop() {
updateShop(this.ruleForm).then(resp => { updateShop(this.ruleForm).then(() => {
this.$message({ type: 'success', message: '修改成功' }) this.$message({ type: 'success', message: '修改成功' })
this.dialogVisible = false this.dialogVisible = false
this.$store.dispatch('getShop') this.$store.dispatch('getShop')
......
...@@ -14,13 +14,21 @@ const store = new Vuex.Store({ ...@@ -14,13 +14,21 @@ const store = new Vuex.Store({
groups: [], // 商品分组 groups: [], // 商品分组
// 项目列表 // 项目列表
projectList: [ projectList: [
{ label: '玛丽伍德综合管理方向工商管理硕士', value: '1012' },
{ label: '索菲亚大学金融方向工商管理硕士', value: '1000' }, { label: '索菲亚大学金融方向工商管理硕士', value: '1000' },
{ label: '瑞士酒店大学酒店及旅游业工商管理硕士', value: '1008' },
{ label: '瑞士美食艺术管理大学CAAS餐饮管理MBA', value: '1015' },
{ label: '美国印第安纳大学Kelley商学院金融学硕士', value: '1001' }, { label: '美国印第安纳大学Kelley商学院金融学硕士', value: '1001' },
{ label: '加州整合大学应用心理学硕士', value: '1006' },
{ label: '美国康博斯威尔大学教育学硕士', value: '1005' }, { label: '美国康博斯威尔大学教育学硕士', value: '1005' },
{ label: '加州整合大学应用心理学硕士', value: '1006' },
{ label: '威斯康星协和大学家庭教育硕士 ', value: '1021' },
{ label: '玛丽伍德综合管理方向工商管理硕士', value: '1012' },
{ label: '瑞士酒店大学酒店及旅游业工商管理硕士', value: '1008' },
{ label: '瑞士美食艺术管理大学CAAS餐饮管理MBA', value: '1015' },
{ label: 'SHMS-EMBA', value: '1019' },
{ label: '玛丽伍德大学国际硕士保研项目(工商管理方向)', value: '1016' },
{ label: '玛丽伍德大学国际硕士保研项目(管理信息系统方向)', value: '1022' },
{ label: '纽约州立大学石溪分校金融硕士保研项目', value: '1018' },
{ label: '斯蒂文斯理工学院工程管理硕士保研项目', value: '1020' },
{ label: '加州浸会大学全日制工商管理博士DBA', value: '1017' },
{ label: '加州浸会大学在线工商管理博士DBA', value: '1023' },
{ label: '中国未来金融领袖计划', value: '1007' }, { label: '中国未来金融领袖计划', value: '1007' },
{ label: 'WMP高级财富管理师', value: '5000' }, { label: 'WMP高级财富管理师', value: '5000' },
{ label: '道路运输企业', value: '5001' }, { label: '道路运输企业', value: '5001' },
...@@ -80,7 +88,7 @@ const store = new Vuex.Store({ ...@@ -80,7 +88,7 @@ const store = new Vuex.Store({
}) })
}, },
// 获取费用类型列表 // 获取费用类型列表
getFeeTypes({ commit, state }) { getFeeTypes({ commit }) {
getFeeTypes() getFeeTypes()
.then(response => { .then(response => {
const { data = [] } = response const { data = [] } = response
......
import store from '@/store' import store from '@/store'
export default class BeforeEnter { export default async function (to, from, next) {
constructor(opt) { // 登录白名单
this.opt = opt || {} const whiteList = []
} if (whiteList.includes(to.path)) {
async update(to, from, next) {
// 登录白名单
const whiteList = []
if (whiteList.includes(to.path)) {
next()
return
}
const isLogin = store.state.user.id || (await store.dispatch('checkLogin'))
if (!isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
return
}
next() next()
return
}
const isLogin = store.state.user.id || (await store.dispatch('checkLogin'))
if (!isLogin) {
window.location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.href)}`
return
} }
next()
} }
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2' import vue from '@vitejs/plugin-vue2'
export default defineConfig({ import checker from 'vite-plugin-checker'
plugins: [createVuePlugin()],
export default defineConfig(({ mode }) => ({
base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/shop-center/' : '/',
plugins: [vue(), checker({ eslint: { lintCommand: 'eslint "./src/**/*.{vue,js,jsx,ts,tsx}"' } })],
server: { server: {
open: true,
host: 'dev.ezijing.com', host: 'dev.ezijing.com',
https: { https: {
key: fs.readFileSync(path.join(__dirname, './build/dev.ezijing.com.key')), key: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.key')),
cert: fs.readFileSync(path.join(__dirname, './build/dev.ezijing.com.pem')) cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
}, },
proxy: { proxy: {
'/api': 'https://shop-admin.ezijing.com' '/api': 'https://shop-center.ezijing.com'
} }
}, },
resolve: { resolve: {
alias: [ alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }]
{ },
find: '@', css: {
replacement: path.resolve(__dirname, 'src') // 禁用SASS警告提醒
} preprocessorOptions: { scss: { quietDeps: true, charset: false } }
]
} }
}) }))
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论