小程序产品库完成
This commit is contained in:
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
unpackage/
|
||||
dist/
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.project
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
/package-lock.json
|
||||
/.hbuilderx/launch.json
|
||||
/src/pages.json
|
||||
63
babel.config.js
Normal file
63
babel.config.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const plugins = []
|
||||
|
||||
if (process.env.UNI_OPT_TREESHAKINGNG) {
|
||||
plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'))
|
||||
}
|
||||
|
||||
if (
|
||||
(
|
||||
process.env.UNI_PLATFORM === 'app-plus' &&
|
||||
process.env.UNI_USING_V8
|
||||
) ||
|
||||
(
|
||||
process.env.UNI_PLATFORM === 'h5' &&
|
||||
process.env.UNI_H5_BROWSER === 'builtin'
|
||||
)
|
||||
) {
|
||||
const path = require('path')
|
||||
|
||||
const isWin = /^win/.test(process.platform)
|
||||
|
||||
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
|
||||
|
||||
const input = normalizePath(process.env.UNI_INPUT_DIR)
|
||||
try {
|
||||
plugins.push([
|
||||
require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
|
||||
{
|
||||
file (file) {
|
||||
file = normalizePath(file)
|
||||
if (file.indexOf(input) === 0) {
|
||||
return path.relative(input, file)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
])
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']
|
||||
process.UNI_LIBRARIES.forEach(libraryName => {
|
||||
plugins.push([
|
||||
'import',
|
||||
{
|
||||
'libraryName': libraryName,
|
||||
'customName': (name) => {
|
||||
return `${libraryName}/lib/${name}/${name}`
|
||||
}
|
||||
}
|
||||
])
|
||||
})
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@vue/app',
|
||||
{
|
||||
modules: 'commonjs',
|
||||
useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry'
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins
|
||||
}
|
||||
113
bin/serve.js
Normal file
113
bin/serve.js
Normal file
@@ -0,0 +1,113 @@
|
||||
const fsExtra = require('fs-extra')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
/**
|
||||
* 将函数封装成promise
|
||||
*/
|
||||
const promisify = fn => {
|
||||
return function () {
|
||||
let args = arguments;
|
||||
return new Promise(function (resolve, reject) {
|
||||
[].push.call(args, function (err, result) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
fn.apply(null, args);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const readdir = promisify(fs.readdir)
|
||||
const stat = promisify(fs.stat)
|
||||
/**
|
||||
* 封装打印工具
|
||||
*/
|
||||
const chalk = require('chalk')
|
||||
const {log} = console
|
||||
const chalkTag = {
|
||||
info: msg => log([chalk.bgBlue.black(' INFO '), msg].join(' ')),
|
||||
done: msg => log([chalk.bgGreen.black(' DONE '), msg].join(' ')),
|
||||
warn: msg => log([chalk.bgYellow.black(' WARN '), msg].join(' ')),
|
||||
error: msg => log([chalk.bgRed.black(' ERROR '), msg].join(' ')),
|
||||
}
|
||||
|
||||
/**
|
||||
* 遍历应用的方法
|
||||
*/
|
||||
const findApp = (dir, cb) => {
|
||||
return readdir(dir).then(apps => {
|
||||
return Promise.all(apps.map(e => {
|
||||
let cPath = path.join(dir, e)
|
||||
return stat(cPath).then(state => {
|
||||
if (state.isDirectory()) {
|
||||
return findApp(cPath, cb)
|
||||
} else if (state.isFile()) {
|
||||
cb && cb(cPath)
|
||||
}
|
||||
})
|
||||
}) || [])
|
||||
})
|
||||
}
|
||||
const start = () => {
|
||||
chalkTag.info('开始生成pages.json...')
|
||||
let json = {
|
||||
easycom: {
|
||||
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
|
||||
"^(Ai|V)(.*)": "@/components/$1$2/$1$2.vue"
|
||||
},
|
||||
pages: [
|
||||
{path: 'pages/home', style: {navigationBarTitleText: "小程序应用库"}}
|
||||
],
|
||||
subPackages: [
|
||||
{root: "mods/", pages: []},
|
||||
{root: "components/pages/", pages: []}
|
||||
],
|
||||
globalStyle: {
|
||||
pageOrientation: "auto",
|
||||
navigationBarTextStyle: "white",
|
||||
navigationBarBackgroundColor: "#197DF0",
|
||||
backgroundColor: "#197DF0"
|
||||
}
|
||||
}
|
||||
findApp('src/components/pages', file => {
|
||||
if (/.+\\[^\\]+\\[^\\]+\.vue/g.test(file)) {
|
||||
let app = {
|
||||
path: file.replace(/^src\\components\\pages\\(.*).vue/g, '$1').replace(/\\/g, '/')
|
||||
}
|
||||
let vue = fs.readFileSync(file).toString()
|
||||
if (/appName/.test(vue)) {
|
||||
let appName = vue.replace(/[\s\S]*(appName:.+),[\s\S]*/gm, '$1'),
|
||||
title = appName.replace(/(appName:|["'])/g, '')
|
||||
app.style = {navigationBarTitleText: title}
|
||||
}
|
||||
json.subPackages[1].pages.push(app)
|
||||
}
|
||||
}).then(() => {
|
||||
return findApp('src/mods', file => {
|
||||
if (/.+\\App[^\\]+\\[^\\]+\.vue/g.test(file)) {
|
||||
let app = {
|
||||
name: file.replace(/.*\\([^\\]+).vue/g, '$1'),
|
||||
path: file.replace(/^src\\mods\\(.*).vue/g, '$1').replace(/\\/g, '/')
|
||||
}
|
||||
let vue = fs.readFileSync(file).toString()
|
||||
if (/appName/.test(vue)) {
|
||||
let appName = vue.replace(/[\s\S]*(appName:.+),[\s\S]*/gm, '$1'),
|
||||
title = appName.replace(/(appName:|["'])/g, '')
|
||||
app.style = {navigationBarTitleText: title}
|
||||
}
|
||||
json.subPackages[0].pages.push(app)
|
||||
}
|
||||
}).then(() => {
|
||||
fsExtra.outputJson('src/pages.json', json, () => {
|
||||
chalkTag.done('生成pages.json')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
start();
|
||||
14
jest.config.js
Normal file
14
jest.config.js
Normal file
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
globalTeardown: '@dcloudio/uni-automator/dist/teardown.js',
|
||||
testEnvironment: '@dcloudio/uni-automator/dist/environment.js',
|
||||
testEnvironmentOptions: {},
|
||||
testTimeout: 15000,
|
||||
reporters: [
|
||||
'default'
|
||||
],
|
||||
watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
|
||||
moduleFileExtensions: ['js', 'json'],
|
||||
rootDir: __dirname,
|
||||
testMatch: ['<rootDir>/src/__tests__/**/*spec.[jt]s?(x)'],
|
||||
testPathIgnorePatterns: ['/node_modules/']
|
||||
}
|
||||
70
package.json
Normal file
70
package.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "dvcp-wechat-apps",
|
||||
"version": "1.0.0",
|
||||
"private": false,
|
||||
"author": "Kubbo",
|
||||
"scripts": {
|
||||
"dev:mp-weixin": "node bin/serve.js&&cross-env NODE_ENV=development VUE_APP_CW_MODE=dev UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
|
||||
"lib": "npm unpublish --force&&npm publish",
|
||||
"pages": "node bin/serve.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-app-plus": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-h5": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-helper-json": "^1.0.8",
|
||||
"@dcloudio/uni-mp-360": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-alipay": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-baidu": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-kuaishou": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-lark": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-qq": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-toutiao": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-vue": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-mp-weixin": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-quickapp-native": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-quickapp-webview": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-stat": "^2.0.1-33320211224001",
|
||||
"@vue/shared": "^3.2.26",
|
||||
"axios": "^0.19.2",
|
||||
"core-js": "^3.7.0",
|
||||
"dayjs": "^1.9.5",
|
||||
"flyio": "^0.6.14",
|
||||
"regenerator-runtime": "^0.12.1",
|
||||
"uview-ui": "^1.7.8",
|
||||
"vc-wx-ui": "^0.1.0",
|
||||
"vue": "^2.6.11",
|
||||
"vuex": "^3.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dcloudio/types": "^1.1.1",
|
||||
"@dcloudio/uni-automator": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-cli-i18n": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-cli-shared": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-i18n": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-migration": "^2.0.1-33320211224001",
|
||||
"@dcloudio/uni-template-compiler": "^2.0.1-33320211224001",
|
||||
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.1-33320211224001",
|
||||
"@dcloudio/vue-cli-plugin-uni": "^2.0.1-33320211224001",
|
||||
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.1-33320211224001",
|
||||
"@dcloudio/webpack-uni-mp-loader": "^2.0.1-33320211224001",
|
||||
"@dcloudio/webpack-uni-pages-loader": "^2.0.1-33320211224001",
|
||||
"@vue/cli-plugin-babel": "^4.5.6",
|
||||
"@vue/cli-service": "^4.5.6",
|
||||
"babel-plugin-import": "^1.13.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"jest": "^25.5.4",
|
||||
"mini-types": "^0.1.4",
|
||||
"miniprogram-api-typings": "^3.1.6",
|
||||
"postcss-comment": "^2.0.0",
|
||||
"sass": "^1.45.1",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuex-persistedstate": "^3.1.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"Android >= 4",
|
||||
"ios >= 8"
|
||||
],
|
||||
"uni-app": {
|
||||
"scripts": {}
|
||||
}
|
||||
}
|
||||
22
postcss.config.js
Normal file
22
postcss.config.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const path = require('path')
|
||||
module.exports = {
|
||||
parser: require('postcss-comment'),
|
||||
plugins: [
|
||||
require('postcss-import')({
|
||||
resolve (id, basedir, importOptions) {
|
||||
if (id.startsWith('~@/')) {
|
||||
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3))
|
||||
} else if (id.startsWith('@/')) {
|
||||
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2))
|
||||
} else if (id.startsWith('/') && !id.startsWith('//')) {
|
||||
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1))
|
||||
}
|
||||
return id
|
||||
}
|
||||
}),
|
||||
require('autoprefixer')({
|
||||
remove: process.env.UNI_PLATFORM !== 'h5'
|
||||
}),
|
||||
require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
|
||||
]
|
||||
}
|
||||
27
public/index.html
Normal file
27
public/index.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>
|
||||
<%= htmlWebpackPlugin.options.title %>
|
||||
</title>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
|
||||
})
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
||||
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>Please enable JavaScript to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
178
src/App.vue
Normal file
178
src/App.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<script>
|
||||
|
||||
export default {
|
||||
onLaunch() {
|
||||
if (!wx.getUpdateManager) return
|
||||
const updateManager = wx.getUpdateManager()
|
||||
updateManager.onUpdateReady(() => {
|
||||
this.$dialog.alert({
|
||||
title: '更新提示',
|
||||
content: '新版本已经准备好,点击确认按钮重启应用!'
|
||||
}).then(() => {
|
||||
updateManager.applyUpdate()
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "common/common.scss";
|
||||
/* #ifdef MP-BAIDU */
|
||||
page {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
swan-template {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* 原生组件模式下需要注意组件外部样式 */
|
||||
custom-component {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* #ifdef MP-ALIPAY */
|
||||
page {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* 原生组件模式下需要注意组件外部样式 */
|
||||
m-input {
|
||||
width: 100%;
|
||||
/* min-height: 100%; */
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
background-color: #efeff4;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
background-color: #ffffff;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-group::before {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
content: "";
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: #c8c7cc;
|
||||
}
|
||||
|
||||
.input-group::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
content: "";
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: #c8c7cc;
|
||||
}
|
||||
|
||||
.input-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
font-size: 18px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.input-row .title {
|
||||
width: 72px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.input-row.border::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 8px;
|
||||
height: 1px;
|
||||
content: "";
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
background-color: #c8c7cc;
|
||||
}
|
||||
|
||||
uni-tabbar .uni-tabbar-border {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.btn-row {
|
||||
margin-top: 25px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
button.primary {
|
||||
background-color: #0faeff;
|
||||
}
|
||||
|
||||
.flexRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.u-input__right-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.spb {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&.column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.start {
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.fill {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
270
src/common/common.css
Normal file
270
src/common/common.css
Normal file
@@ -0,0 +1,270 @@
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
/* project id 1862352 */
|
||||
src: url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.eot');
|
||||
src: url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.eot?#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.woff2') format('woff2'),
|
||||
url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.woff') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.ttf') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_1862352_i00id3q02qr.svg#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 32px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
ul,
|
||||
li,
|
||||
span,
|
||||
div,
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none
|
||||
}
|
||||
|
||||
page {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background-color: #f3f6f9;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f3f6f9;
|
||||
}
|
||||
|
||||
.span-hover {
|
||||
background: transparent;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bg-hover {
|
||||
background: #eee !important;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-align {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.solid {
|
||||
border-bottom: 2px solid #E8E8E8;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
uni-button[disabled] {
|
||||
background-color: #F7F7F7 !important;
|
||||
color: #999 !important;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
uni-button:after {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.break-word {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.masking-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgb(0, 0, 0);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 入口页列表 */
|
||||
.list {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 112px;
|
||||
background-color: #fff;
|
||||
padding-left: 32px;
|
||||
padding-right: 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.title-sub {
|
||||
height: 112px;
|
||||
margin-left: 16px;
|
||||
width: 654px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.more {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
border-bottom: 2px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.no-content-pds {
|
||||
margin-top: 360px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-content-pds div {
|
||||
height: 40px;
|
||||
font-size: 28px;
|
||||
line-height: 40px;
|
||||
font-family: PingFangSC-Regular, PingFangSC;
|
||||
}
|
||||
|
||||
.no-content-pds .span {
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
|
||||
.no-content-pds .span-p {
|
||||
color: rgba(153, 153, 153, 1);
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
/* margin */
|
||||
.mar-t8 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.mar-r20 {
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.mar-l10 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
/* color */
|
||||
.color-333 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.color-999 {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.color-666 {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* */
|
||||
.font-12 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
/* */
|
||||
.report {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #135AB8;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 112px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.span-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.textarea-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 多级下拉选择css */
|
||||
.type-picke-more {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 330px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #fff;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.type-picke-more picker-div-column {
|
||||
text-align: center;
|
||||
line-height: 110px;
|
||||
}
|
||||
|
||||
.fixed-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
width: 100%
|
||||
}
|
||||
808
src/common/common.scss
Normal file
808
src/common/common.scss
Normal file
@@ -0,0 +1,808 @@
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
/* project id 1862352 */
|
||||
src: url('https://at.alicdn.com/t/font_1862352_jpvud12digs.eot');
|
||||
src: url('https://at.alicdn.com/t/font_1862352_jpvud12digs.eot?#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_1862352_jpvud12digs.woff2') format('woff2'),
|
||||
url('https://at.alicdn.com/t/font_1862352_jpvud12digs.woff') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_1862352_jpvud12digs.ttf') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_1862352_jpvud12digs.svg#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 32rpx;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f3f6f9;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f3f6f9;
|
||||
}
|
||||
|
||||
.text-hover {
|
||||
background: transparent;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bg-hover {
|
||||
background: #eee !important;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-align {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.solid {
|
||||
border-bottom: 2rpx solid #E8E8E8;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
uni-button[disabled] {
|
||||
background-color: #F7F7F7 !important;
|
||||
color: #999 !important;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
uni-button:after {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.break-word {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.masking-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgb(0, 0, 0);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 入口页列表 */
|
||||
// .list {
|
||||
// justify-content: space-between;
|
||||
// align-items: center;
|
||||
// height: 112rpx;
|
||||
// background-color: #fff;
|
||||
// padding-left: 32rpx;
|
||||
// padding-right: 32rpx;
|
||||
// box-sizing: border-box;
|
||||
// }
|
||||
|
||||
// .list-cell {
|
||||
// width: 48rpx;
|
||||
// height: 48rpx;
|
||||
// }
|
||||
.input-placeholder, .textarea-placeholder {
|
||||
color: #999999;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.title-sub {
|
||||
height: 112rpx;
|
||||
margin-left: 16rpx;
|
||||
width: 654rpx;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.more {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
.title-line {
|
||||
border-bottom: 2rpx solid #DDDDDD;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.no-content-pds {
|
||||
margin-top: 360rpx;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-content-pds view {
|
||||
height: 40rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
font-family: PingFangSC-Regular, PingFangSC;
|
||||
}
|
||||
|
||||
.no-content-pds .text {
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
|
||||
.no-content-pds .text-p {
|
||||
color: rgba(153, 153, 153, 1);
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
/* margin */
|
||||
.mar-t8 {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.mar-r20 {
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
.mar-l10 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
/* color */
|
||||
.color-333 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.color-999 {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.color-666 {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.color-467DFE {
|
||||
color: #467DFE;
|
||||
}
|
||||
|
||||
.color-135AB8 {
|
||||
color: #197DF0 !important;
|
||||
}
|
||||
|
||||
/* */
|
||||
.font-12 {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* */
|
||||
.report {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 112rpx;
|
||||
background-color: #197DF0;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 112rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.textarea-placeholder {
|
||||
color: #666;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
/* 多级下拉选择css */
|
||||
.type-picke-more {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 330rpx;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #fff;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.type-picke-more picker-view-column {
|
||||
text-align: center;
|
||||
line-height: 110rpx;
|
||||
}
|
||||
|
||||
|
||||
/* 固定在顶部 */
|
||||
.fixed-top {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 固定在底部 */
|
||||
.fixed-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
/* 背景颜色为蓝色的按钮 */
|
||||
.confirm-btn {
|
||||
background-color: #197DF0;
|
||||
height: 112rpx;
|
||||
line-height: 112rpx;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 顶部搜索栏 */
|
||||
.header-search {
|
||||
width: 100%;
|
||||
height: 112rpx;
|
||||
padding: 16rpx 32rpx 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
background: #197DF0;
|
||||
}
|
||||
|
||||
.header-search .search-input-content {
|
||||
width: 686rpx;
|
||||
height: 64rpx;
|
||||
background: #0D6DDC;
|
||||
border-radius: 32rpx;
|
||||
padding: 14rpx 24rpx 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-search .search-icon {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
position: absolute;
|
||||
top: 18rpx;
|
||||
left: 24rpx;
|
||||
}
|
||||
|
||||
.header-search .search-input {
|
||||
display: inline-block;
|
||||
width: calc(100% - 58rpx);
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
color: #fff;
|
||||
padding-left: 20rpx;
|
||||
font-size: 28rpx;
|
||||
padding-left: 58rpx;
|
||||
}
|
||||
|
||||
/* 顶部搜索栏 */
|
||||
|
||||
/* 顶部搜索框 (带下拉选择) */
|
||||
.header-search-select {
|
||||
width: 100%;
|
||||
height: 112rpx;
|
||||
background: #197DF0;
|
||||
padding: 24rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header-search-select .select-content {
|
||||
display: inline-block;
|
||||
width: 206rpx;
|
||||
line-height: 64rpx;
|
||||
font-weight: 500;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.header-search-select .select-content img {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-search-select .input-content {
|
||||
display: inline-block;
|
||||
width: calc(100% - 206rpx);
|
||||
height: 64rpx;
|
||||
background: #0D6DDC;
|
||||
border-radius: 32rpx;
|
||||
padding: 14rpx 24rpx 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
padding-left: 58rpx;
|
||||
}
|
||||
|
||||
.header-search-select .search-icon {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
height: 34rpx;
|
||||
position: absolute;
|
||||
top: 18rpx;
|
||||
left: 24rpx;
|
||||
}
|
||||
|
||||
.header-search-select .search-input {
|
||||
display: inline-block;
|
||||
width: calc(100% - 58rpx);
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
color: #fff;
|
||||
padding-left: 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 顶部搜索框 (带下拉选择) */
|
||||
|
||||
/* 顶部筛选框 */
|
||||
.header-select {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
background-color: #fff;
|
||||
padding: 24rpx 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.header-select .select-item {
|
||||
flex: 1;
|
||||
height: 48rpx;
|
||||
line-height: 48rpx;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.header-select .down-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
vertical-align: middle;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.header-select .select-item:nth-of-type(2) {
|
||||
border-left: 2rpx solid #eee;
|
||||
}
|
||||
|
||||
/* 顶部筛选框 */
|
||||
|
||||
/* 顶部tab类型切换栏 */
|
||||
.header-tab {
|
||||
height: 96rpx;
|
||||
background-color: #4181FF;
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header-tab .tab-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.header-tab .tab-active {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header-tab .active-line {
|
||||
position: absolute;
|
||||
width: 40rpx;
|
||||
height: 4rpx;
|
||||
background: #FFF;
|
||||
top: 48rpx;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
/* 顶部tab类型切换栏 */
|
||||
|
||||
/* 下划线 */
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 字体加粗 500 */
|
||||
.fw500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* u-input字体大小重置 */
|
||||
.fs-32 .u-input__input {
|
||||
line-height: 42rpx !important;
|
||||
font-size: 32rpx !important;
|
||||
height: 180rpx !important;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
/* button样式重置 */
|
||||
button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
line-height: inherit;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.button-hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/**
|
||||
* author: Di (微信小程序开发工程师)
|
||||
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
|
||||
* 垂直微信小程序开发交流社区
|
||||
*
|
||||
* github地址: https://github.com/icindy/wxParse
|
||||
*
|
||||
* for: 微信小程序富文本解析
|
||||
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
|
||||
*/
|
||||
|
||||
.wxParse {
|
||||
width: 100%;
|
||||
font-family: Helvetica, sans-serif;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.wxParse view {
|
||||
word-break: hyphenate;
|
||||
}
|
||||
|
||||
.wxParse .inline {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wxParse .div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wxParse .h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
.wxParse .h2 {
|
||||
font-size: 1.5em;
|
||||
margin: 0.83em 0;
|
||||
}
|
||||
|
||||
.wxParse .h3 {
|
||||
font-size: 1.17em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.wxParse .h4 {
|
||||
margin: 1.33em 0;
|
||||
}
|
||||
|
||||
.wxParse .h5 {
|
||||
font-size: 0.83em;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
|
||||
.wxParse .h6 {
|
||||
font-size: 0.67em;
|
||||
margin: 2.33em 0;
|
||||
}
|
||||
|
||||
.wxParse .h1,
|
||||
.wxParse .h2,
|
||||
.wxParse .h3,
|
||||
.wxParse .h4,
|
||||
.wxParse .h5,
|
||||
.wxParse .h6,
|
||||
.wxParse .b,
|
||||
.wxParse .strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.wxParse .p {
|
||||
margin: 1em 0;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.wxParse .i,
|
||||
.wxParse .cite,
|
||||
.wxParse .em,
|
||||
.wxParse .var,
|
||||
.wxParse .address {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.wxParse .pre,
|
||||
.wxParse .tt,
|
||||
.wxParse .code,
|
||||
.wxParse .kbd,
|
||||
.wxParse .samp {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.wxParse .pre {
|
||||
overflow: auto;
|
||||
background: #f5f5f5;
|
||||
padding: 8px;
|
||||
white-space: pre;
|
||||
margin: 1em 0px;
|
||||
}
|
||||
|
||||
.wxParse .code {
|
||||
display: inline;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.wxParse .big {
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
.wxParse .small,
|
||||
.wxParse .sub,
|
||||
.wxParse .sup {
|
||||
font-size: 0.83em;
|
||||
}
|
||||
|
||||
.wxParse .sub {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.wxParse .sup {
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
.wxParse .s,
|
||||
.wxParse .strike,
|
||||
.wxParse .del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.wxParse .strong,
|
||||
.wxParse .s {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.wxParse .a {
|
||||
color: deepskyblue;
|
||||
}
|
||||
|
||||
.wxParse .video {
|
||||
text-align: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.wxParse .video-video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wxParse .img {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
max-width: 100% !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wxParse .blockquote {
|
||||
margin: 5px 0;
|
||||
padding: 10px 0 10px 10px;
|
||||
font-family: Courier, Calibri, "宋体";
|
||||
background: #f5f5f5;
|
||||
border-left: 3px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.wxParse .blockquote .p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.wxParse .ul,
|
||||
.wxParse .ol {
|
||||
display: block;
|
||||
margin: 1em 0;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.wxParse .ol {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.wxParse .ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.wxParse .li {
|
||||
display: list-item;
|
||||
align-items: baseline;
|
||||
text-align: match-parent;
|
||||
}
|
||||
|
||||
.wxParse .ul .ul,
|
||||
.wxParse .ol .ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.wxParse .ol .ol .ul,
|
||||
.wxParse .ol .ul .ul,
|
||||
.wxParse .ul .ol .ul,
|
||||
.wxParse .ul .ul .ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.wxParse .u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.wxParse .hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wxParse .del {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.wxParse .figure {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wxParse .table {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.wxParse .thead,
|
||||
.wxParse .tfoot,
|
||||
.wxParse .tr {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.wxParse .tr {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
/*border-right: 1px solid #e0e0e0;*/
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.wxParse .th,
|
||||
.wxParse .td {
|
||||
display: flex;
|
||||
width: 260px;
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
/*border-left: 1px solid #e0e0e0;*/
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wxParse .td:last-child {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.wxParse .th {
|
||||
background: #f0f0f0;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.btn-wrapper {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
padding: 20px 0 20px 0 !important;
|
||||
transform: translateX(-50%);
|
||||
background: #f3f6f9;
|
||||
}
|
||||
|
||||
.btn-wrapper .btn {
|
||||
width: 686px;
|
||||
height: 88px;
|
||||
line-height: 88px;
|
||||
margin: 0 auto;
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 34px;
|
||||
background: #4181FF;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.btn-wrapper .disabled {
|
||||
color: #B9E7D0;
|
||||
background: #50C48A;
|
||||
}
|
||||
|
||||
.rich-content {
|
||||
::v-deep {
|
||||
p {
|
||||
margin: 20px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 30px;
|
||||
text-align: justify;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
image {
|
||||
// margin: 20px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
padding: 10px 0 10px 16px;
|
||||
box-sizing: border-box;
|
||||
background: #4181FF;
|
||||
}
|
||||
367
src/components/AiAreaPicker/AiAreaPicker.vue
Normal file
367
src/components/AiAreaPicker/AiAreaPicker.vue
Normal file
@@ -0,0 +1,367 @@
|
||||
<template>
|
||||
<section class="AiAreaPicker">
|
||||
<ai-search-popup mode="bottom" ref="areaSelector" length="85%">
|
||||
<div slot="btn" @tap="handleInit">
|
||||
<slot v-if="$slots.default"/>
|
||||
<div v-else class="areaSelector">
|
||||
<image :src="locationIcon" class="location"/>
|
||||
<div v-text="currentArea.name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="areaSelector" id="areaSelector">
|
||||
<div class="fixedTop">
|
||||
<b>选择地区</b>
|
||||
<em>选择区域</em>
|
||||
<div class="selectedArea" v-if="hasSelected">
|
||||
<p v-for="area in fullArea" :key="area.id" v-text="area.name"/>
|
||||
<p v-if="selected.type==5" v-text="selected.name"/>
|
||||
</div>
|
||||
<div/>
|
||||
<span v-if="all" v-text="`省`" @click="selectNode({}, -1)"/>
|
||||
<span v-for="(area,i) in fullArea" :key="area.id" v-text="area.levelLabel"
|
||||
@click="selectNode(area, i)"/>
|
||||
</div>
|
||||
</div>
|
||||
<scroll-view class="fill pendingList" :style="{height: height}" scroll-y>
|
||||
<div class="pendingItem flexRow" flex v-for="op in pending" :key="op.id" @tap="getChild(op)">
|
||||
<div class="fill" :class="{ self: index == op.id }" v-html="op.name"/>
|
||||
<u-icon v-if="index == op.id" name="checkbox-mark" color="#4181FF"/>
|
||||
</div>
|
||||
</scroll-view>
|
||||
<div class="bottomBtns">
|
||||
<div @click="closePopup">取消</div>
|
||||
<div class="primary fill" @click="handleSelect">确定</div>
|
||||
</div>
|
||||
</ai-search-popup>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiSearchPopup from './AiSearchPopup'
|
||||
import AiCell from './AiCell.vue'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AiAreaPicker',
|
||||
components: {AiCell, AiSearchPopup},
|
||||
props: {
|
||||
areaId: {default: ''},
|
||||
name: {default: ''},
|
||||
value: String,
|
||||
all: Boolean,
|
||||
icon: {default: "location.svg"},
|
||||
isHideTown: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
dataRange() {
|
||||
let rules = [10, 8, 6, 3, 0],
|
||||
level = 0
|
||||
if (this.all) return (level = 0)
|
||||
rules.some((e, i) => {
|
||||
let reg = new RegExp(`0{${e}}`, 'g')
|
||||
if (reg.test(this.areaId || this.user.areaId || this.$areaId)) {
|
||||
return (level = i)
|
||||
}
|
||||
})
|
||||
return level
|
||||
},
|
||||
currentArea() {
|
||||
return this.fullArea?.slice(-1)?.[0] || {}
|
||||
},
|
||||
locationIcon() {
|
||||
return this.$cdn + this.icon
|
||||
},
|
||||
pending() {
|
||||
return this.list.map(e => ({...e, levelLabel: this.levelLabels[e.type]}))
|
||||
},
|
||||
hasSelected() {
|
||||
return this.fullArea?.length > 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fullArea: [],
|
||||
index: '',
|
||||
list: [],
|
||||
height: '500px',
|
||||
levelLabels: ["省", "市", "县/区", "镇/街道", "村/社区"],
|
||||
selected: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
areaId(v) {
|
||||
v && this.getFullArea()
|
||||
},
|
||||
|
||||
fullArea: {
|
||||
handler(v) {
|
||||
this.$nextTick(() => {
|
||||
if (v) {
|
||||
this.scrollHeight()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.handleInit()
|
||||
this.$refs.areaSelector.showPopup()
|
||||
},
|
||||
scrollHeight () {
|
||||
var obj = this.createSelectorQuery()
|
||||
obj.select('#areaSelector').boundingClientRect()
|
||||
obj.exec(rect => {
|
||||
if (rect.length) {
|
||||
this.height = `calc(100% - ${rect[0].height}px)`
|
||||
}
|
||||
})
|
||||
},
|
||||
getFullArea() {
|
||||
let areaId = this.areaId || (this.all ? '' : this.$areaId)
|
||||
return this.$instance.post('/admin/area/getAllParentAreaId', null, {
|
||||
withoutToken: true,
|
||||
params: {areaId},
|
||||
}).then((res) => {
|
||||
if (res?.data) {
|
||||
res.data.forEach((e) => {
|
||||
e && (e.levelLabel = this.levelLabels[e.type])
|
||||
})
|
||||
if (res.data.length > 1) {
|
||||
this.fullArea = res.data.reverse().slice(this.dataRange)
|
||||
} else {
|
||||
this.fullArea = res.data
|
||||
}
|
||||
return this.fullArea
|
||||
}
|
||||
})
|
||||
},
|
||||
getChildAreas(id) {
|
||||
id && this.$instance.post('/admin/area/queryAreaByParentId', null, {
|
||||
withoutToken: true,
|
||||
params: {id},
|
||||
}).then((res) => {
|
||||
if (res.data.length) {
|
||||
this.list = res.data
|
||||
let self = this.fullArea.find((e) => e.id == this.areaId)
|
||||
if (self.id && !this.isHideTown) {
|
||||
this.list.unshift(self)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
isVillage (areaId) {
|
||||
return areaId.substr(areaId.length - 3, 3) != '000'
|
||||
},
|
||||
|
||||
getProvinces() {
|
||||
this.$instance.post('/admin/area/queryProvinceList', null, {withoutToken: true}).then((res) => {
|
||||
if (res?.data) {
|
||||
this.list = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSelect() {
|
||||
this.$emit('select', this.index)
|
||||
let fullName = ''
|
||||
this.fullArea.forEach(v => {
|
||||
fullName = fullName + v.name
|
||||
})
|
||||
|
||||
if (this.selected.type == 5) {
|
||||
fullName = fullName + this.selected.name
|
||||
}
|
||||
this.$emit('update:fullName', fullName)
|
||||
this.$emit('update:name', this.selected.name)
|
||||
this.closePopup()
|
||||
},
|
||||
getChild(op) {
|
||||
if (op.id != this.index) {
|
||||
if (op.type < 5 && (/0{3}$/g.test(this.index) || !this.index)) {
|
||||
this.fullArea.push(op)
|
||||
this.getChildAreas(op.id)
|
||||
}
|
||||
this.selected = op
|
||||
this.index = op.id
|
||||
}
|
||||
},
|
||||
selectNode(area, i) {
|
||||
this.fullArea.splice(i + 1, this.fullArea.length - i)
|
||||
if (this.all && !area.id) {
|
||||
this.index = ''
|
||||
this.getProvinces()
|
||||
} else {
|
||||
this.index = area.id
|
||||
this.getChildAreas(area.id)
|
||||
}
|
||||
},
|
||||
handleInit() {
|
||||
this.index = this.value || this.areaId
|
||||
|
||||
if (this.all && !this.areaId && !this.currentArea.id) {
|
||||
this.getProvinces()
|
||||
|
||||
return false
|
||||
}
|
||||
this.getFullArea().then(() => {
|
||||
this.getChildAreas(this.currentArea.id || this.areaId)
|
||||
})
|
||||
},
|
||||
closePopup() {
|
||||
this.$refs.areaSelector?.handleSelect()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiAreaPicker {
|
||||
::v-deep .areaSelector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
line-height: 112px;
|
||||
margin-right: 72px;
|
||||
position: relative;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
|
||||
&:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -26px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 100%);
|
||||
width: 40px;
|
||||
height: 8px;
|
||||
background: #4181FF;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 96px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.selectedArea {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: fit-content;
|
||||
max-width: calc(100vw - 128px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0 32px;
|
||||
height: 80px;
|
||||
background: #ECF2FF;
|
||||
border-radius: 40px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #4181FF !important;
|
||||
margin: 16px 0 32px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fixedTop {
|
||||
// position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
background: #fff;
|
||||
border-bottom: 4px solid #f5f5f5;
|
||||
z-index: 1;
|
||||
text-align: start;
|
||||
padding: 0 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.u-drawer-content {
|
||||
|
||||
.areaSelector {
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .pendingList {
|
||||
padding: 0 32px 120px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.pendingItem {
|
||||
color: #333;
|
||||
height: 104px;
|
||||
text-align: start;
|
||||
|
||||
.self {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.bottomBtns {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
height: 120px;
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #3671EE;
|
||||
background: #fff;
|
||||
padding: 0 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
& > div {
|
||||
padding: 0 92px;
|
||||
line-height: 88px;
|
||||
height: 88px;
|
||||
border: 1px solid #A0C0FF;
|
||||
border-radius: 16px;
|
||||
|
||||
&.primary {
|
||||
color: #fff;
|
||||
background: #4181FF;
|
||||
border-color: #4181FF;
|
||||
}
|
||||
|
||||
& + div {
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.location {
|
||||
width: 28px;
|
||||
height: 80px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
76
src/components/AiAreaPicker/AiCell.vue
Normal file
76
src/components/AiAreaPicker/AiCell.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<section class="AiCell" :class="{bottomBorder,alignCenter,topLabel}">
|
||||
<div class="label" :class="{title}">
|
||||
<slot v-if="$slots.label" name="label"/>
|
||||
<span v-else>{{ label }}</span>
|
||||
</div>
|
||||
<div class="content" :class="{topLabel}">
|
||||
<slot/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiCell",
|
||||
props: {
|
||||
label: {default: ""},
|
||||
bottomBorder: Boolean,
|
||||
topLabel: Boolean,
|
||||
title: Boolean,
|
||||
alignCenter: Boolean
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiCell {
|
||||
display: flex;
|
||||
min-height: 72px;
|
||||
font-size: 30px;
|
||||
color: #333;
|
||||
padding: 14px 0;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
|
||||
&.bottomBorder {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
&.alignCenter {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.topLabel {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.label {
|
||||
min-width: 60px;
|
||||
flex-shrink: 0;
|
||||
width: auto;
|
||||
color: #999;
|
||||
|
||||
|
||||
&.title {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
font-size: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
min-height: 40px;
|
||||
max-width: 500px;
|
||||
text-align: right;
|
||||
|
||||
&.topLabel {
|
||||
text-align: start;
|
||||
margin-top: 16px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
94
src/components/AiAreaPicker/AiSearchPopup.vue
Normal file
94
src/components/AiAreaPicker/AiSearchPopup.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<section class="AiSearchPopup">
|
||||
<u-popup v-model="show" :length="length" closeable :mode="mode" border-radius="32">
|
||||
<slot v-if="$slots.default"/>
|
||||
<div class="searchPane" v-else>
|
||||
<div class="title">{{ title }}</div>
|
||||
<u-search v-model="search" :placeholder="placeholder" :show-action="false" @search="getList()" :focus="show"/>
|
||||
<div class="result">
|
||||
<div class="option" v-for="(op,i) in list" :key="i" @tap="handleSelect(op)">{{ op[ops.label] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</u-popup>
|
||||
<div @tap="show=true">
|
||||
<slot name="btn"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiSearchPopup",
|
||||
props: {
|
||||
title: {default: "搜索"},
|
||||
placeholder: {default: "请搜索"},
|
||||
ops: {default: () => ({label: 'label', search: 'name'})},
|
||||
url: String,
|
||||
mode: {default: "right"},
|
||||
length: {default: "100%"}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
search: "",
|
||||
list: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(v) {
|
||||
!v && this.$emit('close')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.url && this.$instance.post(this.url, null, {
|
||||
params: {[this.ops.search]: this.search}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
showPopup() {
|
||||
this.show = true
|
||||
},
|
||||
handleSelect(op) {
|
||||
this.$emit('select', op)
|
||||
this.show = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiSearchPopup {
|
||||
::v-deep .searchPane {
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
}
|
||||
|
||||
.result {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 80px;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
97
src/components/AiCheckbox/AiCheckbox.vue
Normal file
97
src/components/AiCheckbox/AiCheckbox.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="AiCheckbox">
|
||||
<div
|
||||
class="AiCheckbox-item"
|
||||
v-for="(item, index) in options"
|
||||
@click="onChange(item.value)"
|
||||
:class="[choosed.indexOf(item.value) > -1 ? 'active' : '']"
|
||||
:key="index">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AiCheckbox',
|
||||
|
||||
model: {
|
||||
event: 'input',
|
||||
prop: 'value'
|
||||
},
|
||||
|
||||
props: {
|
||||
value: Array,
|
||||
placeholder: {
|
||||
default: '请选择'
|
||||
},
|
||||
list: {
|
||||
default: () => []
|
||||
},
|
||||
dict: String,
|
||||
disabled: Boolean
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
dictKey: '',
|
||||
choosed: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
options () {
|
||||
return this.dictKey ? this.$dict.getDict(this.dict).map(e => ({
|
||||
value: e.dictValue,
|
||||
label: e.dictName
|
||||
})) : this.list
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$dict.load(this.dict).then(() => {
|
||||
this.dictKey = this.dict
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (value) {
|
||||
if (this.choosed.indexOf(value) > -1) {
|
||||
this.choosed.splice(this.choosed.indexOf(value), 1)
|
||||
} else {
|
||||
this.choosed.push(value)
|
||||
}
|
||||
|
||||
this.$emit('input', this.choosed)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiCheckbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.AiCheckbox-item {
|
||||
width: 100%;
|
||||
line-height: 1.3;
|
||||
padding: 20px 32px;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
box-sizing: border-box;
|
||||
border-radius: 16px;
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
border: 1px solid #CCCCCC;
|
||||
|
||||
&.active {
|
||||
background: #4181FF;
|
||||
color: #fff;
|
||||
border-color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
207
src/components/AiComment/AiComment.vue
Normal file
207
src/components/AiComment/AiComment.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<div class="AiComment">
|
||||
<div class="comments flex-row">
|
||||
<div class="comments-box" @click="showCommentBox">{{ boxContent }}</div>
|
||||
<img src="./static/comment.svg" @click="showCommentList" alt=""/>
|
||||
<text>{{ commentCount || 0 }}</text>
|
||||
</div>
|
||||
<div class="modalWrapper" v-if="commentBoxPopup" :class="{clickClose:!modelClickClose}"
|
||||
@click="commentBoxPopup=false"/>
|
||||
<div class="commentBox" v-if="commentBoxPopup" :style="{bottom:marginBottom+ 'px'}">
|
||||
<textarea v-model="content" placeholder="写下你的想法…" maxlength="300" :focus="focus" @focus="getMarginBottom"
|
||||
@blur="marginBottom=0" :adjust-position="false" fixed/>
|
||||
<view class="flex-row form-submit">
|
||||
<div>{{ `字数 ${wordCount || 0} / 300` }}</div>
|
||||
<button @click="submitComment" :disabled="wordCount == 0">发布</button>
|
||||
</view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AiComment",
|
||||
props: {
|
||||
needLogin: Boolean,
|
||||
customLogin: Boolean,
|
||||
commentCount: Number,
|
||||
modelClickClose: {type: Boolean, default: true}
|
||||
},
|
||||
computed: {
|
||||
wordCount() {
|
||||
return this.content.length || 0
|
||||
},
|
||||
boxContent() {
|
||||
return this.content || "我也说两句..."
|
||||
},
|
||||
isLogin() {
|
||||
return Boolean(uni.getStorageSync('token'))
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: "",
|
||||
marginBottom: 0,
|
||||
commentBoxPopup: false,
|
||||
focus: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showCommentBox() {
|
||||
if (this.customLogin) {
|
||||
this.$emit("login", flag => this.commentBoxPopup = flag)
|
||||
} else if (this.needLogin) {
|
||||
if (this.isLogin) {
|
||||
this.commentBoxPopup = true
|
||||
} else {
|
||||
this.$dialog.confirm({
|
||||
content: '您还未登陆',
|
||||
confirmText: '去登录'
|
||||
}).then(() => {
|
||||
uni.switchTab({url: '/pages/mine/mine'})
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.commentBoxPopup = true
|
||||
}
|
||||
},
|
||||
submitComment() {
|
||||
this.commentBoxPopup = false
|
||||
this.$emit("submitComment", this.content)
|
||||
this.content = ""
|
||||
},
|
||||
showCommentList() {
|
||||
this.commentBoxPopup = false
|
||||
this.$emit("showCommentList")
|
||||
},
|
||||
getMarginBottom({detail}) {
|
||||
this.marginBottom = detail.height
|
||||
this.focus = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.AiComment {
|
||||
.comments {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
background: #f7f7f7;
|
||||
|
||||
.comments-box {
|
||||
width: 580px;
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
font-size: 26px;
|
||||
padding-left: 16px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
margin-left: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
text {
|
||||
color: #666666;
|
||||
font-size: 28px;
|
||||
line-height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.modalWrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
z-index: 9;
|
||||
|
||||
&.clickClose {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.commentBox {
|
||||
width: 100%;
|
||||
height: 288px;
|
||||
background-color: #fff;
|
||||
padding: 32px 32px 24px 26px;
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 99;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 144px;
|
||||
color: #666;
|
||||
font-size: 26px;
|
||||
background: #F7F7F7;
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::placeholder {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.form-submit {
|
||||
margin-top: 24px;
|
||||
height: 64px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
|
||||
button {
|
||||
width: 144px;
|
||||
height: 64px;
|
||||
background-color: #135AB8;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
border-radius: 32px;
|
||||
line-height: 64px;
|
||||
text-align: center;
|
||||
margin: unset;
|
||||
|
||||
&[disabled] {
|
||||
color: #999;
|
||||
background-color: #f7f7f7;
|
||||
font-size: 28px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
11
src/components/AiComment/static/comment.svg
Normal file
11
src/components/AiComment/static/comment.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="26px" height="26px" viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 55.2 (78181) - https://sketchapp.com -->
|
||||
<title>icon/tab_bar/Comment</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="icon/tab_bar/Comment" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M4.75,21.7864745 L9.45344419,19.4347524 C9.6964412,19.3132539 9.96438906,19.25 10.236068,19.25 L20,19.25 C20.6903559,19.25 21.25,18.6903559 21.25,18 L21.25,8 C21.25,7.30964406 20.6903559,6.75 20,6.75 L6,6.75 C5.30964406,6.75 4.75,7.30964406 4.75,8 L4.75,21.7864745 Z" id="矩形" stroke="#333333" stroke-width="1.5"></path>
|
||||
<rect id="矩形" fill="#999999" x="8" y="10.5" width="10" height="1.5" rx="0.75"></rect>
|
||||
<rect id="矩形备份" fill="#999999" x="8" y="14" width="10" height="1.5" rx="0.75"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 983 B |
149
src/components/AiDetail/AiDetail.vue
Normal file
149
src/components/AiDetail/AiDetail.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<section class="AiDetail">
|
||||
<div class="content">
|
||||
<div class="title">{{detail.title}}</div>
|
||||
<div class="info">
|
||||
<span>{{detail.createTime}}</span>
|
||||
<span class="right">
|
||||
<em>{{detail.viewCount}}</em>人看过
|
||||
</span>
|
||||
</div>
|
||||
<slot v-if="$slots.content" name="content"/>
|
||||
<u-parse v-else :html="detail.content"/>
|
||||
</div>
|
||||
<!-- <div class="files" v-if="detail.contentType==0 && detail.files && detail.files.length">-->
|
||||
<!-- <img class="file-img" :src="file.url" @click.native="preview(index)" alt="" v-for="(file,index) in detail.files" :key="index">-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="files" v-if="detail.contentType==1 && detail.files && detail.files.length">
|
||||
<video class="file-img" :src="file.url" v-for="(file,index) in detail.files" :key="index"></video>
|
||||
</div>
|
||||
|
||||
<div v-if="comment" class="comments">
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiImage from "../../components/AiImage/AiImage";
|
||||
import AiTopFixed from "../../components/AiTopFixed/AiTopFixed";
|
||||
export default {
|
||||
name: "AiDetail",
|
||||
components: {AiImage, AiTopFixed},
|
||||
props: {
|
||||
title: {default: ""},
|
||||
detail: {default: () => ({})},
|
||||
comment: Boolean
|
||||
},
|
||||
methods: {
|
||||
preview(index) {
|
||||
this.$previewImage(this.detail.files,index,"url");
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiDetail {
|
||||
min-height: 100vh;
|
||||
background: #ffffff;
|
||||
|
||||
.header {
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
justify-content: space-between;
|
||||
margin-top: 16px;
|
||||
color: #999;
|
||||
|
||||
.u-icon + .u-icon {
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content{
|
||||
padding: 32px;
|
||||
background: #fff;
|
||||
|
||||
&.content {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.title{
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 52px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 64px;
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
|
||||
.right{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em{
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.files {
|
||||
padding: 0 32px;
|
||||
background: #fff;
|
||||
|
||||
.file-img{
|
||||
width:100%;
|
||||
height:486px;
|
||||
margin-bottom:32px;
|
||||
}
|
||||
}
|
||||
|
||||
.imageList {
|
||||
justify-content: space-around;
|
||||
|
||||
.AiImage {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.fileList {
|
||||
& > div {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
margin-left: 16px;
|
||||
word-break: break-all;
|
||||
align-items: center;
|
||||
|
||||
& > span {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
& > i {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
41
src/components/AiEmpty/AiEmpty.vue
Normal file
41
src/components/AiEmpty/AiEmpty.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="emptyWrap">
|
||||
<img class="emptyImg" src="https://cdn.cunwuyun.cn/dvcp/h5/Empty.png">
|
||||
<div class="emptyText">{{ description }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiEmpty",
|
||||
props: {
|
||||
description: {
|
||||
default: '暂无相关信息',
|
||||
type: String
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.emptyWrap {
|
||||
width:100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 80px;
|
||||
|
||||
.emptyImg {
|
||||
width: 400px;
|
||||
height: 240px;
|
||||
margin-top: 52px;
|
||||
}
|
||||
|
||||
.emptyText {
|
||||
font-size: 29px;
|
||||
font-weight: 400;
|
||||
color: rgba(183, 183, 183, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
src/components/AiEmpty/static/Empty.png
Normal file
BIN
src/components/AiEmpty/static/Empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
35
src/components/AiFixedBtn/AiFixedBtn.vue
Normal file
35
src/components/AiFixedBtn/AiFixedBtn.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<section class="AiFixedBtn">
|
||||
<movable-area class="movableArea">
|
||||
<movable-view direction="all" x="300" y="500" @tap.stop>
|
||||
<slot/>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiFixedBtn"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiFixedBtn {
|
||||
.movableArea {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 999;
|
||||
|
||||
uni-movable-view {
|
||||
pointer-events: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
27
src/components/AiIcon/AiIcon.vue
Normal file
27
src/components/AiIcon/AiIcon.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<section class="AiIcon">
|
||||
<view v-if="!singleColor" class="ai-icon" :class="icon" :style="{width:size+'px',height:size+'px'}"/>
|
||||
<view v-else class="iconfont" :style="{ fontSize: size + 'rpx', color: color }">{{ icon }}</view>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiIcon",
|
||||
props: {
|
||||
icon: String,
|
||||
singleColor: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
color: {
|
||||
type: String
|
||||
},
|
||||
size: {type: String, default: "32"}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./ai-icon.css";
|
||||
</style>
|
||||
658
src/components/AiIcon/ai-icon.css
Normal file
658
src/components/AiIcon/ai-icon.css
Normal file
File diff suppressed because one or more lines are too long
77
src/components/AiImage/AiImage.vue
Normal file
77
src/components/AiImage/AiImage.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<section class="AiImage">
|
||||
<div v-if="$slots.default" @tap="prev">
|
||||
<slot/>
|
||||
</div>
|
||||
<u-image v-else :src="image" @tap="prev">
|
||||
<image v-if="link" class="errorImage" slot="error" :src="$cdn+'link.png'"/>
|
||||
<image v-else-if="miniapp" class="errorImage" slot="error" :src="$cdn+'miniwxmp.jpg'"/>
|
||||
<image v-else class="errorImage" slot="error" :src="$cdn+'file.png'"/>
|
||||
</u-image>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapActions} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AiImage",
|
||||
data() {
|
||||
return {
|
||||
dialog: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
image() {
|
||||
return this.src?.replace(/\\/g, '/')
|
||||
}
|
||||
},
|
||||
props: {
|
||||
src: String,
|
||||
preview: Boolean,
|
||||
link: Boolean,
|
||||
miniapp: Boolean,
|
||||
file: {
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['previewFile', 'injectJWeixin']),
|
||||
prev() {
|
||||
if (this.preview) {
|
||||
if (!!this.image) {
|
||||
uni.previewImage({
|
||||
current: this.image,
|
||||
urls: [this.image],
|
||||
success() {
|
||||
sessionStorage.setItem("previewImage", " 1")
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.previewFile({size: 1, ...this.file})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiImage {
|
||||
::v-deep image {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
::v-deep .u-image__error {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.errorImage {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
src/components/AiLogin/AiLogin.vue
Normal file
65
src/components/AiLogin/AiLogin.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="ai-login">
|
||||
<u-modal v-model="userPhoneShow" showCancelButton :showTitle="true" :title="'手机号码授权'"
|
||||
:content="'本次操作需要获取您的手机号码,请同意授权'" @cancel="hide">
|
||||
<template slot="confirm-button">
|
||||
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" class="confirm-button">同意</button>
|
||||
</template>
|
||||
</u-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AiLogin',
|
||||
data() {
|
||||
return {
|
||||
userPhoneShow: false,
|
||||
userData: {},
|
||||
code: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.$getUserProfile().then(data => {
|
||||
this.userData = data.userInfo;
|
||||
this.userPhoneShow = true;
|
||||
})
|
||||
this.$getLoginCode().then(res => {
|
||||
this.code = res.code;
|
||||
})
|
||||
},
|
||||
hide() {
|
||||
this.userPhoneShow = false
|
||||
},
|
||||
getPhoneNumber(arg) {
|
||||
const {encryptedData, errMsg, iv} = arg.detail
|
||||
if (errMsg == 'getPhoneNumber:ok') {
|
||||
this.$getLoginCode().then(() => {
|
||||
// let body = {...this.userData, encryptedData, iv, code: res.code}
|
||||
this.$instance.post(`/app/appwechatuser/getWechatUserPhone`, {
|
||||
encryptedData, iv,
|
||||
code: this.code
|
||||
}, {withoutToken: true}).then(d => {
|
||||
if (d.data) {
|
||||
let data = {...this.userData, phone: d.data};
|
||||
this.$autoLogin(data).then(res=>{
|
||||
this.$emit("success",res);
|
||||
});
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.confirm-button{
|
||||
background-color: #fff!important;
|
||||
}
|
||||
.confirm-button::after{
|
||||
border: none!important;
|
||||
}
|
||||
</style>
|
||||
202
src/components/AiNewsList/AiNewsList.vue
Normal file
202
src/components/AiNewsList/AiNewsList.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<section class="AiNewsList">
|
||||
<slot name="header"/>
|
||||
<slot v-if="$slots.content" name="content"/>
|
||||
<div class="list-wrap" v-if="list && list.length">
|
||||
<div class="list-card" v-for="(category,index) in list" :key="index" @click="$linkTo('/subPages/contentManager/contentDetail?id='+category.id)">
|
||||
<div class="header">{{category.title}}</div>
|
||||
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length == 1">
|
||||
<img class="img" :src="item.url" v-for="(item,index) in category.files" :key="index.id" alt="">
|
||||
</div>
|
||||
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length > 1">
|
||||
<img class="min-img" :src="item.url" v-for="(item,index) in category.files && category.files.slice(0,3)" :key="index.id" alt="">
|
||||
</div>
|
||||
<div class="content-wrap" v-if="category.contentType==1">
|
||||
<img class="img" :src="category.pictureUrl" alt="">
|
||||
<img class="play-icon" src="../../static/img/play.png" alt="">
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="left">
|
||||
<div class="tag">{{category.categoryName}}</div>
|
||||
{{category.createTime}}
|
||||
</div>
|
||||
<div class="right">
|
||||
<em>{{category.viewCount}}</em>
|
||||
人看过
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import AiTopFixed from "../AiTopFixed/AiTopFixed";
|
||||
import AiEmpty from "../../components/AiEmpty/AiEmpty"
|
||||
|
||||
export default {
|
||||
name: "AiNewsList",
|
||||
components: {AiTopFixed,AiEmpty},
|
||||
props: {
|
||||
list: {default: () => []},
|
||||
props: {
|
||||
default: () => ({
|
||||
title: 'title',
|
||||
type: "type",
|
||||
createTime: "createTime",
|
||||
count: "count",
|
||||
})
|
||||
},
|
||||
loadmore: {default: "loadmore"}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiNewsList {
|
||||
height: 100vh;
|
||||
background: #f3f6f9;
|
||||
|
||||
.listPane {
|
||||
padding: 24px 32px 36px;
|
||||
|
||||
.card {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
padding: 32px;
|
||||
margin-bottom: 32px;
|
||||
|
||||
.title {
|
||||
height: 50px;
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
line-height: 50px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
color: #999;
|
||||
width: 100%;
|
||||
|
||||
.tag {
|
||||
height: 48px;
|
||||
background: #EEEEEE;
|
||||
border-radius: 24px;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: #4181FF;
|
||||
}
|
||||
|
||||
.right{
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
|
||||
.list-card {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 50px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 24px;
|
||||
position: relative;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.min-img{
|
||||
width: 204px;
|
||||
height: 204px;
|
||||
}
|
||||
|
||||
.play-icon{
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius:50%;
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top: 50%;
|
||||
transform:translate(-50%,-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
|
||||
.tag {
|
||||
width: 144px;
|
||||
height: 48px;
|
||||
background: #EEEEEE;
|
||||
border-radius: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
em {
|
||||
font-style: normal;
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
120
src/components/AiRadio/AiRadio.vue
Normal file
120
src/components/AiRadio/AiRadio.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div class="AiRadio" :class="[isLine ? 'AiRadio-line' : '']">
|
||||
<div
|
||||
class="AiRadio-item"
|
||||
v-for="(item, index) in options"
|
||||
@click="onChange(index)"
|
||||
:class="[currIndex === index ? 'active' : '']"
|
||||
:key="index">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AiRadio',
|
||||
|
||||
model: {
|
||||
event: 'input',
|
||||
prop: 'value'
|
||||
},
|
||||
|
||||
props: {
|
||||
value: String,
|
||||
placeholder: {
|
||||
default: '请选择'
|
||||
},
|
||||
list: {
|
||||
default: () => []
|
||||
},
|
||||
isLine: Boolean,
|
||||
dict: String,
|
||||
disabled: Boolean
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
currIndex: -1,
|
||||
dictKey: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
options () {
|
||||
return this.dictKey ? this.$dict.getDict(this.dict).map(e => ({
|
||||
value: e.dictValue,
|
||||
label: e.dictName
|
||||
})) : this.list
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$dict.load(this.dict).then(() => {
|
||||
this.dictKey = this.dict
|
||||
|
||||
if (this.value) {
|
||||
console.log(this.value)
|
||||
this.$dict.getDict(this.dict).forEach((e, i) => {
|
||||
console.log(e)
|
||||
if (e.dictValue === this.value) {
|
||||
this.currIndex = i
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (index) {
|
||||
this.currIndex = index
|
||||
const choosed = this.options[index]
|
||||
this.$emit('name', choosed.label)
|
||||
this.$emit('input', choosed.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiRadio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.AiRadio-item {
|
||||
width: 212px;
|
||||
line-height: 1.3;
|
||||
padding: 20px 32px;
|
||||
margin-bottom: 16px;
|
||||
margin-right: 16px;
|
||||
padding: 20px 32px;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16px;
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
border: 1px solid #CCCCCC;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:nth-of-type(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #4181FF;
|
||||
color: #fff;
|
||||
border-color: #4181FF;
|
||||
}
|
||||
}
|
||||
|
||||
&.AiRadio-line {
|
||||
width: 100%;
|
||||
|
||||
.AiRadio-item {
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
99
src/components/AiSelect/AiSelect.vue
Normal file
99
src/components/AiSelect/AiSelect.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<section class="AiSelect">
|
||||
<div class="display" v-if="$slots.default" @tap="handleShowOptions">
|
||||
<slot/>
|
||||
</div>
|
||||
<div v-else class="display" @tap="handleShowOptions">
|
||||
<div class="selectedLabel" v-if="selectedLabel">{{ selectedLabel }}</div>
|
||||
<i v-else>{{ placeholder }}</i>
|
||||
<u-icon name="arrow-right" color="#ddd"/>
|
||||
</div>
|
||||
<u-select v-model="show" :list="options" :mode="mode" @confirm="handleConfirm"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiSelect",
|
||||
model: {
|
||||
event: "input",
|
||||
prop: "value"
|
||||
},
|
||||
props: {
|
||||
value: String,
|
||||
placeholder: {default: "请选择"},
|
||||
list: {default: () => []},
|
||||
mode: {default: "single-column"},
|
||||
dict: {default: ""},
|
||||
disabled: Boolean
|
||||
},
|
||||
computed: {
|
||||
selectedLabel() {
|
||||
let label = this.options.find(e => e.value == this.value)?.label
|
||||
return this.selected?.map(e => e.label)?.join(",") || label
|
||||
},
|
||||
options() {
|
||||
return this.dictKey ? this.$dict.getDict(this.dict).map(e => ({
|
||||
value: e.dictValue,
|
||||
label: e.dictName
|
||||
})) : this.list
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
dictKey: '',
|
||||
selected: []
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.dict && this.$dict.load(this.dict).then(() => {
|
||||
this.dictKey = this.dict
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleConfirm(v) {
|
||||
this.selected = v
|
||||
this.$emit("data", this.selected)
|
||||
console.log(v)
|
||||
this.$emit("input", v[0].value)
|
||||
this.$forceUpdate()
|
||||
},
|
||||
handleShowOptions() {
|
||||
if (!this.disabled) this.show = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiSelect {
|
||||
max-width: 100%;
|
||||
|
||||
::v-deep .u-icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.selectedLabel {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 30px;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
font-size: 30px;
|
||||
color: $uni-text-color-grey;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
src/components/AiTopFixed/AiTopFixed.vue
Normal file
65
src/components/AiTopFixed/AiTopFixed.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<section class="AiTopFixed" :style="{background}">
|
||||
<!--占位区-->
|
||||
<div class="placeholder">
|
||||
<div v-if="$slots.tabs">
|
||||
<slot name="tabs"/>
|
||||
</div>
|
||||
<div class="content" v-if="$slots.default">
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
<!--悬浮区-->
|
||||
<div class="fixed" :style="{background}">
|
||||
<div v-if="$slots.tabs">
|
||||
<slot name="tabs"/>
|
||||
</div>
|
||||
<div class="content" v-if="$slots.default">
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiTopFixed",
|
||||
props: {
|
||||
background: {default: "#fff"}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiTopFixed {
|
||||
width: 100%;
|
||||
|
||||
& > div {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
min-height: 100px;
|
||||
padding: 20px 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::v-deep .u-search {
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
margin-bottom: 32px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
146
src/components/AiTransSpeech/AiTransSpeech.vue
Normal file
146
src/components/AiTransSpeech/AiTransSpeech.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="AiTransSpeech" v-if="!noSpeech">
|
||||
<button title="语音播报" @click="getSpeech">
|
||||
<div>
|
||||
<div class="iconfont" :class="{playing:loading}"></div>
|
||||
</div>
|
||||
<div>{{ text }}</div>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AiTransSpeech",
|
||||
props: {
|
||||
src: String,
|
||||
content: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
audioContext: null,
|
||||
speech: "",
|
||||
loading: false,
|
||||
text: "开始"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
speechString() {
|
||||
return this.content ? this.content.replace(/<\/?.+?\/?>/g, "") : ""
|
||||
},
|
||||
noSpeech() {
|
||||
return !this.src && !this.content
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getSpeech() {
|
||||
if (!this.noSpeech) {
|
||||
if (this.audioContext) {
|
||||
if (this.loading) {
|
||||
this.loading = false
|
||||
this.audioContext.pause()
|
||||
} else {
|
||||
this.loading = true
|
||||
this.audioContext.play()
|
||||
}
|
||||
} else if (this.content) {
|
||||
this.loading = true
|
||||
if (!this.speech) {
|
||||
this.$instance.post("/app/msc/transToSpeech" + `?fileName=demo&words=${this.speechString}`).then(res => {
|
||||
if (res && res.data) {
|
||||
let url = res.data.join("")
|
||||
this.speech = url.substring(0, url.indexOf(";"))
|
||||
this.playAudio()
|
||||
}
|
||||
}).catch(() => this.loading = false)
|
||||
} else {
|
||||
this.playAudio()
|
||||
}
|
||||
} else if (this.src) {
|
||||
this.loading = true
|
||||
this.speech = this.src
|
||||
this.playAudio()
|
||||
}
|
||||
}
|
||||
},
|
||||
playAudio() {
|
||||
let _ = this
|
||||
this.audioContext = uni.createInnerAudioContext();
|
||||
this.audioContext.src = this.speech;
|
||||
this.audioContext.play()
|
||||
this.audioContext.onPlay(() => {
|
||||
_.text = "暂停"
|
||||
});
|
||||
this.audioContext.onPause(() => {
|
||||
_.loading = false
|
||||
_.text = "开始"
|
||||
});
|
||||
this.audioContext.onEnded(() => {
|
||||
_.loading = false
|
||||
_.text = "开始"
|
||||
});
|
||||
this.audioContext.onError((res) => {
|
||||
console.error(res.errMsg);
|
||||
_.text = "开始"
|
||||
});
|
||||
},
|
||||
},
|
||||
destroyed() {
|
||||
if (this.audioContext) {
|
||||
this.audioContext.pause()
|
||||
this.audioContext.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiTransSpeech {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
position: fixed;
|
||||
right: 80px;
|
||||
bottom: 150px;
|
||||
width: 104px;
|
||||
height: 104px;
|
||||
background: linear-gradient(130deg, rgba(70, 192, 253, 1) 0%, rgba(37, 158, 249, 1) 57%, rgba(39, 148, 248, 1) 100%);
|
||||
border-radius: 50%;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff !important;
|
||||
z-index: 10000;
|
||||
|
||||
& > div {
|
||||
width: 48px;
|
||||
white-space: nowrap;
|
||||
line-height: normal;
|
||||
|
||||
.iconfont {
|
||||
width: 48px;
|
||||
font-size: 48px;
|
||||
line-height: 48px;
|
||||
overflow: hidden;
|
||||
|
||||
&.playing {
|
||||
animation: playingSpeech .5s infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes playingSpeech {
|
||||
from {
|
||||
width: 30px
|
||||
}
|
||||
to {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
419
src/components/AiUniIcon/AiUniIcon.vue
Normal file
419
src/components/AiUniIcon/AiUniIcon.vue
Normal file
File diff suppressed because one or more lines are too long
226
src/components/AiUploader/AiUploader.vue
Normal file
226
src/components/AiUploader/AiUploader.vue
Normal file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div class="ai-uploader">
|
||||
<div class="imgs flex-align">
|
||||
<div class="img" v-for="(item, index) in fileList" :key="index">
|
||||
<image :src="item.url" hover-class="text-hover" @click="prev(index)" class="image" />
|
||||
<!-- <i class="iconfont" @click="remove(index)"></i> -->
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/upload/del-icon.png" alt="" class="del-icon" @click="remove(index)"/>
|
||||
</div>
|
||||
<div class="upload" @click="upload" v-if="fileList.length < limit">
|
||||
<!-- <i class="iconfont"></i> -->
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/upload/add-icon.png" alt="" class="add-icon"/>
|
||||
<span>添加照片</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from '@/utils/axios.js'
|
||||
|
||||
export default {
|
||||
name: 'AiUploader',
|
||||
|
||||
model: {
|
||||
event: 'input',
|
||||
prop: 'value',
|
||||
},
|
||||
|
||||
props: {
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
|
||||
type: {
|
||||
type: 'img',
|
||||
},
|
||||
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.fileList = [...val]
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
fileList: [],
|
||||
hideStatus: false,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
remove(index) {
|
||||
this.fileList.splice(index, 1)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('input', [...this.fileList])
|
||||
this.$emit('change', [...this.fileList])
|
||||
})
|
||||
},
|
||||
|
||||
prev(index) {
|
||||
uni.previewImage({
|
||||
current: this.fileList[index].url,
|
||||
urls: this.fileList.map((v) => v.url),
|
||||
})
|
||||
},
|
||||
|
||||
upload() {
|
||||
uni.chooseImage({
|
||||
count: this.limit,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: (res) => {
|
||||
if (this.fileList.length + res.tempFilePaths.length > this.limit && this.limit !== 1) {
|
||||
this.$toast(`图片不能超过${this.limit}张`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
this.$loading('上传中')
|
||||
res.tempFilePaths.forEach((item, index) => {
|
||||
if (index === res.tempFilePaths.length - 1) {
|
||||
this.hideStatus = true
|
||||
}
|
||||
console.log(item)
|
||||
this.uploadFile(item)
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
uploadFile(img) {
|
||||
uni.uploadFile({
|
||||
url: axios.baseURL + '/admin/file/add',
|
||||
filePath: img,
|
||||
name: 'file',
|
||||
header: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
Authorization: uni.getStorageSync('token'),
|
||||
},
|
||||
success: (res) => {
|
||||
const data = JSON.parse(res.data)
|
||||
|
||||
if (data.code === 0) {
|
||||
if (this.limit === 1) {
|
||||
this.fileList = [
|
||||
{
|
||||
id: data.data[0].split(';')[1],
|
||||
url: data.data[0].split(';')[0],
|
||||
},
|
||||
]
|
||||
} else {
|
||||
this.fileList.push({
|
||||
id: data.data[0].split(';')[1],
|
||||
url: data.data[0].split(';')[0],
|
||||
})
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('input', [...this.fileList])
|
||||
this.$emit('change', [...this.fileList])
|
||||
})
|
||||
} else {
|
||||
this.$toast(data.msg)
|
||||
}
|
||||
},
|
||||
complete: () => {
|
||||
if (this.hideStatus) {
|
||||
this.$hideLoading()
|
||||
this.hideStatus = false
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ai-uploader {
|
||||
.del-icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 11;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
-webkit-transform: translate(50%, -50%);
|
||||
transform: translate(50%, -50%);
|
||||
}
|
||||
|
||||
.imgs {
|
||||
flex-wrap: wrap;
|
||||
|
||||
div {
|
||||
position: relative;
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:nth-of-type(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
i {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 11;
|
||||
font-size: 28px;
|
||||
opacity: 0.8;
|
||||
color: #f72c27;
|
||||
transform: translate(50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.upload {
|
||||
width: 224px;
|
||||
height: 224px;
|
||||
text-align: center;
|
||||
border: 1px solid #dddddd;
|
||||
box-sizing: border-box;
|
||||
|
||||
i {
|
||||
padding: 42px 0 16px;
|
||||
color: #ddd;
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
.add-icon {
|
||||
margin: 50px 0 16px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: #dddddd;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
42
src/main.js
Normal file
42
src/main.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import axios from "./utils/axios"
|
||||
import utils from './utils/util'
|
||||
import config from './utils/config'
|
||||
import dayjs from 'dayjs'
|
||||
import vui from 'uview-ui'
|
||||
import 'uview-ui/theme.scss'
|
||||
import AiAreaPicker from '@/components/AiAreaPicker/AiAreaPicker'
|
||||
import AiLogin from '@/components/AiLogin/AiLogin'
|
||||
import AiRadio from '@/components/AiRadio/AiRadio'
|
||||
import AiCheckbox from '@/components/AiCheckbox/AiCheckbox'
|
||||
|
||||
Vue.use(vui)
|
||||
Vue.component('ai-area-picker', AiAreaPicker)
|
||||
Vue.component('AiLogin', AiLogin)
|
||||
Vue.component('AiRadio', AiRadio)
|
||||
Vue.component('AiCheckbox', AiCheckbox)
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$instance = axios.instance
|
||||
Vue.prototype.$areaId = config.areaId;
|
||||
Vue.prototype.$areaName = config.areaName;
|
||||
Vue.prototype.$cdn = 'https://cdn.cunwuyun.cn/'
|
||||
|
||||
App.mpType = 'app'
|
||||
|
||||
var relativeTime = require('dayjs/plugin/relativeTime')
|
||||
var duration = require('dayjs/plugin/duration')
|
||||
require('dayjs/locale/zh-cn')
|
||||
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime)
|
||||
Vue.prototype.$dayjs = dayjs
|
||||
|
||||
Object.keys(utils).map(e => Vue.prototype[e] = utils[e])
|
||||
|
||||
const app = new Vue({
|
||||
store,
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
22
src/manifest.json
Normal file
22
src/manifest.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "dvcp-wechatApps",
|
||||
"description": "数字乡村小程序应用库",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": true,
|
||||
"mp-weixin": {
|
||||
"appid": "wx8d6346f632980668",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"optimization": {
|
||||
"subPackages": true
|
||||
},
|
||||
"usingComponents": true,
|
||||
"permission": {
|
||||
"scope.userLocation": {
|
||||
"desc": "你的位置信息将用于当前事件发生地点"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
353
src/mods/AppActivityList/AppActivityList.vue
Normal file
353
src/mods/AppActivityList/AppActivityList.vue
Normal file
@@ -0,0 +1,353 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="fixed-top">
|
||||
<div class="header-search">
|
||||
<div class="search-input-content">
|
||||
<img src="https://cdn.cunwuyun.cn/img/search-blue.svg" alt="" class="search-icon">
|
||||
<input type="text" placeholder="请输入活动名称或地点" class="search-input" placeholder-style="color:#E2E8F1;"
|
||||
v-model="inputValue" @confirm="getListInit" confirm-type="search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-select">
|
||||
<div class="select-item" @click="activeStatusShow = true">
|
||||
<span>{{ activeStatusLabel }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
<div class="select-item" @click="checkStatusShow = true">
|
||||
<span>{{ checkStatusLabel }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="active-list">
|
||||
<div class="item" v-for="(item, index) in list" :key="index" @click="isToken(`./detail?id=${item.id}`)">
|
||||
<div class="item-top">
|
||||
<p class="title">{{ item.title }}</p>
|
||||
<div class="info">
|
||||
<span class="label">活动时间:</span>
|
||||
<span class="value">{{ item.beginTime }} 至<br/>{{ item.endTime }}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">活动地点:</span>
|
||||
<span class="value">{{ item.address }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-btn">
|
||||
<span class="phone-btn" @click.stop="callPhone(item.contactPhone)" v-if="item.contactPhone">呼叫联系人</span>
|
||||
<span v-if="item.signupStatus == 0 && item.logStatus == null"
|
||||
@click="isToken(`./toAdd?id=${item.id}`)">去报名</span>
|
||||
<span v-if="item.actionStatus == 1 && item.logStatus == 0"
|
||||
@click="isToken(`./addContent?id=${item.id}&reportId=${item.reportId}`)">填写日志</span>
|
||||
<span v-if="item.logStatus == 2" @click="isToken(`./logDetail?id=${item.id}&title=${item.title}`)">查看日志</span>
|
||||
</div>
|
||||
<span class="item-status"
|
||||
:class="'color'+item.actionStatus">{{
|
||||
$dict.getLabel('partyReportActionStatus', item.actionStatus)
|
||||
}}</span>
|
||||
</div>
|
||||
<AiEmpty v-if="!list.length" class="pad-t168"/>
|
||||
</div>
|
||||
<div class="fixed-bottom btn-footer">
|
||||
<div :class="listType == 0 ? 'confirm-bg' : ''" @click="listTypeChange('0')">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/activityList/more-icon-fff.png" alt="" v-if="listType == 0">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/activityList/more-icon-999.png" alt="" v-else>
|
||||
活动列表
|
||||
</div>
|
||||
<div :class="listType == 3 ? 'confirm-bg' : ''" @click="listTypeChange('3')">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/activityList/pen-icon-fff.png" alt="" v-if="listType == 3">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/activityList/pen-icon-999.png" alt="" v-else>
|
||||
我的活动
|
||||
</div>
|
||||
</div>
|
||||
<u-select v-model="activeStatusShow" :list="activeStatusList" @confirm="confirmActiveStatus"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<u-select v-model="checkStatusShow" :list="checkStatusList" @confirm="confirmActiveStatus"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<ai-login ref="login"></ai-login>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "AppActivityList",
|
||||
appName: "居民活动",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
current: 1,
|
||||
list: [],
|
||||
activeStatus: '',
|
||||
activeStatusLabel: '活动状态',
|
||||
activeStatusShow: false,
|
||||
activeStatusList: [],
|
||||
checkStatusShow: false,
|
||||
checkStatusList: [],
|
||||
checkStatus: '',
|
||||
checkStatusLabel: '报名状态',
|
||||
listType: '0',
|
||||
partyId: '',
|
||||
areaId: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.areaId = uni.getStorageSync('areaId')
|
||||
if (this.user.partyId) {
|
||||
this.partyId = this.user.partyId
|
||||
} else {
|
||||
this.partyId = this.user.residentId
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.$dict.load('partyReportActionStatus', 'partyReportSignupStatus').then((res) => {
|
||||
this.activeStatusList = this.getSelectList('partyReportActionStatus')
|
||||
this.checkStatusList = this.getSelectList('partyReportSignupStatus')
|
||||
this.getListInit()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
confirmActiveStatus(e) {
|
||||
if (this.activeStatusShow) {
|
||||
this.activeStatusLabel = e[0].label
|
||||
this.activeStatus = e[0].value
|
||||
}
|
||||
|
||||
if (this.checkStatusShow) {
|
||||
this.checkStatusLabel = e[0].label
|
||||
this.checkStatus = e[0].value
|
||||
}
|
||||
this.getListInit()
|
||||
},
|
||||
getListInit() {
|
||||
this.current = 1
|
||||
this.list = []
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post(`/app/apppartyreport/list-xcx?title=${this.inputValue}&size=10¤t=${this.current}&listType=${this.listType}&actionStatus=${this.activeStatus}&signupStatus=${this.checkStatus}&partyId=${this.partyId}&areaId=${this.areaId}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (this.current > res.data.pages) {
|
||||
return
|
||||
}
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
}
|
||||
})
|
||||
},
|
||||
isToken(url) {
|
||||
if (this.token) {//判断是否登录
|
||||
if (this.user.status == 0) {
|
||||
if (!this.user.phone) {//判断已经绑定手机
|
||||
this.$linkTo('/pages/phone/bingPhoneNumber?from=auth')
|
||||
} else {
|
||||
this.$linkTo('/pages/auth/authenticationInfo')
|
||||
}
|
||||
} else {
|
||||
this.$linkTo(url)
|
||||
}
|
||||
} else {
|
||||
// this.$getUserProfile().then((v) => {
|
||||
// this.$autoLogin(v.userInfo).then(() => {
|
||||
// this.isToken(url)
|
||||
// })
|
||||
// }).catch(() => {
|
||||
// this.$toast('请先登录')
|
||||
// })
|
||||
this.login()
|
||||
}
|
||||
},
|
||||
login() {
|
||||
this.$refs.login.show()
|
||||
},
|
||||
// toDetail(id) {
|
||||
// this.$linkTo(`./detail?id=${id}`)
|
||||
// },
|
||||
// toAddContent(id, reportId) {
|
||||
// this.$linkTo(`./addContent?id=${id}&reportId=${reportId}`)
|
||||
// },
|
||||
// toAdd(id) {
|
||||
// this.$linkTo(`./add?id=${id}`)
|
||||
// },
|
||||
// toLogDetail(id) {
|
||||
// this.$linkTo(`./logDetail?id=${id}`)
|
||||
// },
|
||||
listTypeChange(type) {
|
||||
this.listType = type
|
||||
this.activeStatus = ''
|
||||
this.activeStatusLabel = '活动状态'
|
||||
this.checkStatus = ''
|
||||
this.checkStatusLabel = '报名状态'
|
||||
this.getListInit()
|
||||
},
|
||||
getSelectList(dictName) {
|
||||
var list = []
|
||||
this.$dict.getDict(dictName).map(i => {
|
||||
var item = {
|
||||
label: i.dictName,
|
||||
value: i.dictValue
|
||||
}
|
||||
list.push(item)
|
||||
})
|
||||
list.unshift({label: '全部', value: ''})
|
||||
return list
|
||||
},
|
||||
callPhone(phone) {
|
||||
wx.makePhoneCall({
|
||||
phoneNumber: phone,
|
||||
})
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current = this.current + 1;
|
||||
this.getList()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.fixed-top {
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.active-list {
|
||||
padding: 234px 32px 112px;
|
||||
margin-top: 8px;
|
||||
background-color: #F3F6F9;
|
||||
box-sizing: border-box;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
background: #FFF;
|
||||
padding: 32px 0 0;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 34px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.item-top {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 576px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 30px;
|
||||
line-height: 42px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
width: 150px;
|
||||
color: #999;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: calc(100% - 150px);
|
||||
color: #343D65;
|
||||
}
|
||||
}
|
||||
|
||||
.item-btn {
|
||||
margin-top: 32px;
|
||||
padding: 20px 32px;
|
||||
border-top: 2px solid #eee;
|
||||
text-align: right;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 0 24px;
|
||||
line-height: 56px;
|
||||
border-radius: 28px;
|
||||
border: 2px solid #1365DD;
|
||||
color: #1365DD;
|
||||
font-size: 28px;
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
.phone-btn {
|
||||
border: 2px solid #E1E1E1;
|
||||
color: #606060;
|
||||
}
|
||||
}
|
||||
|
||||
.item-status {
|
||||
width: 160px;
|
||||
height: 40px;
|
||||
line-height: 36px;
|
||||
font-size: 26px;
|
||||
font-weight: 500;
|
||||
position: absolute;
|
||||
right: -38px;
|
||||
top: 24px;
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(45deg);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.color0 {
|
||||
background: #FFF3E9;
|
||||
color: #FF8822;
|
||||
}
|
||||
|
||||
.color1 {
|
||||
background: #EEF5FF;
|
||||
color: #5A98F2;
|
||||
}
|
||||
|
||||
.color2 {
|
||||
background: #F2F2F2;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-footer {
|
||||
display: flex;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
background-color: #fff;
|
||||
border-top: 2px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-right: 8px;
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-bg {
|
||||
background-color: #197DF0;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
205
src/mods/AppActivityList/add.vue
Normal file
205
src/mods/AppActivityList/add.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="add-form">
|
||||
<div class="form-item">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">活动报名类型</span>
|
||||
<span :class="reportType ? 'value color-333' : 'value color-999'"
|
||||
@click="reportTypeShow = true">{{ reportTypeList[reportType].label || '请选择' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/right-icon-999.png" alt="" class="right-icon">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">联系手机</span>
|
||||
<div class="item-input">
|
||||
<input type="tel" placeholder="请输入手机号码" placeholder-style="color:#999;" maxlength="11" v-model="phone">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<span class="item-tips"></span>
|
||||
<span class="label">报名备注</span>
|
||||
<div class="item-input fs-32">
|
||||
<u-input type="textarea" height="140" placeholder="填写报名备注(1000字以内)" placeholder-style="color:#999;"
|
||||
maxlength="1000" v-model="remark"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips-content">
|
||||
<p>报到类型说明:</p>
|
||||
<p>1、单位联系社区报到服务:党员所属单位联系的社区参与活动,到社区服务;</p>
|
||||
<p>2、居住地社区报到服务:党员所在本人居住的社区参与活动,到社区服务;</p>
|
||||
<p>3、其他村(社区)报到服务:党员所在除单位联系社区与居住社区以外的其他社区参与活动,到社区服务;</p>
|
||||
</div>
|
||||
<u-select v-model="reportTypeShow" :list="reportTypeList" @confirm="confirmReportType"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<div class="fixed-bottom confirm-btn" @click="confirm">提交</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "add",
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reportType: '',
|
||||
title: '',
|
||||
content: '',
|
||||
reportTypeList: [],
|
||||
reportTypeShow: false,
|
||||
flag: false,
|
||||
id: '',
|
||||
phone: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.id = option.id
|
||||
this.$dict.load('partyReportSignupReportType').then((res) => {
|
||||
this.$nextTick(() => {
|
||||
this.$dict.getDict('partyReportSignupReportType').map(i => {
|
||||
var item = {
|
||||
label: i.dictName,
|
||||
value: i.dictValue
|
||||
}
|
||||
this.reportTypeList.push(item)
|
||||
})
|
||||
})
|
||||
})
|
||||
this.phone = this.user.phone
|
||||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
if (this.flag) return
|
||||
this.$loading()
|
||||
var params = {
|
||||
reportType: this.reportType,
|
||||
phone: this.phone,
|
||||
remark: this.remark,
|
||||
reportId: this.id,
|
||||
avatar: this.user.avatarUrl,
|
||||
partyId: this.user.partyId || this.user.residentId
|
||||
}
|
||||
if (!params.reportType) {
|
||||
return this.$toast('请选择活动报名类型')
|
||||
}
|
||||
if (!params.phone) {
|
||||
return this.$toast('请输入联系手机')
|
||||
}
|
||||
this.flag = true
|
||||
this.$instance.post(`/app/apppartyreport/signup`, params).then(res => {
|
||||
if (res && res.code == 0) {
|
||||
this.$hideLoading()
|
||||
this.$toast('活动报名成功!')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
this.flag = false
|
||||
})
|
||||
},
|
||||
confirmReportType(e) {
|
||||
this.reportType = e[0].value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.form-item {
|
||||
padding: 34px 32px 34px 12px;
|
||||
line-height: 44px;
|
||||
background-color: #fff;
|
||||
border-bottom: 2px solid #ddd;
|
||||
|
||||
.item-tips {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
font-size: 32px;
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
min-width: 126px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-left: 8px;
|
||||
|
||||
.mini-label {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: 454px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
width: 520px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.color-333 {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-input {
|
||||
padding-bottom: 4px;
|
||||
margin-left: 24px;
|
||||
margin-top: 32px;
|
||||
|
||||
input {
|
||||
line-height: 42px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.upload {
|
||||
margin: 32px 0 024px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-item:nth-last-child(1) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
padding: 64px 32px 0;
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
line-height: 40px;
|
||||
font-size: 28px;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
178
src/mods/AppActivityList/addContent.vue
Normal file
178
src/mods/AppActivityList/addContent.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="header-bg"></div>
|
||||
<div class="add-form">
|
||||
<div class="form-item">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">活动总结</span>
|
||||
<div class="item-input fs-32">
|
||||
<u-input type="textarea" height="140" placeholder="填写本次活动参与心得体会(1000字以内)" placeholder-style="color:#999;"
|
||||
maxlength="1000" v-model="content"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<span class="item-tips"></span>
|
||||
<span class="label">活动照片<span class="mini-label">(最多9张)</span></span>
|
||||
<div class="upload">
|
||||
<AiUploader :limit="9" v-model="files"></AiUploader>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed-bottom confirm-btn" @click="confirm">提交</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import AiUploader from '@/components/AiUploader/AiUploader'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "addContent",
|
||||
components: {
|
||||
AiUploader
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
files: [],
|
||||
flag: false,
|
||||
id: '',
|
||||
reportId: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.id = option.id
|
||||
this.reportId = option.reportId
|
||||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
if (this.flag) return
|
||||
this.$loading()
|
||||
|
||||
var fileIds = []
|
||||
if (this.files.length) {
|
||||
this.files.map((item) => {
|
||||
fileIds.push(item.id)
|
||||
})
|
||||
}
|
||||
|
||||
var params = {
|
||||
reportId: this.reportId,
|
||||
id: this.id,
|
||||
content: this.content,
|
||||
files: this.files,
|
||||
fileIds: fileIds
|
||||
}
|
||||
if (!params.content) {
|
||||
return this.$toast('请输入本次活动参与心得体会')
|
||||
}
|
||||
this.flag = true
|
||||
this.$instance.post(`/app/apppartyreport/log-add`, params).then(res => {
|
||||
if (res && res.code == 0) {
|
||||
this.$hideLoading()
|
||||
this.$toast('日志填写成功!')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
this.flag = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.header-bg {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background: #197DF0;
|
||||
}
|
||||
|
||||
.add-form {
|
||||
margin: -96px 0 0 32px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
width: 686px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
padding: 34px 32px 34px 12px;
|
||||
line-height: 44px;
|
||||
|
||||
.item-tips {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
font-size: 32px;
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
min-width: 126px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-left: 8px;
|
||||
|
||||
.mini-label {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: 518px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
width: 520px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.color-333 {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-input {
|
||||
padding-bottom: 4px;
|
||||
margin-left: 24px;
|
||||
margin-top: 32px;
|
||||
|
||||
input {
|
||||
line-height: 42px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.upload {
|
||||
margin: 32px 0 0 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
238
src/mods/AppActivityList/detail.vue
Normal file
238
src/mods/AppActivityList/detail.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="header-info">
|
||||
<p class="title">{{ info.title }}</p>
|
||||
<div class="info">
|
||||
<span class="label">联系人:</span>
|
||||
<span class="value">{{ info.contactPerson }}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">联系电话:</span>
|
||||
<span class="value">{{ info.contactPhone }}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">活动时间:</span>
|
||||
<span class="value">{{ info.beginTime }} 至 {{ info.endTime }}</span>
|
||||
</div>
|
||||
<div v-if="viewMore">
|
||||
<div class="info">
|
||||
<span class="label">活动地点:</span>
|
||||
<span class="value">{{ info.address }}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">参与名额:</span>
|
||||
<span class="value" v-if="info.total > 0">限{{ info.total }}人</span>
|
||||
<span class="value" v-else>不限额</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">报名截止时间:</span>
|
||||
<span class="value">{{ info.stopSignupTime }}({{ info.timeRemaining }})</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">活动报名人数:</span>
|
||||
<span class="value">共{{ info.signupCount }}人报名</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span class="label">活动状态:</span>
|
||||
<span class="value">{{ $dict.getLabel('partyReportActionStatus', info.actionStatus) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view-btn" @click="viewMore = !viewMore">{{ viewMore ? '收起' : '展开' }}<img
|
||||
:class="viewMore ? 'view-btn-active' : ''" src="https://cdn.cunwuyun.cn/img/down-icon-fff.png" alt=""/></div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p class="title">活动介绍</p>
|
||||
<!-- <div class="html" v-html="info.content"></div> -->
|
||||
<u-parse :html="info.content"></u-parse>
|
||||
</div>
|
||||
<div class="fixed-bottom btn-footer">
|
||||
<div @click="$linkTo(`./userList?id=${info.id}`)"><img
|
||||
src="https://cdn.cunwuyun.cn/dvcp/activityList/more-icon-999.png" alt=""/>查看报名情况
|
||||
</div>
|
||||
<div class="confirm-bg" v-if="info.signupStatus == 0 && info.logStatus == null"
|
||||
@click="$linkTo(`./add?id=${info.id}`)"><img src="https://cdn.cunwuyun.cn/dvcp/activityList/edit-icon"
|
||||
alt=""/>立即报名
|
||||
</div>
|
||||
<!-- <div class="confirm-bg" v-if="info.logStatus != null && info.logStatus != 0" @click="cancel()">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/activityList/cancel-icon" alt="">取消报名
|
||||
</div> -->
|
||||
<div class="confirm-bg" v-if="info.actionStatus == 1 && info.logStatus == 0"
|
||||
@click="$linkTo(`./addContent?id=${info.signupId}&reportId=${info.id}`)"><img
|
||||
src="https://cdn.cunwuyun.cn/dvcp/activityList/edit-icon" alt=""/>填写活动日志
|
||||
</div>
|
||||
<div class="confirm-bg" v-if="info.logStatus == 2"
|
||||
@click="$linkTo(`./logDetail?id=${info.id}&title=${info.title}`)"><img
|
||||
src="https://cdn.cunwuyun.cn/dvcp/activityList/tips-icon" alt=""/>我的活动日志
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'detail',
|
||||
computed: {
|
||||
...mapState(['user', 'token']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewMore: false,
|
||||
id: '',
|
||||
info: {},
|
||||
partyId: '',
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.id = option.id
|
||||
if (this.user.partyId) {
|
||||
this.partyId = this.user.partyId
|
||||
} else {
|
||||
this.partyId = this.user.residentId
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.$dict.load('partyReportActionStatus').then((res) => {
|
||||
this.getDetail()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.$instance.post(`/app/apppartyreport/queryDetailById?id=${this.id}&partyId=${this.partyId}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.info = res.data
|
||||
this.info.beginTime = this.info.beginTime.substring(0, 16)
|
||||
this.info.endTime = this.info.endTime.substring(0, 16)
|
||||
this.info.stopSignupTime = this.info.stopSignupTime.substring(0, 16)
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.$instance.post(`/app/apppartyreport/signup-cancel?id=${this.id}&partyId=${this.partyId}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$toast('取消报名成功!')
|
||||
this.getDetail()
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.info.title,
|
||||
path: `/mods/AppActivityList/AppActivityList?id=${this.id}`,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import '../../common/common.scss';
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.header-info {
|
||||
background-color: #197df0;
|
||||
padding: 24px 32px 0;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
word-break: break-all;
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
line-height: 64px;
|
||||
letter-spacing: 2px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-bottom: 16px;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
// width:192px; // text-align: justify;
|
||||
// text-align-last:justify
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.view-btn {
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
padding: 52px 0 20px 0;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
margin-left: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.view-btn-active {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: #fff;
|
||||
padding-bottom: 112px;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
line-height: 96px;
|
||||
background: #fff;
|
||||
padding-left: 32px;
|
||||
box-sizing: border-box;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.html {
|
||||
padding: 16px 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-footer {
|
||||
display: flex;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
background-color: #fff;
|
||||
border-top: 2px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-right: 8px;
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-bg {
|
||||
background-color: #197df0;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
160
src/mods/AppActivityList/logDetail.vue
Normal file
160
src/mods/AppActivityList/logDetail.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="header-info">
|
||||
<p class="title">{{ title }}</p>
|
||||
<div class="info">
|
||||
<span class="label">提交时间:</span>
|
||||
<span class="value">{{ info.submitTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<p class="title"><span class="title-line"></span>活动总结</p>
|
||||
<div class="html" v-html="info.content"></div>
|
||||
</div>
|
||||
<div class="content" v-if="info.files.length">
|
||||
<p class="title"><span class="title-line"></span>活动照片</p>
|
||||
<div class="img-list">
|
||||
<img :src="item.accessUrl" alt="" v-for="(item, index) in info.files" :key="index"
|
||||
@click="$previewImage(info.files, index, 'accessUrl')"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'logDetail',
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
info: {},
|
||||
partyId: '',
|
||||
title: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
if (this.user.partyId) {
|
||||
this.partyId = this.user.partyId
|
||||
} else {
|
||||
this.partyId = this.user.residentId
|
||||
}
|
||||
this.id = option.id
|
||||
this.title = option.title
|
||||
this.getDetail()
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.$instance.post(`/app/apppartyreport/log-report?reportId=${this.id}&partyId=${this.partyId}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.info = res.data
|
||||
this.info.submitTime = this.info.submitTime.substring(0, 16)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import '../../common/common.scss';
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #f3f6f9;
|
||||
|
||||
.header-info {
|
||||
background-color: #197df0;
|
||||
padding: 24px 32px 48px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
word-break: break-all;
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
line-height: 64px;
|
||||
letter-spacing: 2px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-bottom: 16px;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
// width:192px; // text-align: justify;
|
||||
// text-align-last:justify
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #ffe8e8;
|
||||
}
|
||||
}
|
||||
|
||||
.view-btn {
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
padding: 52px 0 20px 0;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
margin-left: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.view-btn-active {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: #fff;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
line-height: 96px;
|
||||
background: #fff;
|
||||
padding-left: 32px;
|
||||
box-sizing: border-box;
|
||||
color: #666;
|
||||
|
||||
.title-line {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 32px;
|
||||
background: #D7261E;
|
||||
margin-right: 12px;
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
||||
|
||||
.html {
|
||||
padding: 16px 32px;
|
||||
}
|
||||
|
||||
.img-list {
|
||||
img {
|
||||
width: 686px;
|
||||
height: 384px;
|
||||
margin: 0 0 32px 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
119
src/mods/AppActivityList/userList.vue
Normal file
119
src/mods/AppActivityList/userList.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<p class="title">报名记录(已有<span>{{ list.length }}</span>人报名)</p>
|
||||
<div class="user-list">
|
||||
<div class="item" v-for="(item, index) in list" :key="index">
|
||||
<div class="left">
|
||||
<img :src="item.avatar" alt="">
|
||||
<span>{{ nameInit(item.partyName) }}</span>
|
||||
</div>
|
||||
<div class="time">{{ item.signupTime }}</div>
|
||||
</div>
|
||||
<AiEmpty v-if="!list.length" class="pad-t168"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "userList",
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
list: []
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.id = option.id
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.$instance.post(`/app/apppartyreport/signup-info?id=${this.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.list = res.data
|
||||
if (this.list.length) {
|
||||
this.list.map((item) => {
|
||||
if (!item.partyName && item.residentName) {
|
||||
item.partyName = item.residentName
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
nameInit(name) {
|
||||
if (!name) {
|
||||
return '-'
|
||||
}
|
||||
|
||||
var newStr;
|
||||
if (name.length === 2) {
|
||||
newStr = '*' + name.substr(1, 2)
|
||||
} else if (name.length > 2) {
|
||||
var char = '';
|
||||
for (var i = 0, len = name.length - 2; i < len; i++) {
|
||||
char += '*';
|
||||
}
|
||||
newStr = char + name.substr(name.length - 2, name.length);
|
||||
} else {
|
||||
newStr = name;
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
padding-top: 16px;
|
||||
|
||||
.title {
|
||||
line-height: 96px;
|
||||
background-color: #fff;
|
||||
padding-left: 32px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-bottom: 4px span {
|
||||
color: #D73D3D;
|
||||
}
|
||||
}
|
||||
|
||||
.user-list {
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 148px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 30px;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 8px 34px -8px rgba(213, 213, 213, 0.5);
|
||||
|
||||
.left {
|
||||
color: #2D2D2E;
|
||||
line-height: 46px;
|
||||
vertical-align: middle;
|
||||
|
||||
img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
color: #999;
|
||||
line-height: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
141
src/mods/AppAddressBook/AppAddressBook.vue
Normal file
141
src/mods/AppAddressBook/AppAddressBook.vue
Normal file
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="areaSelection">
|
||||
<div class="area">区域选择</div>
|
||||
<div class="select">
|
||||
<ai-area-picker ref="area" class="ai-area" :value="areaId" :name.sync="areaName" :areaId="$areaId"
|
||||
@select="areaSelect">
|
||||
<div class="ai-area__wrapper">
|
||||
<span class="label" v-if="areaName">{{ areaName }}</span>
|
||||
<span v-else>请选择</span>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</div>
|
||||
</ai-area-picker>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="list.length">
|
||||
<u-index-list :scrollTop="scrollTop" :index-list="indexList">
|
||||
<div v-for="(letter, index) in indexList" :key="index">
|
||||
<u-index-anchor :index="letter"/>
|
||||
<div class="item" hover-class="bg-hover" @click="phone(item)"
|
||||
v-for="(item, index) in list.filter(e=>e.nameInitials==letter)" :key="index">
|
||||
<label>{{ item.name }}</label>
|
||||
<div class="info">
|
||||
{{ item.type }}<span>{{ item.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</u-index-list>
|
||||
</template>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "AppAddressBook",
|
||||
appName: "便民通讯录",
|
||||
data() {
|
||||
return {
|
||||
scrollTop: 0,
|
||||
indexList: [],
|
||||
list: [],
|
||||
userInfo: {},
|
||||
areaId: '',
|
||||
$areaId: '',
|
||||
areaName: '',
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.userInfo = uni.getStorageSync("userInfo");
|
||||
this.areaId = this.$areaId
|
||||
this.areaName = this.$areaName
|
||||
this.getList();
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
|
||||
methods: {
|
||||
phone({phone: phoneNumber}) {
|
||||
uni.makePhoneCall({phoneNumber});
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post("/app/appconvenientaddressbook/list", null, {
|
||||
params: {
|
||||
isPublic: 1,
|
||||
resource: "portal",
|
||||
areaId: this.areaId,
|
||||
size: 999
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.indexList = [...new Set(res.data.records.map(e => e.nameInitials))];
|
||||
this.list = res.data.records;
|
||||
}
|
||||
})
|
||||
},
|
||||
areaSelect(v) {
|
||||
this.areaId = v
|
||||
this.isMore = false
|
||||
this.current = 0
|
||||
this.list = []
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop;
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.areaSelection {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 30px;
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
background-color: #FFFF;
|
||||
|
||||
.select {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
box-sizing: border-box;
|
||||
padding: 32px 48px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
|
||||
& > label {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26px;
|
||||
color: #999999;
|
||||
margin-top: 8px;
|
||||
|
||||
& > span {
|
||||
color: #333333;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
320
src/mods/AppAgProducts/AppAgProducts.vue
Normal file
320
src/mods/AppAgProducts/AppAgProducts.vue
Normal file
@@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="wrapper padding">
|
||||
<!-- <u-tabs :list="tabs" height="124" font-size="40" bg-color="#4181FF" inactive-color="rgba(255,255,255,0.75)"
|
||||
:bar-style="{backgroundColor:'#fff'}" :active-item-style="active"
|
||||
:is-scroll="true" :current="index" @change="onChange"></u-tabs> -->
|
||||
<div class="tabs">
|
||||
<u-tabs
|
||||
:list="tabs"
|
||||
font-size="36"
|
||||
bg-color="transparent"
|
||||
:bold="false"
|
||||
inactive-color="#ccddff"
|
||||
:is-scroll="true"
|
||||
:gutter="16"
|
||||
active-color="#fff"
|
||||
:current="index"
|
||||
@change="onChange">
|
||||
</u-tabs>
|
||||
</div>
|
||||
<header>
|
||||
<span @click="show=true">{{ !typeName ? '全部类型' : typeName }}
|
||||
<u-icon name="arrow-down" size="28" color="#333333" :custom-style="{marginLeft:'8px'}"></u-icon>
|
||||
</span>
|
||||
<div class="total">
|
||||
共<em>{{ total }}</em>个农产品
|
||||
</div>
|
||||
</header>
|
||||
<div class="card-list" v-if="list.length">
|
||||
<div class="card" v-for="(item,index) in list" :key="index" @click="toDetail(item)">
|
||||
<div class="top">
|
||||
<div class="title">{{ item.title }}
|
||||
</div>
|
||||
<div class="ag-content">{{ item.content }}
|
||||
</div>
|
||||
<div class="phone-wrap">
|
||||
<img class="img" :class="[item.files.length ==1 ? 'single' : '']" v-for="(photo,idx) in item.files"
|
||||
:key="idx" :src="photo.url" alt="" @click.stop="preview(item.files,idx)">
|
||||
</div>
|
||||
<div class="ag-info">
|
||||
<div class="tag">{{ $dict.getLabel('agriculturalType', item.type) }}</div>
|
||||
<div class="date">{{ item.createTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="phone" @click.stop="phone(item.phone)">
|
||||
<u-icon name="phone-fill" size="32" color="#4181FF"></u-icon>
|
||||
<span>{{ item.phone }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else/>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="suport" hover-class="text-hover">我要发布</div>
|
||||
</div>
|
||||
<u-select v-model="show" :list="$dict.getDict('agriculturalTypeSearch')" value-name="dictValue"
|
||||
label-name="dictName" @confirm="confirm"></u-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AppAgProducts",
|
||||
appName: "晒农产品",
|
||||
data() {
|
||||
return {
|
||||
index: 0,
|
||||
show: false,
|
||||
current: 1,
|
||||
type: "",
|
||||
typeName: "",
|
||||
list: [],
|
||||
total: 0,
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.$dict.load("agriculturalTypeSearch");
|
||||
},
|
||||
computed: {
|
||||
active() {
|
||||
return {
|
||||
fontSize: "22px",
|
||||
color: "#FFFFFF",
|
||||
};
|
||||
},
|
||||
tabs() {
|
||||
return [{
|
||||
name: '全部'
|
||||
}, {
|
||||
name: '我的发布'
|
||||
}]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
preview(photos, index) {
|
||||
this.$previewImage(photos, index, "url");
|
||||
},
|
||||
onChange(val) {
|
||||
this.index = val;
|
||||
this.current = 1;
|
||||
if (!!this.index) {
|
||||
this.getMine();
|
||||
} else this.getAll();
|
||||
},
|
||||
phone(phoneNumber) {
|
||||
uni.makePhoneCall({phoneNumber});
|
||||
},
|
||||
confirm(val) {
|
||||
this.type = val[0].value;
|
||||
this.typeName = val[0].label;
|
||||
this.current = 1;
|
||||
if (!!this.index) {
|
||||
this.getMine();
|
||||
} else this.getAll();
|
||||
},
|
||||
getAll() {
|
||||
this.$instance.post("/app/appshowagriculturalproduce/list", null, {
|
||||
params: {
|
||||
type: this.type,
|
||||
current: this.current,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
this.total = res.data.total;
|
||||
}
|
||||
})
|
||||
},
|
||||
getMine() {
|
||||
this.$instance.post("/app/appshowagriculturalproduce/listByWx", null, {
|
||||
params: {
|
||||
type: this.type,
|
||||
current: this.current,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
this.total = res.data.total;
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetail({id}) {
|
||||
uni.navigateTo({
|
||||
url: "./agDetail?id=" + id + "&type=" + this.index
|
||||
})
|
||||
},
|
||||
suport() {
|
||||
uni.navigateTo({
|
||||
url: "./agAdd"
|
||||
})
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.current = 1;
|
||||
if (!!this.index) {
|
||||
this.getMine();
|
||||
} else {
|
||||
this.getAll();
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
if (!!this.index) {
|
||||
this.getMine();
|
||||
} else {
|
||||
this.getAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.padding {
|
||||
padding-top: 100px;
|
||||
padding-bottom: 156px;
|
||||
|
||||
.tabs {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
padding: 10px 0 10px 16px;
|
||||
box-sizing: border-box;
|
||||
background: #4181FF;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 48px 32px 32px;
|
||||
|
||||
& > span {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.total {
|
||||
margin-left: auto;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
|
||||
.card {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px -1px 0px 0px #DDDDDD;
|
||||
border-radius: 16px 16px 0px 0px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.top {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 50px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ag-content {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 44px;
|
||||
margin-top: 8px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.phone-wrap {
|
||||
gap: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 24px;
|
||||
|
||||
.img {
|
||||
width: 203px;
|
||||
height: 204px;
|
||||
}
|
||||
|
||||
.single {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
.ag-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24px;
|
||||
|
||||
.tag {
|
||||
width: 88px;
|
||||
height: 48px;
|
||||
background: #EEEEEE;
|
||||
border-radius: 24px;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phone {
|
||||
height: 104px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
|
||||
& > img {
|
||||
width: 32px;
|
||||
height: 33px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #4181FF;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
192
src/mods/AppAgProducts/agAdd.vue
Normal file
192
src/mods/AppAgProducts/agAdd.vue
Normal file
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="card">
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>标题</label>
|
||||
</div>
|
||||
<u-input type="textarea" trim placeholder="请输入标题" maxlength="100"
|
||||
placeholder-style="color: #999999;font-size: 15px;" v-model="form.title"/>
|
||||
<div class="form" style="border-top: 1px solid #dddddd;">
|
||||
<em>*</em>
|
||||
<label>详细描述</label>
|
||||
</div>
|
||||
<u-input type="textarea" trim placeholder="请输入详细描述信息" maxlength="500"
|
||||
placeholder-style="color: #999999;font-size: 15px;" v-model="form.content"/>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>农产品类型</label>
|
||||
<div class="right" @click="show=true">
|
||||
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
|
||||
<span class="value" style="color: #999999;font-weight:normal;" v-if="!form.typeName">请选择</span>
|
||||
<span class="value" style="color: #333;font-weight:normal;" v-else>{{ form.typeName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="padding-bottom: 20px;">
|
||||
<div class="form">
|
||||
<label>图片上传
|
||||
<span>(最多9张)</span>
|
||||
</label>
|
||||
</div>
|
||||
<AiUploader :limit="9" v-model="form.files"></AiUploader>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="form border">
|
||||
<em>*</em>
|
||||
<label>联系人</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right"
|
||||
placeholder-style="color:#999;font-size: 17px;" v-model="form.contactPerson"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form border">
|
||||
<em>*</em>
|
||||
<label>联系方式</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right"
|
||||
placeholder-style="color:#999;font-size: 17px;" v-model="form.phone"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>地址</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right" style="flex: 1;margin-left: 16px;"
|
||||
placeholder-style="color:#999;font-size: 17px;" v-model="form.address"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="submit" hover-class="text-hover">提交</div>
|
||||
</div>
|
||||
<u-select v-model="show" :list="$dict.getDict('agriculturalType')" value-name="dictValue"
|
||||
label-name="dictName" @confirm="confirm"></u-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import AiUploader from '../../components/AiUploader/AiUploader'
|
||||
|
||||
export default {
|
||||
name: "agAdd",
|
||||
components: {AiUploader},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
form: {
|
||||
title: "",
|
||||
content: "",
|
||||
type: "",
|
||||
typeName: "",
|
||||
files: [],
|
||||
contactPerson: "",
|
||||
phone: "",
|
||||
address: "",
|
||||
},
|
||||
flag: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.$dict.load("agriculturalType");
|
||||
},
|
||||
|
||||
methods: {
|
||||
confirm(val) {
|
||||
this.form.type = val[0].value;
|
||||
this.form.typeName = val[0].label;
|
||||
},
|
||||
|
||||
submit() {
|
||||
if (!!!this.form.title) return this.$u.toast("请输入标题");
|
||||
if (!!!this.form.content) return this.$u.toast("请输入详细描述");
|
||||
if (!!!this.form.typeName) return this.$u.toast("请选择农产品类型");
|
||||
if (!!!this.form.contactPerson) return this.$u.toast("请输入联系人")
|
||||
if (!!!this.form.phone) return this.$u.toast("请输入联系方式");
|
||||
if (!!!this.form.address) return this.$u.toast("请输入地址");
|
||||
if (this.flag) return
|
||||
this.flag = true
|
||||
this.$loading()
|
||||
this.$instance.post("/app/appshowagriculturalproduce/addOrUpdate", {
|
||||
...this.form
|
||||
}).then(res => {
|
||||
this.$hideLoading()
|
||||
this.flag = false
|
||||
if (res.code == 0) {
|
||||
this.$u.toast("提交成功");
|
||||
setTimeout(_ => {
|
||||
uni.navigateBack();
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-bottom: 150px;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-sizing: border-box;
|
||||
padding-left: 32px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.form {
|
||||
height: 112px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
width: 16px;
|
||||
height: 44px;
|
||||
font-weight: 400;
|
||||
color: #FF4466;
|
||||
line-height: 54px;
|
||||
font-style: normal;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
& > label {
|
||||
font-size: 32px;
|
||||
font-weight: 500;
|
||||
color: #666666;
|
||||
|
||||
& > span {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
margin-right: 32px;
|
||||
|
||||
.value {
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.border {
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
200
src/mods/AppAgProducts/agDetail.vue
Normal file
200
src/mods/AppAgProducts/agDetail.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div class="wrapper padding">
|
||||
<div class="card">
|
||||
<header>{{ detail.title }}</header>
|
||||
<div class="date">{{ detail.createTime }}</div>
|
||||
<div class="detail-content">{{ detail.content }}
|
||||
</div>
|
||||
<div class="photo-title">图片</div>
|
||||
<div class="photo-wrap">
|
||||
<img :src="item.url" alt=""
|
||||
v-for="(item,index) in detail.files" :key="index" @click="preview(index)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="item">
|
||||
<div class="label">联系方式</div>
|
||||
<div class="value" @click="phone">
|
||||
<u-icon name="phone-fill" size="28" color="#4181FF" :custom-style="{marginRight:'6px'}"></u-icon>
|
||||
{{ detail.phone }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="label">地址</div>
|
||||
<div class="address">{{ detail.address }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-wrapper" v-if="type==1">
|
||||
<div class="btn" @click="unDo" hover-class="text-hover">撤销发布</div>
|
||||
</div>
|
||||
<!-- <div class="btn" @click="unDo" v-if="type==1">撤销发布</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "agDetail",
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
type: null,
|
||||
detail: {},
|
||||
}
|
||||
},
|
||||
onLoad(opt) {
|
||||
this.id = opt.id;
|
||||
this.type = opt.type;
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
preview(index) {
|
||||
this.$previewImage(this.detail.files, index, "url");
|
||||
},
|
||||
phone() {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.detail.phone
|
||||
})
|
||||
},
|
||||
unDo() {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否确定要撤销?",
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
this.$instance.post("/app/appshowagriculturalproduce/delete", null, {
|
||||
params: {ids: this.id}
|
||||
}).then(ret => {
|
||||
if (ret.code == 0) {
|
||||
this.$u.toast("撤销成功");
|
||||
setTimeout(_ => {
|
||||
uni.navigateBack();
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetail() {
|
||||
this.$instance.post("/app/appshowagriculturalproduce/queryDetailById", null, {
|
||||
params: {id: this.id}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.padding {
|
||||
padding-bottom: 156px;
|
||||
|
||||
.card {
|
||||
background-color: #FFFFFF;
|
||||
margin-bottom: 24px;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 32px;
|
||||
|
||||
header {
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 66px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 64px;
|
||||
margin-top: 64px;
|
||||
padding-bottom: 48px;
|
||||
}
|
||||
|
||||
.photo-title {
|
||||
height: 112px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.photo-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& > img {
|
||||
width: 225px;
|
||||
height: 225px;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #4181FF;
|
||||
}
|
||||
|
||||
.address {
|
||||
width: 480px;
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 44px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-wrapper {
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 686px;
|
||||
height: 88px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #FF4466;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
bottom: 32px;
|
||||
transform: translateX(-50%);
|
||||
color: #FF4466;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
232
src/mods/AppContent/AppContent.vue
Normal file
232
src/mods/AppContent/AppContent.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<div class="wrapper" :style="{ paddingTop: categorys.length ? '54px' : '10px' }" v-if="pageShow">
|
||||
<div class="tabs">
|
||||
<u-tabs
|
||||
:list="categorys && categorys.map(e=>({name:e.categoryName}))"
|
||||
font-size="36"
|
||||
bg-color="transparent"
|
||||
:bold="false"
|
||||
inactive-color="#ccddff"
|
||||
:is-scroll="true"
|
||||
:gutter="16"
|
||||
active-color="#fff"
|
||||
:current="index"
|
||||
@change="tabChange">
|
||||
</u-tabs>
|
||||
</div>
|
||||
<div class="list-wrap" v-if="categoryList && categoryList.length">
|
||||
<div class="list-card" hover-class="bg-hover" v-for="(category,index) in categoryList" :key="index"
|
||||
@click="$linkTo('./contentDetail?id='+category.id)">
|
||||
<div class="header">{{ category.title }}</div>
|
||||
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length == 1">
|
||||
<img class="img" :src="item.url" v-for="(item,index) in category.files" :key="index.id" alt="">
|
||||
</div>
|
||||
<div class="content-wrap" v-if="category.contentType==0 && category.files && category.files.length > 1">
|
||||
<img class="min-img" :src="item.url" v-for="(item,index) in category.files && category.files.slice(0,3)"
|
||||
:key="index.id" alt="">
|
||||
</div>
|
||||
<div class="content-wrap" v-if="category.contentType==1">
|
||||
<img class="img" :src="category.pictureUrl" alt="">
|
||||
<img class="play-icon" src="../../static/img/play.png" alt="">
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="left">
|
||||
<div class="tag">{{ category.categoryName || names }}</div>
|
||||
{{ category.createTime }}
|
||||
</div>
|
||||
<div class="right">
|
||||
<em>{{ category.viewCount }}</em>
|
||||
人看过
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AppContent",
|
||||
appName: "内容管理",
|
||||
data() {
|
||||
return {
|
||||
index: 0,
|
||||
names: "",
|
||||
moduleId: "",
|
||||
categoryId: "",
|
||||
categorys: [],
|
||||
categoryList: [],
|
||||
pageShow: false,
|
||||
areaId: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.$loading()
|
||||
this.names = option.names;
|
||||
this.areaId = option.areaId
|
||||
this.getName();
|
||||
if (option.names) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: option.names
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
active() {
|
||||
return {
|
||||
fontSize: "22px",
|
||||
color: "#fff",
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getName() {
|
||||
this.$instance.post("/app/appcontentmoduleinfo/listByName", null, {
|
||||
params: {names: this.names}
|
||||
}).then(res => {
|
||||
if (res.data && res.data.length) {
|
||||
this.categorys = res.data[0]["categoryList"];
|
||||
this.moduleId = res.data[0]["id"];
|
||||
if (res.data[0]["categoryList"]?.length) {
|
||||
this.categoryId = res.data[0]["categoryList"][0]["id"];
|
||||
}
|
||||
this.getCategoryList();
|
||||
} else {
|
||||
this.$hideLoading()
|
||||
}
|
||||
})
|
||||
},
|
||||
tabChange(e) {
|
||||
this.index = e
|
||||
this.$nextTick(() => {
|
||||
this.getCategoryList(this.categorys[e]["id"]);
|
||||
})
|
||||
},
|
||||
getCategoryList(e) {
|
||||
this.$instance.post("/app/appcontentinfo/list", null, {
|
||||
params: {
|
||||
moduleId: this.moduleId,
|
||||
categoryId: e ? e : (this.categoryId ? this.categoryId : ''),
|
||||
size: 10,
|
||||
areaId: this.areaId ? this.areaId : ''
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.categoryList = this.current > 1 ? [...this.categoryList, ...res.data.records] : res.data.records;
|
||||
}
|
||||
|
||||
this.pageShow = true
|
||||
this.$hideLoading()
|
||||
})
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
this.getCategoryList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-top: 100px;
|
||||
|
||||
.list-wrap {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
|
||||
.list-card {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.header {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 50px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 24px;
|
||||
position: relative;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.min-img {
|
||||
width: 204px;
|
||||
height: 204px;
|
||||
}
|
||||
|
||||
.play-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
|
||||
.tag {
|
||||
width: 144px;
|
||||
height: 48px;
|
||||
background: #EEEEEE;
|
||||
border-radius: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
em {
|
||||
font-style: normal;
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
52
src/mods/AppContent/contentDetail.vue
Normal file
52
src/mods/AppContent/contentDetail.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<section class="contentDetail">
|
||||
<ai-detail :detail="detail" :props="props"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiDetail from "../../components/AiDetail/AiDetail";
|
||||
|
||||
export default {
|
||||
name: "contentDetail",
|
||||
components: {AiDetail},
|
||||
data() {
|
||||
return {
|
||||
detail: {title: "内容详情"},
|
||||
props: {
|
||||
count: "viewCount"
|
||||
},
|
||||
id: "",
|
||||
}
|
||||
},
|
||||
onLoad({id}) {
|
||||
if (id) {
|
||||
this.id = id;
|
||||
this.getDetail(id);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail(id) {
|
||||
this.$instance.post(`/app/appcontentinfo/queryDetailById`, null, {
|
||||
params: {id}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: detail.title,
|
||||
path: '/mods/AppContent/contentDetail?id=' + this.id
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.contentDetail {
|
||||
}
|
||||
</style>
|
||||
104
src/mods/AppContent/contentManager.vue
Normal file
104
src/mods/AppContent/contentManager.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<section class="AppContentManager">
|
||||
<ai-news-list :list="list" :loadmore="loadmore" @select="showDetail">
|
||||
<template #header>
|
||||
<div class="search-wrap">
|
||||
<div class="search">
|
||||
<u-icon name="search" color="rgba(255,255,255,0.5)" size="40"></u-icon>
|
||||
<input placeholder="请输入需要搜索的内容" class="desc" placeholder-style="color:rgba(255,255,255,0.5);"
|
||||
confirm-type="search" @change="onChange"></input>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ai-news-list>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import AiNewsList from "../../components/AiNewsList/AiNewsList";
|
||||
|
||||
export default {
|
||||
name: "contentManager",
|
||||
components: {AiNewsList},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
loadmore() {
|
||||
return this.pages <= this.current ? 'loading ' : 'nomore'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
current: 1,
|
||||
pages: 0,
|
||||
name: "",
|
||||
}
|
||||
},
|
||||
onLoad(params) {
|
||||
if (params.moduleId) {
|
||||
this.moduleId = params.moduleId
|
||||
this.getData(params.moduleId)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(val) {
|
||||
this.current = 1;
|
||||
this.getData(val.detail.value);
|
||||
},
|
||||
getData(title = "") {
|
||||
let {current, search} = this
|
||||
this.moduleId && this.$instance.post("/app/appcontentinfo/list", null, {
|
||||
params: {moduleId: this.moduleId, current, size: 10, title}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = current > 1 ? [...this.list, ...res.data.records] : res.data.records
|
||||
this.pages = res.data.pages
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSelectArea(e) {
|
||||
this.search.areaId = e.id
|
||||
this.getData()
|
||||
},
|
||||
showDetail(row) {
|
||||
uni.navigateTo({url: `./contentDetail?id=${row.id}`})
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
this.getData()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .search-wrap {
|
||||
width: 750px;
|
||||
height: 112px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #4181FF;
|
||||
|
||||
.search {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
border-radius: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.desc {
|
||||
flex: 1;
|
||||
font-size: 28px;
|
||||
color: #FFFFFF;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
424
src/mods/AppCreditPoints/AppCreditPoints.vue
Normal file
424
src/mods/AppCreditPoints/AppCreditPoints.vue
Normal file
@@ -0,0 +1,424 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="credit-points">
|
||||
<div class="fixed-top">
|
||||
<div class="header-tab" style="background-color:#197DF0;">
|
||||
<div class="tab-item" v-for="(item, index) in tabList" :key="index" @click="tabClick(index)">{{ item }}<span
|
||||
class="active-line" v-if="tabIndex == index"></span></div>
|
||||
</div>
|
||||
<div class="bg-blue"></div>
|
||||
<div class="header-content">
|
||||
<div class="item">
|
||||
<div class="num color-5AAD6A">{{ tabIndex == 0 ? info['家庭积分'] || '0' : Number(info['个人积分']) || '0' }}</div>
|
||||
<div class="label">{{ tabIndex == 0 ? '家庭' : '个人' }}总分</div>
|
||||
</div>
|
||||
<div class="item" v-if="tabIndex != 1">
|
||||
<div class="num color-4185F5">{{ tabIndex == 0 ? info['剩余总分'] || '0' : info['个人积分'] || '0' }}</div>
|
||||
<div class="label">剩余总分</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="num color-CD413A">{{ tabIndex == 0 ? info['家庭排行'] || '0' : info['个人排行'] || '0' }}</div>
|
||||
<div class="label">{{ tabIndex == 0 ? '家庭' : '个人' }}排名</div>
|
||||
</div>
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/credit/head.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!showDetail" style="padding-top:432rpx;">
|
||||
<div class="ranking-content" v-if="info['列表'] && info['列表'].length">
|
||||
<div class="item" v-if="info['列表'].length > 1">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/credit/2.png" alt="" class="top-img">
|
||||
<img :src="info['列表'][1].photo" alt="" class="user-img mar-b4" v-if="info['列表'][1].photo">
|
||||
<div class="user-name-bg mar-b4" v-else>{{ $formatName(info['列表'][1].name) }}</div>
|
||||
<p class="user-name mar-b8">{{ info['列表'][1].name }}{{ tabIndex == 0 ? '家' : '' }}</p>
|
||||
<p class="item-num">{{ info['列表'][1].integral }}</p>
|
||||
</div>
|
||||
<div class="item-top item" v-if="info['列表'].length > 0">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/credit/1.png" alt="" class="top-img-one">
|
||||
<img :src="info['列表'][0].photo" alt="" class="user-img mar-b4" v-if="info['列表'][0].photo">
|
||||
<div class="user-name-bg mar-b4" v-else>{{ $formatName(info['列表'][0].name) }}</div>
|
||||
<p class="user-name mar-b8">{{ info['列表'][0].name }}{{ tabIndex == 0 ? '家' : '' }}</p>
|
||||
<p class="item-num">{{ info['列表'][0].integral }}</p>
|
||||
</div>
|
||||
<div class="item" v-if="info['列表'].length > 2">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/credit/3.png" alt="" class="top-img">
|
||||
<img :src="info['列表'][2].photo" alt="" class="user-img mar-b4" v-if="info['列表'][2].photo">
|
||||
<div class="user-name-bg mar-b4" v-else>{{ $formatName(info['列表'][2].name) }}</div>
|
||||
<p class="user-name mar-b8">{{ info['列表'][2].name }}{{ tabIndex == 0 ? '家' : '' }}</p>
|
||||
<p class="item-num">{{ info['列表'][2].integral }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ranking-list" v-if="info['列表'] && info['列表'].length">
|
||||
<div class="item" v-for="(item, index) in info['列表']" :key="index" v-if="index > 2">
|
||||
<span class="item-num">{{ index + 1 }}</span>
|
||||
<img :src="item.photo" alt="" class="user-img mar-b4" v-if="item.photo">
|
||||
<div class="user-name-bg mar-b4 mar-r24" v-else>{{ $formatName(item.name) }}</div>
|
||||
<span class="item-name">{{ item.name }}{{ tabIndex == 0 ? '家' : '' }}</span>
|
||||
<span class="item-point">{{ item.integral }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-content" v-if="showDetail && list.length">
|
||||
<div class="title">积分明细</div>
|
||||
<div class="item" v-for="(item, index) in list" :key="index">
|
||||
<div class="item-info">
|
||||
<p>{{ tabIndex == 0 ? item.residentName + ':' : '' }}{{ item.description }}</p>
|
||||
<span> {{ item.doTime }}</span>
|
||||
</div>
|
||||
<div class="item-num" :class="'color-'+ (item.changeIntegral >= 0 ? 0 : 1)">
|
||||
{{ item.changeIntegral > 0 ? '+' + item.changeIntegral : item.changeIntegral }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "AppCreditPoints",
|
||||
appName: "信用积分",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabList: ['家庭积分', '个人积分'],
|
||||
tabIndex: 0,
|
||||
showDetail: false, //是否显示积分明细
|
||||
info: {},
|
||||
current: 1,
|
||||
list: [],
|
||||
areaId: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (uni.getStorageSync('areaId')) {
|
||||
this.areaId = uni.getStorageSync('areaId')
|
||||
} else {
|
||||
this.areaId = this.$areaId
|
||||
}
|
||||
if (options.type == 'detail') {
|
||||
this.showDetail = true
|
||||
this.getList()
|
||||
}
|
||||
uni.setNavigationBarTitle({
|
||||
title: options.title
|
||||
})
|
||||
this.getInfo()
|
||||
},
|
||||
methods: {
|
||||
tabClick(index) {
|
||||
this.tabIndex = index
|
||||
this.getInfo()
|
||||
this.getList()
|
||||
},
|
||||
// 积分排行
|
||||
getInfo() {
|
||||
this.info = {}
|
||||
// var url = `/app/appresident/rank?id=00255e188d1225f3fe022cb4eed44a84&type=${this.tabIndex}` //积分排行
|
||||
var url = `/app/appresident/rank?id=${this.user.residentId}&type=${this.tabIndex}&areaId=${this.areaId}` //积分排行
|
||||
this.$instance.post(url).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 积分明细列表
|
||||
getList() {
|
||||
// var url = `/app/appvillagerintegraldetail/IntegralList?residentId=00255e188d1225f3fe022cb4eed44a84&type=${this.tabIndex}¤t=${this.current}&size=10` //积分明细
|
||||
var url = `/app/appvillagerintegraldetail/IntegralList?residentId=${this.user.residentId}&type=${this.tabIndex}¤t=${this.current}&size=10` //积分明细
|
||||
this.$instance.post(url).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.current > res.data.pages) {
|
||||
return
|
||||
}
|
||||
const records = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
this.list = records
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
if (!this.showDetail) return
|
||||
this.current = this.current + 1;
|
||||
this.getList()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #f3f6f9;
|
||||
|
||||
.credit-points {
|
||||
.bg-blue {
|
||||
width: 100%;
|
||||
height: 176px;
|
||||
background-color: #197DF0;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
width: 690px;
|
||||
height: 256px;
|
||||
background: #FFF;
|
||||
border-radius: 16px;
|
||||
margin: -130px 0 40px 30px;
|
||||
padding: 100px 60px 40px 60px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
z-index: 99;
|
||||
|
||||
.num {
|
||||
font-family: DIN;
|
||||
font-size: 52px;
|
||||
font-weight: bold;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #999;
|
||||
line-height: 40px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.color-5AAD6A {
|
||||
color: #5AAD6A;
|
||||
}
|
||||
|
||||
.color-4185F5 {
|
||||
color: #4185F5;
|
||||
}
|
||||
|
||||
.color-CD413A {
|
||||
color: #CD413A;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
width: 360px;
|
||||
height: 250px;
|
||||
top: -40px;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ranking-content {
|
||||
padding: 94px 30px 0;
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
width: 216px;
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.12);
|
||||
border-radius: 12px;
|
||||
padding: 40px 0 76px 0;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.user-name {
|
||||
font-size: 30px;
|
||||
font-family: PingFang-SC-Medium, PingFang-SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.item-num {
|
||||
font-size: 46px;
|
||||
font-weight: 6000;
|
||||
color: #2C51CE;
|
||||
line-height: 54px;
|
||||
}
|
||||
|
||||
.top-img {
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.item-top {
|
||||
margin: -46px 20px 0;
|
||||
|
||||
.user-img {
|
||||
width: 104px;
|
||||
height: 104px;
|
||||
}
|
||||
|
||||
.user-name-bg {
|
||||
width: 104px;
|
||||
height: 104px;
|
||||
border-radius: 50%;
|
||||
background-color: #4E8EEE;
|
||||
font-size: 28px;
|
||||
line-height: 104px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.top-img-one {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: -22px;
|
||||
left: 0;
|
||||
height: 46px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ranking-list {
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
background: #FFF;
|
||||
padding: 0 64px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.item-num {
|
||||
display: inline-block;
|
||||
width: 68px;
|
||||
color: #858594;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.user-img {
|
||||
margin-right: 24px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
color: #333;
|
||||
font-size: 30px;
|
||||
display: inline-block;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.item-point {
|
||||
display: inline-block;
|
||||
width: 210px;
|
||||
text-align: right;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.mar-r24 {
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-name-bg {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
background-color: #4E8EEE;
|
||||
font-size: 28px;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mar-b4 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
width: 690px;
|
||||
background: #FFF;
|
||||
border-radius: 16px;
|
||||
margin: 432px 0 0 32px;
|
||||
padding: 30px 30px 94px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.title {
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 34px 0 32px 0;
|
||||
border-bottom: 2px solid #ddd;
|
||||
display: flex;
|
||||
|
||||
.item-info {
|
||||
width: 500px;
|
||||
|
||||
p {
|
||||
word-break: break-all;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-num {
|
||||
width: calc(100% - 500px);
|
||||
text-align: right;
|
||||
font-size: 36px;
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
line-height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.color-0 {
|
||||
color: #2C51CE !important;
|
||||
}
|
||||
|
||||
.color-1 {
|
||||
color: #E6736E !important;
|
||||
}
|
||||
|
||||
.fixed-top {
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
70
src/mods/AppCreditPoints/result.vue
Normal file
70
src/mods/AppCreditPoints/result.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="service-result">
|
||||
<image :src="type === '0' ? '/static/img/service-success.png' : '/static/img/error.png'"/>
|
||||
<h2>{{ type === '1' ? '领取失败!请联系管理员处理' : '提交成功!' }}</h2>
|
||||
<div class="text" v-if="type === '0'">请等待信用好超市管理员与您联系</div>
|
||||
<div class="service-btn" hover-class="text-hover" @click="back">确定</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
type: '0'
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.type = query.type
|
||||
},
|
||||
|
||||
methods: {
|
||||
back() {
|
||||
uni.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.service-result {
|
||||
min-height: 100vh;
|
||||
padding-top: 96px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
|
||||
.service-btn {
|
||||
width: 558px;
|
||||
height: 88px;
|
||||
line-height: 88px;
|
||||
margin: 64px auto 0;
|
||||
text-align: center;
|
||||
background: #197DF0;
|
||||
font-size: 36px;
|
||||
color: #fff;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 8px;
|
||||
color: #333333;
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 32px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
243
src/mods/AppCreditPoints/submitOrder.vue
Normal file
243
src/mods/AppCreditPoints/submitOrder.vue
Normal file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<div class="order">
|
||||
<div class="order-info">
|
||||
<h2>{{ userName }}家</h2>
|
||||
<span>剩余积分:{{ familyIntegral }}分</span>
|
||||
</div>
|
||||
<image class="line" src="/static/img/line.png"/>
|
||||
<div class="order-list">
|
||||
<div class="order-item" v-for="(item, index) in goods" :key="index">
|
||||
<image :src="item.photo[0].url"/>
|
||||
<div class="order-item__right flex1">
|
||||
<h2>{{ item.merchandiseName }}</h2>
|
||||
<div class="order-item__right--info">
|
||||
<span>{{ item.costIntegral }}</span>
|
||||
<i>积分</i>
|
||||
</div>
|
||||
<div class="item-bottom">
|
||||
<div></div>
|
||||
<div class="item-bottom__right">
|
||||
<span>x {{ item.num }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-footer">
|
||||
<div class="goods-footer__bottom">
|
||||
<div class="goods-footer__bottom__left">
|
||||
<h3>共{{ total }}件商品</h3>
|
||||
<div class="goods-footer__bottom--middle">
|
||||
<span>合计 :</span>
|
||||
<i>{{ money }}</i>
|
||||
<em>积分</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-footer__bottom--btn" @click="submit" hover-class="text-hover">确认提交</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
total: 0,
|
||||
money: 0,
|
||||
goods: [],
|
||||
memberId: '',
|
||||
userName: '',
|
||||
familyId: '',
|
||||
familyIntegral: 0
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.userName = query.userName
|
||||
this.total = query.total
|
||||
this.familyIntegral = query.familyIntegral
|
||||
this.money = query.money
|
||||
this.memberId = query.memberId
|
||||
this.familyId = query.familyId
|
||||
this.goods = JSON.parse(query.goods)
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
this.$loading()
|
||||
this.$instance.post(`/app/appvillagerintegralshoporder/createOrderForWx`, {
|
||||
memberId: this.memberId,
|
||||
familyId: this.familyId,
|
||||
orderIntegral: this.money,
|
||||
shopId: this.goods[0].shopId,
|
||||
merchandiseList: this.goods.map(item => {
|
||||
return {
|
||||
merchandiseId: item.id,
|
||||
merchandiseNumber: item.num
|
||||
}
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.$emit('update')
|
||||
this.$linkTo('./result?type=0')
|
||||
} else {
|
||||
this.$linkTo('./result?type=1')
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order {
|
||||
min-height: 100%;
|
||||
background: #fff;
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
display: flex;
|
||||
padding: 28px 30px 44px;
|
||||
|
||||
.order-item__right--info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
margin-right: 8px;
|
||||
color: #FA4A51;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #FA4A51;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 30px;
|
||||
color: #333333;
|
||||
font-size: 30px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
& > image {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-list {
|
||||
margin-top: 20px;
|
||||
padding-bottom: 110px;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 128px;
|
||||
padding: 030px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.goods-footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
box-shadow: 0px -1px 4px 0px rgba(214, 214, 214, 0.5);
|
||||
background: #fff;
|
||||
|
||||
.goods-footer__bottom--btn {
|
||||
width: 212px;
|
||||
height: 104px;
|
||||
line-height: 104px;
|
||||
font-size: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #197DF0;
|
||||
}
|
||||
|
||||
.goods-footer__bottom__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
padding: 032px h3 {
|
||||
color: #F94246;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.goods-footer__bottom--middle {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
color: #F94246;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
i {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
margin-right: 6px;
|
||||
color: #FA444B;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
em {
|
||||
color: #F94246;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-footer__bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 104px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 28px;
|
||||
|
||||
.item-bottom__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 90px;
|
||||
height: 60px;
|
||||
padding: 020px;
|
||||
margin: 010px;
|
||||
background: #F6F6F6;
|
||||
border-radius: 10px;
|
||||
font-size: 26px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
450
src/mods/AppCreditPoints/supermarket.vue
Normal file
450
src/mods/AppCreditPoints/supermarket.vue
Normal file
@@ -0,0 +1,450 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="supermarket">
|
||||
<div class="fixed-top title" @click="$linkTo(`./system?areaName=${areaName}`)"
|
||||
v-if="propAreaId == '341021104000'">{{ areaName }}信用好超市管理制度,点击查看 >>
|
||||
</div>
|
||||
<div class="goods-list" v-if="numList.length"
|
||||
:style="propAreaId == '341021104000' ? 'padding-top:80px' : 'padding-top: 0;'">
|
||||
<div class="left">
|
||||
<div
|
||||
:class="numIndex == index ? 'item active' : 'item'"
|
||||
v-for="(item, index) in numList"
|
||||
:key="index"
|
||||
@click="numClick(index)">
|
||||
<i v-show="item.total > 0">{{ item.total }}</i>
|
||||
{{ item.type }}分区
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="item" v-for="(item, index) in goodsList[numIndex]" :key="index">
|
||||
<img :src="item.photo[0].url" alt="">
|
||||
<div class="item-info">
|
||||
<p class="item-name">{{ item.merchandiseName }}</p>
|
||||
<div class="item-point"><span class="num">{{ item.costIntegral }}</span>积分</div>
|
||||
<div class="item-bottom">
|
||||
<div></div>
|
||||
<div class="item-bottom__right">
|
||||
<image v-show="item.num > 0" @click="cut(numIndex, index)" src="/static/img/cut.png"/>
|
||||
<input v-show="item.num > 0" v-model="item.num">
|
||||
<image src="/static/img/add.png" @click="add(numIndex, index)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else/>
|
||||
<div class="goods-footer" v-if="numList.length">
|
||||
<div class="goods-footer__top">
|
||||
<h2>{{ userInfo.familyName || user.nickName }}{{ userInfo.familyName ? '家' : '' }}</h2>
|
||||
<span>剩余积分:{{ userInfo.familyIntegral || 0 }}分</span>
|
||||
</div>
|
||||
<div class="goods-footer__bottom">
|
||||
<div class="goods-footer__bottom__left">
|
||||
<h3>共{{ total }}件商品</h3>
|
||||
<div class="goods-footer__bottom--middle">
|
||||
<span>合计 :</span>
|
||||
<i>{{ money }}</i>
|
||||
<em>积分</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-footer__bottom--btn" @click="toOrder" hover-class="text-hover">去结算</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'supermarket',
|
||||
|
||||
data() {
|
||||
return {
|
||||
numList: [],
|
||||
numIndex: 0,
|
||||
goodsList: [],
|
||||
areaId: '',
|
||||
userInfo: {},
|
||||
areaName: '',
|
||||
propAreaId: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['global', 'user', 'token']),
|
||||
|
||||
total() {
|
||||
let total = 0
|
||||
if (!this.numList.length) {
|
||||
return total
|
||||
}
|
||||
|
||||
this.numList.forEach(item => {
|
||||
total = item.total + total
|
||||
})
|
||||
|
||||
return total
|
||||
},
|
||||
|
||||
money() {
|
||||
let money = 0
|
||||
if (!this.goodsList.length) {
|
||||
return money
|
||||
}
|
||||
|
||||
this.goodsList.forEach(arr => {
|
||||
arr.forEach(item => {
|
||||
money = money + Number(item.num) * item.costIntegral
|
||||
})
|
||||
})
|
||||
|
||||
return money
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.propAreaId = this.$areaId
|
||||
uni.$on('update', () => {
|
||||
this.getInfo()
|
||||
})
|
||||
|
||||
if (uni.getStorageSync('areaId')) {
|
||||
this.areaId = uni.getStorageSync('areaId')
|
||||
}
|
||||
this.getUserInfo()
|
||||
this.getInfo()
|
||||
},
|
||||
onShow() {
|
||||
this.getUserInfo()
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
this.$instance.post(`/admin/area/queryAreaByAreaid?id=${this.areaId}`, null, {}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (res.data) {
|
||||
this.areaName = res.data.name
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getUserInfo() {
|
||||
this.$instance.post(`/app/appresident/queryFamilyById?id=${this.user.residentId}`, null, {}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.userInfo = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toOrder() {
|
||||
if (this.user.status == 0) {
|
||||
if (!this.user.phone) {
|
||||
return this.$linkTo('/pages/phone/bingPhoneNumber?from=auth')
|
||||
} else {
|
||||
return this.$linkTo('/pages/auth/authenticationInfo')
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.total) {
|
||||
return this.$toast('请选择商品')
|
||||
}
|
||||
|
||||
if (this.money > this.userInfo.familyIntegral) {
|
||||
return this.$toast('积分不足')
|
||||
}
|
||||
|
||||
let goods = []
|
||||
|
||||
this.goodsList.forEach(arr => {
|
||||
arr.forEach(item => {
|
||||
if (item.num) {
|
||||
goods.push(item)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
this.$linkTo(`./submitOrder?familyId=${this.userInfo.familyId}&userName=${this.userInfo.familyName}&memberId=${this.userInfo.memberId}&goods=${JSON.stringify(goods)}&total=${this.total}&money=${this.money}&familyIntegral=${this.userInfo.familyIntegral}`)
|
||||
},
|
||||
|
||||
getList() {
|
||||
this.$instance.post(`/app/appvillagerintegralmerchandise/listByIntegral?areaId=${this.areaId}`, null, {}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (res.data) {
|
||||
this.numList = Object.keys(res.data).map(item => {
|
||||
return {
|
||||
type: item,
|
||||
total: 0
|
||||
}
|
||||
})
|
||||
this.goodsList = Object.values(res.data).map((item) => {
|
||||
item.map((items) => {
|
||||
items.num = 0
|
||||
items.photo = JSON.parse(items.photo)
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
return item
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
add(index, i) {
|
||||
this.$set(this.goodsList[index][i], 'num', Number(this.goodsList[index][i].num) + 1)
|
||||
|
||||
let total = 0
|
||||
this.goodsList[index].forEach(item => {
|
||||
total = total + item.num
|
||||
})
|
||||
|
||||
this.$set(this.numList[index], 'total', total)
|
||||
},
|
||||
|
||||
cut(index, i) {
|
||||
this.$set(this.goodsList[index][i], 'num', Number(this.goodsList[index][i].num) - 1)
|
||||
|
||||
let total = 0
|
||||
this.goodsList[index].forEach(item => {
|
||||
total = total + item.num
|
||||
})
|
||||
|
||||
this.$set(this.numList[index], 'total', total)
|
||||
},
|
||||
|
||||
numClick(index) {
|
||||
this.numIndex = index
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.item-bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 28px;
|
||||
|
||||
.item-bottom__right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 90px;
|
||||
height: 60px;
|
||||
padding: 020px;
|
||||
margin: 010px;
|
||||
background: #F6F6F6;
|
||||
border-radius: 10px;
|
||||
font-size: 26px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 111;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
|
||||
.goods-footer__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 80px;
|
||||
padding: 030px;
|
||||
background: #EFF4FF;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.goods-footer__bottom--btn {
|
||||
width: 212px;
|
||||
height: 104px;
|
||||
line-height: 104px;
|
||||
font-size: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background: #197DF0;
|
||||
}
|
||||
|
||||
.goods-footer__bottom__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
padding: 032px h3 {
|
||||
color: #F94246;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.goods-footer__bottom--middle {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
color: #F94246;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
i {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
margin-right: 12px;
|
||||
color: #FA444B;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
em {
|
||||
color: #F94246;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-footer__bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 104px;
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.supermarket {
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
background: #EFF4FF;
|
||||
padding-left: 30px;
|
||||
color: #3A7EE2;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
// padding-top:80px; padding-bottom: 184px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-y: hidden;
|
||||
|
||||
.left {
|
||||
width: 168px;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
float: left;
|
||||
background: #FAF9FB;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 104px;
|
||||
line-height: 1.1;
|
||||
border-bottom: 2px solid #D8E5FF;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
border-left: 6px solid #FAF9FB;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 012px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
border-radius: 13px;
|
||||
background: #FB4E44;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
border-left: 6px solid #1D58FE;
|
||||
background: linear-gradient(270deg, #FFFFFF 0%, #FFFFFF 77%, #E7EAFA 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
float: left;
|
||||
width: calc(100% - 168px);
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
padding: 28px 30px 44px;
|
||||
box-sizing: border-box;
|
||||
|
||||
img {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
border: 2px solid #D7D5D5;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
display: inline-block;
|
||||
width: 276px;
|
||||
padding-left: 30px;
|
||||
vertical-align: top;
|
||||
|
||||
.item-name {
|
||||
width: 100%;
|
||||
word-break: break-all;
|
||||
line-height: 42px;
|
||||
margin-bottom: 30px;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.item-point {
|
||||
color: #FA4A51;;
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FA4A51;
|
||||
line-height: 34px;
|
||||
|
||||
.num {
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
76
src/mods/AppCreditPoints/system.vue
Normal file
76
src/mods/AppCreditPoints/system.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="system">
|
||||
<div class="title">信用好超市管理制度</div>
|
||||
<p class="mini-title underline">为规范信用好超市管理流程,保证信用好超市正常运行,结合{{ areaName }}实际,特制定本制度。</p>
|
||||
<p class="text">1、每月15日、30日各开放1次,时间分别为<span class="underline">上午9:00-11:00;下午14:30-16:30。</span></p>
|
||||
<p class="text">2、信用好超市每月清点兑换物品,及时补充兑换货物,确保货物充足,品类丰富。</p>
|
||||
<p class="text">3、本超市管理人员应严格按照信用券兑换标准执行兑换并及时记录信用户的积分兑换记录。</p>
|
||||
<p class="text">4、超市开放时间段管理员必须在岗在位,热情开展兑换服务,确保公平公正,严禁态度蛮横、弄虚作假。</p>
|
||||
<p class="text">5、信用户凭借信用券根据自己的实际需要,在本超市内自主选择所需的物品,并由管理员登记确认。</p>
|
||||
<p class="text">6、信用好超市内环境卫生干净整洁,超市内禁止吸烟等其他不文明行为。</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "my",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
areaName: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.areaName = options.areaName
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.system {
|
||||
padding: 030px;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.mini-title {
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #222;
|
||||
line-height: 48px;
|
||||
margin-bottom: 32px;
|
||||
width: 100%;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 100%;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #333;
|
||||
line-height: 40px;
|
||||
margin-bottom: 20px;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
118
src/mods/AppHometown/AppHometown.vue
Normal file
118
src/mods/AppHometown/AppHometown.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<template v-if="detail">
|
||||
<header>{{ detail.areaName }}</header>
|
||||
<div class="address">{{ detail.address }}</div>
|
||||
<div class="desc">
|
||||
<u-parse :html="detail.content"></u-parse>
|
||||
</div>
|
||||
</template>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
<div class="btn" @click="cancel" v-if="detail">
|
||||
<div>解除入驻</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AppHometown",
|
||||
appName: "我的家乡",
|
||||
data() {
|
||||
return {
|
||||
detail: null,
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"])
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
if (!this.user.homeArea) return
|
||||
this.$instance.post("/app/appcountrysidetourism/queryDetailByAreaIdForWX", null, {
|
||||
params: {areaId: this.user.homeArea}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data;
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.$instance.post("/app/appwechatuser/unbindHome", {id: this.user.id}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast('解除入驻成功')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
position: relative;
|
||||
|
||||
header {
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 66px;
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 42px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 36px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 64px;
|
||||
margin-top: 64px;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
padding-bottom: 16px;
|
||||
z-index: 999;
|
||||
transform: translateX(-50%);
|
||||
|
||||
div {
|
||||
width: 686px;
|
||||
height: 88px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #FF4466;
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
color: #FF4466;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
352
src/mods/AppJob/AppJob.vue
Normal file
352
src/mods/AppJob/AppJob.vue
Normal file
@@ -0,0 +1,352 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="search-wrap">
|
||||
<div class="left" @click="show=true">
|
||||
<span>{{ search.typeName ? search.typeName : "全部" }}</span>
|
||||
<u-icon name="arrow-down" color="#ffffff" size="20"></u-icon>
|
||||
</div>
|
||||
<div class="right">
|
||||
<u-icon name="search" size="32" color="rgba(255,255,255,0.5)" :custom-style="{marginRight:'8px'}"></u-icon>
|
||||
<input placeholder="请输入需要搜索的内容" style="flex: 1;color:#fff;" confirm-type="search"
|
||||
placeholder-style="color:rgba(255,255,255,0.5)" v-model="search.title"
|
||||
@confirm="current=1;getList()"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="job-list" v-if="list.length">
|
||||
<header>
|
||||
<span>招工就业列表</span>
|
||||
<div class="right">
|
||||
共<em>{{ total }}</em>个职位
|
||||
</div>
|
||||
</header>
|
||||
<div class="card" v-for="(item,index) in list" :key="index">
|
||||
<template v-if="item.type == 1">
|
||||
<div class="top" @click="toDetail(0,item)">
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div class="job-content">{{ item.remark || "" }}</div>
|
||||
<div class="photo">
|
||||
<img
|
||||
:src="photo.url"
|
||||
alt="" v-for="photo in item.files" :key="photo.id">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="tag">个人求职</div>
|
||||
<div class="date">{{ item.createTime && item.createTime.slice(0, 16) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<span class="name">{{ item.linkName }}</span>
|
||||
<div class="right" @click="phone(item)">
|
||||
<u-icon name="phone-fill" size="36" color="#4181FF" :custom-style="{marginRight:'8px'}"></u-icon>
|
||||
{{ item.linkPhone }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="item.type == 0">
|
||||
<div class="top" @click="toDetail(1,item)">
|
||||
<div class="post-info">
|
||||
<div class="post">{{ item.title }}</div>
|
||||
<div class="salary">{{ item.salary }}</div>
|
||||
</div>
|
||||
<div class="require">{{ item.remark || "" }}</div>
|
||||
<div class="info">
|
||||
<div class="tag" style="background-color:#1AAAFF">企业招工</div>
|
||||
<div class="date">{{ item.createTime && item.createTime.slice(0, 16) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="company">{{ item.companyName }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="$linkTo('./pubJob')" hover-class="text-hover">我要找工作</div>
|
||||
</div>
|
||||
<u-select v-model="show" :list="selectList" @confirm="onConfirm"></u-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppJob",
|
||||
appName: "招工就业",
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
current: 1,
|
||||
list: [],
|
||||
total: 0,
|
||||
search: {
|
||||
title: "",
|
||||
type: "",
|
||||
typeName: "",
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectList() {
|
||||
return [{
|
||||
value: '',
|
||||
label: '全部'
|
||||
}, {
|
||||
value: '0',
|
||||
label: '企业招工'
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '个人求职'
|
||||
}];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
preview(index) {
|
||||
this.$previewImage(this.list, index, "url");
|
||||
},
|
||||
phone({linkPhone: phoneNumber}) {
|
||||
uni.makePhoneCall({phoneNumber});
|
||||
},
|
||||
onConfirm(val) {
|
||||
this.search.typeName = val[0].label;
|
||||
this.search.type = val[0].value;
|
||||
this.current = 1;
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post("/app/appjob/list", null, {
|
||||
params: {
|
||||
...this.search,
|
||||
current: this.current
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
this.total = res.data.total;
|
||||
}
|
||||
})
|
||||
},
|
||||
toDetail(val, {id}) {
|
||||
uni.navigateTo({
|
||||
url: !!val ? `./compJob?id=${id}` : `./persJob?id=${id}`
|
||||
})
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.current = 1;
|
||||
this.getList();
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-top: 124px;
|
||||
}
|
||||
|
||||
.search-wrap {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 124px;
|
||||
background: #4181FF;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > span {
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
height: 64px;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
border-radius: 32px;
|
||||
margin-left: 32px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.job-list {
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px 156px;
|
||||
|
||||
& > header {
|
||||
box-sizing: border-box;
|
||||
padding: 48px 0 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
& > span {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.top {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 50px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.job-content {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 44px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.photo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
|
||||
& > img {
|
||||
width: 204px;
|
||||
height: 204px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24px;
|
||||
|
||||
.tag {
|
||||
width: 144px;
|
||||
height: 48px;
|
||||
background: #42D784;
|
||||
border-radius: 24px;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.post-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.post {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.salary {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #FF3521;
|
||||
}
|
||||
}
|
||||
|
||||
.require {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
height: 104px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
|
||||
.name {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #4181FF;
|
||||
}
|
||||
|
||||
.company {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
150
src/mods/AppJob/compJob.vue
Normal file
150
src/mods/AppJob/compJob.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="card">
|
||||
<div class="post-info">
|
||||
<div class="post-name">
|
||||
<span>{{ detail.title }}</span>
|
||||
<span>{{ detail.salary }}</span>
|
||||
</div>
|
||||
<p>{{ detail.education }} | {{ detail.gender }} | {{ detail.age }}岁</p>
|
||||
</div>
|
||||
<div class="form">
|
||||
<div class="label">招聘企业</div>
|
||||
<div class="value">{{ detail.companyName }}</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<div class="label">招聘联系人</div>
|
||||
<div class="value">{{ detail.linkName }}</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<div class="label">联系方式</div>
|
||||
<div class="value phone" @click="phone">
|
||||
<u-icon name="phone-fill" color="#4181FF" size="32" :custom-stype="{marginRight:'8px'}"></u-icon>
|
||||
{{ detail.linkPhone }}
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="detail.remark">
|
||||
<header>岗位要求</header>
|
||||
<div class="post-require">{{ detail.remark }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "compJob",
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
detail: {},
|
||||
}
|
||||
},
|
||||
onLoad({id}) {
|
||||
this.id = id;
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
phone() {
|
||||
uni.makePhoneCall({phoneNumber: this.detail.linkPhone});
|
||||
},
|
||||
getDetail() {
|
||||
this.$instance.post("/app/appjob/detail", null, {
|
||||
params: {id: this.id}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: "企业招工",
|
||||
path: "/mods/AppJob/compJob?id=" + this.id
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card {
|
||||
padding: 32px 0 32px 32px;
|
||||
background-color: #ffffff;
|
||||
|
||||
.post-info {
|
||||
padding-right: 32px;
|
||||
|
||||
.post-name {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
line-height: 56px;
|
||||
|
||||
& > span:first-child {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
& > span:last-child {
|
||||
font-size: 36px;
|
||||
font-weight: 600;
|
||||
color: #FF3521;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > p {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin: 16px 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
height: 112px;
|
||||
background: #FFFFFF;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
padding-right: 32px;
|
||||
|
||||
.label {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 28px;
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
padding: 32px 0;
|
||||
}
|
||||
|
||||
.post-require {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 56px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
155
src/mods/AppJob/persJob.vue
Normal file
155
src/mods/AppJob/persJob.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="padding">
|
||||
<div class="card">
|
||||
<div class="post-info">{{ detail.title }}
|
||||
</div>
|
||||
<div class="date">{{ detail.createTime }}</div>
|
||||
<div class="form border">
|
||||
<div class="label">求职联系人</div>
|
||||
<div class="value">{{ detail.linkName }}</div>
|
||||
</div>
|
||||
<div class="form border">
|
||||
<div class="label">联系方式</div>
|
||||
<div class="value phone" @click="phone">
|
||||
<u-icon name="phone-fill" color="#4181FF" size="32" :custom-stype="{marginRight:'8px'}"></u-icon>
|
||||
{{ detail.linkPhone }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<div class="label">图片</div>
|
||||
</div>
|
||||
<div class="photo border">
|
||||
<img :src="item.url" alt=""
|
||||
v-for="(item,index) in detail.files" :key="index" @click="preview(index)">
|
||||
</div>
|
||||
<header>详细描述</header>
|
||||
<div class="post-require">{{ detail.remark }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "persJob",
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
detail: {},
|
||||
}
|
||||
},
|
||||
onLoad({id}) {
|
||||
this.id = id;
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
preview(index) {
|
||||
this.$previewImage(this.detail.files, index, "url");
|
||||
},
|
||||
phone() {
|
||||
uni.makePhoneCall({phoneNumber: this.detail.linkPhone});
|
||||
},
|
||||
getDetail() {
|
||||
this.$instance.post("/app/appjob/detail", null, {
|
||||
params: {id: this.id}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data;
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: "个人求职",
|
||||
path: "/mods/AppJob/persJob?id=" + this.id
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.padding {
|
||||
min-height: 100%;
|
||||
background-color: #ffffff;
|
||||
|
||||
.card {
|
||||
padding: 32px 0 32px 32px;
|
||||
background-color: #ffffff;
|
||||
|
||||
.post-info {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 56px;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
margin: 16px 0 32px;
|
||||
}
|
||||
|
||||
.form {
|
||||
height: 112px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-right: 32px;
|
||||
|
||||
.label {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 28px;
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
|
||||
.border {
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.photo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
padding-bottom: 48px;
|
||||
|
||||
& > img {
|
||||
width: 225px;
|
||||
height: 225px;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
padding: 32px 0;
|
||||
}
|
||||
|
||||
.post-require {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
line-height: 56px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
159
src/mods/AppJob/pubJob.vue
Normal file
159
src/mods/AppJob/pubJob.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="card">
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>标题</label>
|
||||
</div>
|
||||
<u-input type="textarea" trim placeholder="请输入标题" maxlength="100" v-model="form.title"
|
||||
placeholder-style="color: #999999;font-size: 17px;font-weight:normal;"
|
||||
:custom-style="{color:'#333',fontSize:'17px',paddingLeft:'12px'}"/>
|
||||
<div class="form border-top">
|
||||
<em>*</em>
|
||||
<label>详细描述</label>
|
||||
</div>
|
||||
<u-input type="textarea" trim placeholder="请输入详细描述信息…" maxlength="500" v-model="form.remark"
|
||||
placeholder-style="color: #999999;font-size: 17px;font-weight:normal;"
|
||||
:custom-style="{color:'#333',fontSize:'17px',paddingLeft:'12px'}"/>
|
||||
</div>
|
||||
<div class="card" style="padding-bottom: 20px">
|
||||
<div class="form">
|
||||
<label>图片上传
|
||||
<span>(最多9张)</span>
|
||||
</label>
|
||||
</div>
|
||||
<AiUploader :limit="9" v-model="form.files"></AiUploader>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form border">
|
||||
<em>*</em>
|
||||
<label>联系人</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right"
|
||||
placeholder-style="color:#999;font-size: 17px;font-weight:normal;" v-model="form.linkName"
|
||||
:custom-style="{fontWeight:600,color:'#333',fontSize:'17px'}"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>联系方式</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right"
|
||||
placeholder-style="color:#999;font-size: 17px;font-weight:normal;" v-model="form.linkPhone"
|
||||
:custom-style="{fontWeight:600,color:'#333',fontSize:'17px'}"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="submit" hover-class="text-hover">提交</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import AiUploader from '../../components/AiUploader/AiUploader'
|
||||
|
||||
export default {
|
||||
name: "pubJob",
|
||||
components: {AiUploader},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
title: "",
|
||||
remark: "",
|
||||
files: [],
|
||||
linkName: "",
|
||||
linkPhone: "",
|
||||
type: 1,
|
||||
},
|
||||
flag: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
if (!!!this.form.title) return this.$u.toast("请输入标题");
|
||||
if (!!!this.form.remark) return this.$u.toast("请输入详细描述");
|
||||
if (!!!this.form.linkName) return this.$u.toast("请输入联系人");
|
||||
if (!!!this.form.linkPhone) return this.$u.toast("请输入联系方式");
|
||||
if (this.flag) return
|
||||
this.flag = true
|
||||
this.$loading()
|
||||
this.$instance.post("/app/appjob/addOrUpdate", {
|
||||
...this.form
|
||||
}).then(res => {
|
||||
this.$hideLoading()
|
||||
this.flag = false
|
||||
if (res.code == 0) {
|
||||
this.$u.toast("提交成功");
|
||||
setTimeout(_ => {
|
||||
uni.navigateBack();
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-bottom: 150px;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-sizing: border-box;
|
||||
padding-left: 32px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.form {
|
||||
height: 112px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
width: 16px;
|
||||
height: 44px;
|
||||
font-weight: 400;
|
||||
color: #FF4466;
|
||||
line-height: 54px;
|
||||
font-style: normal;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
& > label {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #666666;
|
||||
|
||||
& > span {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
margin-right: 32px;
|
||||
|
||||
.value {
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.border {
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
216
src/mods/AppMarFuneral/AppMarFuneral.vue
Normal file
216
src/mods/AppMarFuneral/AppMarFuneral.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div class="wrapper padding" v-if="pageShow">
|
||||
<template v-if="list.length">
|
||||
<header>
|
||||
<span>婚丧嫁娶列表</span>
|
||||
<div class="total">
|
||||
共<em>{{ list.length }}</em>条
|
||||
</div>
|
||||
</header>
|
||||
<div class="card" v-for="item in list" :key="item.id">
|
||||
<div class="item">
|
||||
<span class="label">事主姓名</span>
|
||||
<span class="value">{{ item.name }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">联系方式</span>
|
||||
<span class="value">{{ item.phone }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">上报时间</span>
|
||||
<span class="value">{{ item.createTime }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">上报地点</span>
|
||||
<span class="value">{{ item.address }}</span>
|
||||
</div>
|
||||
<div class="item" v-if="item.content.trim().length">
|
||||
<span class="label">上报内容</span>
|
||||
<span class="value">{{ item.content || '' }}</span>
|
||||
</div>
|
||||
<div class="tag" :style="{backgroundColor:$dict.getColor('marriageType',item.type)}">
|
||||
{{ $dict.getLabel('marriageType', item.type) }}
|
||||
</div>
|
||||
<u-icon name="more-dot-fill" size="28" color="#999999" :custom-style="customStyle" @click="handleDel(item)"
|
||||
v-if="item.openId == userInfo.openId"></u-icon>
|
||||
</div>
|
||||
</template>
|
||||
<AiEmpty v-else/>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="suport" hover-class="text-hover">我要上报</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppMarFuneral",
|
||||
appName: "婚丧嫁娶",
|
||||
data() {
|
||||
return {
|
||||
current: 1,
|
||||
pageShow: false,
|
||||
list: [],
|
||||
userInfo: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
customStyle() {
|
||||
return {
|
||||
position: "absolute",
|
||||
top: "16px",
|
||||
right: "24px",
|
||||
transform: "rotate(90deg)"
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.$loading()
|
||||
this.userInfo = uni.getStorageSync("userInfo");
|
||||
|
||||
this.$dict.load("marriageType").then(() => {
|
||||
this.getList()
|
||||
})
|
||||
|
||||
uni.$on('update', () => {
|
||||
this.current = 1
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleDel({id}) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否确定要删除?",
|
||||
success: ret => {
|
||||
if (ret.confirm) {
|
||||
this.$instance.post("/app/appmarriagefuneralinfo/delete", null, {
|
||||
params: {ids: id}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$u.toast("删除成功");
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post("/app/appmarriagefuneralinfo/list", null, {
|
||||
params: {
|
||||
current: this.current,
|
||||
size: 10,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
}
|
||||
|
||||
this.$hideLoading()
|
||||
}).catch(() => {
|
||||
this.$hideLoading()
|
||||
})
|
||||
},
|
||||
suport() {
|
||||
uni.navigateTo({
|
||||
url: "./marAdd"
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.padding {
|
||||
box-sizing: border-box;
|
||||
padding: 48px 32px 156px;
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 44px;
|
||||
|
||||
& > span {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.total {
|
||||
margin-left: auto;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
min-height: 308px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.label {
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
flex-shrink: 0;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
margin-left: 32px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
width: 70px;
|
||||
height: 44px;
|
||||
background: #FF883C;
|
||||
border-radius: 8px;
|
||||
font-size: 26px;
|
||||
line-height: 40px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
175
src/mods/AppMarFuneral/marAdd.vue
Normal file
175
src/mods/AppMarFuneral/marAdd.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="card">
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>类型</label>
|
||||
<div class="right" @click="show=true">
|
||||
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
|
||||
<span class="value" style="color: #999999;font-weight:normal;" v-if="!form.typeName">请选择</span>
|
||||
<span class="value" style="color: #333333;font-weight:normal;" v-else>{{ form.typeName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form border">
|
||||
<em>*</em>
|
||||
<label>事主姓名</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right" v-model="form.name"
|
||||
placeholder-style="color:#999;font-size: 16px;"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form border">
|
||||
<em>*</em>
|
||||
<label>联系方式</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right" v-model="form.phone"
|
||||
placeholder-style="color:#999;font-size: 16px;"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form">
|
||||
<em>*</em>
|
||||
<label>活动地点</label>
|
||||
<div class="right">
|
||||
<u-input trim placeholder="请输入" input-align="right" v-model="form.address"
|
||||
placeholder-style="color:#999;font-size: 16px;" style="flex: 1;margin-left: 16px;"></u-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="form">
|
||||
<em></em>
|
||||
<label>详细描述</label>
|
||||
</div>
|
||||
<u-input type="textarea" trim v-model="form.content" placeholder="请输入详细描述信息…" maxlength="500"
|
||||
placeholder-style="color: #999999;font-size: 15px;"/>
|
||||
</div>
|
||||
<div class="card" style="padding-bottom: 20px">
|
||||
<div class="form">
|
||||
<label>图片上传
|
||||
<span>(最多9张)</span>
|
||||
</label>
|
||||
</div>
|
||||
<AiUploader :limit="9" v-model="form.files"></AiUploader>
|
||||
</div>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" @click="submit" hover-class="text-hover">提交</div>
|
||||
</div>
|
||||
<u-select v-model="show" :list="$dict.getDict('marriageType')" value-name="dictValue"
|
||||
label-name="dictName" @confirm="confirm"></u-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AiUploader from '../../components/AiUploader/AiUploader'
|
||||
|
||||
export default {
|
||||
name: "marAdd",
|
||||
components: {AiUploader},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
type: "",
|
||||
typeName: "",
|
||||
name: "",
|
||||
phone: "",
|
||||
address: "",
|
||||
content: "",
|
||||
personType: 0,
|
||||
files: [],
|
||||
},
|
||||
show: false,
|
||||
flag: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
if (!!!this.form.typeName) return this.$u.toast("请选择类型");
|
||||
if (!!!this.form.name) return this.$u.toast("请输入事主姓名");
|
||||
if (!!!this.form.phone) return this.$u.toast("请输入联系方式");
|
||||
if (!!!this.form.address) return this.$u.toast("请输入活动地点");
|
||||
if (this.flag) return
|
||||
this.flag = true
|
||||
this.$loading()
|
||||
this.$instance.post("/app/appmarriagefuneralinfo/addOrUpdate", {
|
||||
...this.form
|
||||
}).then(res => {
|
||||
this.$hideLoading()
|
||||
this.flag = false
|
||||
if (res.code == 0) {
|
||||
uni.$emit('update')
|
||||
this.$u.toast("提交成功");
|
||||
setTimeout(_ => {
|
||||
uni.navigateBack();
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
},
|
||||
confirm(val) {
|
||||
this.form.type = val[0].value;
|
||||
this.form.typeName = val[0].label;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-bottom: 156px;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-sizing: border-box;
|
||||
padding-left: 32px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.form {
|
||||
height: 112px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
width: 16px;
|
||||
height: 44px;
|
||||
font-weight: 400;
|
||||
color: #FF4466;
|
||||
line-height: 54px;
|
||||
font-style: normal;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
& > label {
|
||||
font-size: 32px;
|
||||
font-weight: 500;
|
||||
color: #666666;
|
||||
|
||||
& > span {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row-reverse;
|
||||
margin-right: 32px;
|
||||
|
||||
.value {
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.border {
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
110
src/mods/AppNotice/AppNotice.vue
Normal file
110
src/mods/AppNotice/AppNotice.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="padding" v-if="pageShow">
|
||||
<header>{{ detail.title }}</header>
|
||||
<div class="info">
|
||||
<span>{{ detail.publishUnitName }} {{ detail.createTime && detail.createTime.slice(0, 16) }}</span>
|
||||
<div class="right">
|
||||
<em>{{ detail.views }}</em>人看过
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-content">
|
||||
<u-parse :html="detail.content"/>
|
||||
</div>
|
||||
<div class="photo">
|
||||
<img :src="item.url" alt="" v-for="(item,index) in images" :key="index" @click="preview(index)">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppNotice",
|
||||
appName:"通知公告",
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
pageShow: false,
|
||||
detail: {},
|
||||
images: [],
|
||||
}
|
||||
},
|
||||
onLoad({id}) {
|
||||
this.$loading()
|
||||
this.id = id;
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
preview(index) {
|
||||
this.$previewImage(this.images, index, 'path');
|
||||
},
|
||||
getDetail() {
|
||||
this.$instance.post("/app/appmininotice/queryDetailById", null, {
|
||||
params: {id: this.id}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data;
|
||||
this.images = JSON.parse(res.data.images || '[]');
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
}
|
||||
|
||||
this.$hideLoading()
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.padding {
|
||||
min-height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 32px;
|
||||
background-color: #fff;
|
||||
|
||||
header {
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
line-height: 66px;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
padding: 16px 0 64px;
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16px;
|
||||
|
||||
& > em {
|
||||
font-style: normal;
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notice-content {
|
||||
font-size: 28px;
|
||||
// color: #333;
|
||||
// line-height: 64px;
|
||||
}
|
||||
|
||||
.photo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
& > img {
|
||||
width: 100%;
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
210
src/mods/AppOrderList/AppOrderList.vue
Normal file
210
src/mods/AppOrderList/AppOrderList.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div class="order">
|
||||
<div class="order-item" v-for="(item, index) in list" :key="index" hover-class="text-hover"
|
||||
@click="$linkTo('./orderInfo?id=' + item.id)">
|
||||
<div class="order-item__imgs">
|
||||
<scroll-view scroll-x>
|
||||
<image v-for="(goods, index) in item.merchandiseList" :key="index"
|
||||
:src="JSON.parse(goods.merchandisePhoto)[0].url"/>
|
||||
</scroll-view>
|
||||
<div class="order-item__imgs--right">
|
||||
<div class="top">
|
||||
<span>{{ item.orderIntegral }}</span>
|
||||
<i>积分</i>
|
||||
</div>
|
||||
<p>共{{ item.total }}件</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-item__footer">
|
||||
<span :style="{color: $dict.getColor('integralOrderStatus', item.orderStatus)}">{{
|
||||
$dict.getLabel('integralOrderStatus', item.orderStatus)
|
||||
}}</span>
|
||||
<div class="order-item__footer--btn" v-if="item.orderStatus === '0'" @click.stop="cancel(item.id)">取消订单</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="!list.length"/>
|
||||
<!-- <div class="loading" style="margin-top:20px">
|
||||
<u-loadmore :status="loadingStatus" />
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppOrderList",
|
||||
appName: "超市订单",
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
current: 0,
|
||||
loadingStatus: 'loadmore'
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.$dict.load(['integralOrderStatus']).then(() => {
|
||||
this.getList()
|
||||
})
|
||||
uni.$on('update', () => {
|
||||
this.reset()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
reset() {
|
||||
this.loadingStatus = 'loadmore'
|
||||
this.current = 0
|
||||
this.$loading()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
cancel(id) {
|
||||
this.$loading()
|
||||
this.$instance.post(`/app/appvillagerintegralshoporder/overOrderForWx?orderId=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast('取消成功')
|
||||
this.reset()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getTotal(arr) {
|
||||
let total = 0
|
||||
arr.forEach(item => {
|
||||
total = total + item.merchandiseNumber
|
||||
})
|
||||
|
||||
return total
|
||||
},
|
||||
|
||||
getList() {
|
||||
if (this.loadingStatus === 'loading' || this.loadingStatus === 'nomore') return
|
||||
|
||||
this.loadingStatus = 'loading'
|
||||
this.$instance.post(`/app/appvillagerintegralshoporder/listForWx?current=${this.current + 1}&size=10`).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.current === 0) {
|
||||
this.list = []
|
||||
}
|
||||
|
||||
const data = res.data.records.map(item => {
|
||||
item.total = this.getTotal(item.merchandiseList)
|
||||
|
||||
return item
|
||||
})
|
||||
this.list.push(...data)
|
||||
this.current = this.current + 1
|
||||
this.loadingStatus = 'loadmore'
|
||||
if (!res.data.records.length || res.data.records.length < 10) {
|
||||
this.loadingStatus = 'nomore'
|
||||
}
|
||||
} else {
|
||||
this.loadingStatus = 'loadmore'
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loadingStatus = 'loadmore'
|
||||
})
|
||||
},
|
||||
|
||||
toDetail(id) {
|
||||
this.$linkTo(`./newsDetail?id=${id}&areaId=${this.areaId}`)
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.getList(this.areaId)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order {
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
width: 686px;
|
||||
margin: 0px auto32px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
|
||||
.order-item__imgs--right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: 144px;
|
||||
height: 160px;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
color: #4185F5;
|
||||
font-size: 40px i {
|
||||
padding-left: 4px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #ADADAD;
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-item__footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 112px;
|
||||
padding: 024px span {
|
||||
color: #3078E1;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.order-item__footer--btn {
|
||||
width: 160px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
font-size: 26px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 32px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
}
|
||||
|
||||
.order-item__imgs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
height: 208px;
|
||||
padding: 0 0 024px;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
scroll-view {
|
||||
flex: 1;
|
||||
height: 160px;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
image {
|
||||
flex-shrink: 1;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin-right: 10px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DDDDDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
234
src/mods/AppOrderList/orderInfo.vue
Normal file
234
src/mods/AppOrderList/orderInfo.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<div class="order" v-if="pageShow">
|
||||
<h2>订单{{ $dict.getLabel('integralOrderStatus', info.orderStatus) }}</h2>
|
||||
<p>{{ info.createTime }}</p>
|
||||
<div class="order-info">
|
||||
<div class="order-top">
|
||||
<div class="goods-item" v-for="(item, index) in info.merchandiseList" :key="index">
|
||||
<image :src="JSON.parse(item.merchandisePhoto)[0].url"/>
|
||||
<div class="goods-item__middle">
|
||||
<h2>{{ item.merchandiseName }}</h2>
|
||||
<p>{{ item.merchandiseNumber }}件</p>
|
||||
</div>
|
||||
<div class="goods-item__right">
|
||||
<span>{{ item.costIntegral * item.merchandiseNumber }}</span>
|
||||
<i>积分</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-bottom">
|
||||
<div class="order-bottom__top">
|
||||
<div class="left">
|
||||
<span>总数量 </span>
|
||||
<i>{{ total }}</i>
|
||||
<span>件</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<span>共消耗</span>
|
||||
<i>{{ info.orderIntegral }}</i>
|
||||
<em>积分</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-bottom__bottom" v-if="info.orderStatus === '0'">
|
||||
<div></div>
|
||||
<span @click="cancel">取消订单</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
info: {},
|
||||
id: '',
|
||||
total: 0,
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.id = query.id
|
||||
this.getInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo() {
|
||||
this.$loading()
|
||||
this.$instance.post(`/app/appvillagerintegralshoporder/queryDetailByIdForWx?id=${this.id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
this.total = this.getTotal(res.data.merchandiseList)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getTotal(arr) {
|
||||
let total = 0
|
||||
arr.forEach(item => {
|
||||
total = total + item.merchandiseNumber
|
||||
})
|
||||
|
||||
return total
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.$loading()
|
||||
this.$instance.post(`/app/appvillagerintegralshoporder/overOrderForWx?orderId=${this.id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast('取消成功')
|
||||
uni.$emit('update')
|
||||
this.getInfo()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order {
|
||||
padding: 48px 32px;
|
||||
|
||||
& > h2 {
|
||||
margin-bottom: 8px;
|
||||
color: #333333;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.order-bottom {
|
||||
.order-bottom__bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 120px span {
|
||||
width: 160px;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
color: #666666;
|
||||
font-size: 26px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 32px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
}
|
||||
|
||||
.order-bottom__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 120px;
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
padding: 08px;
|
||||
color: #FA4A51;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
em {
|
||||
color: #FA4A51;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
span {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 04px;
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
margin-top: 48px;
|
||||
padding: 24px 24px 0;
|
||||
background: #fff;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
|
||||
.order-top {
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.goods-item__right {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
span {
|
||||
margin-right: 4px;
|
||||
color: #4185F5;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
i {
|
||||
color: #4185F5;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-item__middle {
|
||||
flex: 1;
|
||||
|
||||
h2 {
|
||||
line-height: 1.3;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 20px;
|
||||
color: #ADADAD;
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin-right: 24px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #DDDDDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
236
src/mods/AppPlease/AppPlease.vue
Normal file
236
src/mods/AppPlease/AppPlease.vue
Normal file
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="fixed-top">
|
||||
<div class="header-search">
|
||||
<div class="search-input-content">
|
||||
<img src="https://cdn.cunwuyun.cn/img/search-blue.svg" alt="" class="search-icon">
|
||||
<input type="text" placeholder="请输入标题" class="search-input" placeholder-style="color:#E2E8F1;"
|
||||
v-model="inputValue" @confirm="getList" confirm-type="search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-select">
|
||||
<div class="select-item" @click="leaveMessageTypeShow = true">
|
||||
<span>{{ typeName || '提问类型' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
<div class="select-item" @click="timeSelectShow = true">
|
||||
<span>{{ searchTime || '提问时间' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="please-list">
|
||||
<div class="item" v-for="(item, index) in messageList" :key="index" @click="toDetail(item.id)">
|
||||
<p class="item-title"><span class="item-type"
|
||||
:class="'color-'+item.type">{{
|
||||
$dict.getLabel('leaveMessageType', item.type)
|
||||
}}</span>{{ item.title }}
|
||||
</p>
|
||||
<div>
|
||||
<span>提问人:{{ item.leaveName }}</span>
|
||||
<span>{{ ittem.createTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="!messageList.length"/>
|
||||
</div>
|
||||
<div class="fixed-bottom bottom-btn">
|
||||
<div @click="$linkTo('./questionList')">提问记录</div>
|
||||
<div class="btn-active" @click="$linkTo('./add')">我要提问</div>
|
||||
</div>
|
||||
<u-select v-model="leaveMessageTypeShow" :list="leaveMessageTypeList" @confirm="confirmMessageType"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<u-picker v-model="timeSelectShow" mode="time" :params="params" :start-year="startDate" :end-year="endDate"
|
||||
:default-selector="defaultDate"
|
||||
confirm-color="#07c160" @confirm="timeSelectConfirm"></u-picker>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "AppPlease",
|
||||
appName:"随心问",
|
||||
computed: {
|
||||
...mapState(['user', 'token']),
|
||||
startDate() {
|
||||
return this.getDate('start')
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate('end')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true
|
||||
})
|
||||
return {
|
||||
inputValue: '',
|
||||
timeSelectShow: false,
|
||||
params: {
|
||||
year: true,
|
||||
month: true,
|
||||
day: false,
|
||||
hour: false,
|
||||
minute: false,
|
||||
second: false,
|
||||
},
|
||||
startYear: '',
|
||||
endYear: '',
|
||||
defaultDate: [],
|
||||
searchTime: '',
|
||||
leaveMessageTypeShow: false,
|
||||
leaveMessageTypeList: [],
|
||||
type: '',
|
||||
typeName: '',
|
||||
messageList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.$dict.load('leaveMessageType').then((res) => {
|
||||
this.$nextTick(() => {
|
||||
this.$dict.getDict('leaveMessageType').map(i => {
|
||||
var item = {
|
||||
label: i.dictName,
|
||||
value: i.dictValue
|
||||
}
|
||||
this.leaveMessageTypeList.push(item)
|
||||
})
|
||||
})
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
var searchParams = {
|
||||
createTime: this.searchTime ? this.searchTime + '-' + "01" + ' ' + '00' + ":" + "00" + ":" + "00" : '',
|
||||
title: this.inputValue,
|
||||
type: this.type,
|
||||
userType: 0,//小程序用户
|
||||
}
|
||||
this.$instance.post(`/app/appleavemessage/listForWx`, searchParams).then(res => {
|
||||
if (res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
// var reg = new RegExp('(?<=.).', 'g')
|
||||
// item.leaveName = item.leaveName.replace(reg, '*')
|
||||
if (item.leaveName) {
|
||||
item.leaveName = item.leaveName.substring(0, 1) + '**'
|
||||
}
|
||||
|
||||
})
|
||||
this.messageList = res.data.records
|
||||
}
|
||||
})
|
||||
},
|
||||
timeSelectConfirm(e) {
|
||||
this.searchTime = e.year + '-' + e.month
|
||||
this.getList()
|
||||
},
|
||||
confirmMessageType(e) {
|
||||
this.typeName = e[0].label
|
||||
this.type = e[0].value
|
||||
this.getList()
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
if (type === 'start') {
|
||||
year = year - 10;
|
||||
} else if (type === 'end') {
|
||||
year = year;
|
||||
}
|
||||
return `${year}`;
|
||||
},
|
||||
toDetail(id) {
|
||||
this.$linkTo(`./detail?id=${id}`)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.please-list {
|
||||
padding: 240px 32px 144px;
|
||||
|
||||
.item {
|
||||
width: 686px;
|
||||
background: #FFF;
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 32px;
|
||||
|
||||
.item-title {
|
||||
word-break: break-all;
|
||||
line-height: 44px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.item-type {
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 4px;
|
||||
font-size: 26px;
|
||||
line-height: 36px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
height: 112px;
|
||||
line-height: 110px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
font-size: 36px;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-top: 2px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-active {
|
||||
background-color: #1365DD;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.color-0 {
|
||||
background: #FFEBEF;
|
||||
color: #F46;
|
||||
}
|
||||
|
||||
.color-1 {
|
||||
background: #E8EFFF;
|
||||
color: #26f;
|
||||
}
|
||||
|
||||
.color-2 {
|
||||
background: #E8EFFF;
|
||||
color: #26f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
222
src/mods/AppPlease/add.vue
Normal file
222
src/mods/AppPlease/add.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="add-form">
|
||||
<div class="form-item mar-b8">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">提问类型</span>
|
||||
<span :class="typeName ? 'value color-333' : 'value color-999'"
|
||||
@click="leaveMessageTypeShow = true">{{ typeName || '请选择' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/right-icon-999.png" alt="" class="right-icon">
|
||||
</div>
|
||||
<div class="form-item mar-b8">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">所在地区</span>
|
||||
<span class="value color-999">
|
||||
<AiAreaPicker v-model="areaId" class="picker" :name.sync="areaName">
|
||||
<div :class="areaName == '请选择' ? 'text color-999' : 'text color-333' ">{{ areaName || "请选择" }}</div>
|
||||
</AiAreaPicker>
|
||||
</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/right-icon-999.png" alt="" class="right-icon">
|
||||
</div>
|
||||
<div class="form-item title-line">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">提问标题</span>
|
||||
<div class="item-input">
|
||||
<input type="text" placeholder="请输入标题(30字以内)" placeholder-style="color:#999;" maxlength="30" v-model="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item mar-b8">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">提问内容</span>
|
||||
<div class="item-input fs-32">
|
||||
<u-input type="textarea" height="140" placeholder="请输入提问内容(500字以内)" placeholder-style="color:#999;"
|
||||
maxlength="500" v-model="content"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<span class="item-tips"></span>
|
||||
<span class="label">图片上传<span class="mini-label">(最多9张)</span></span>
|
||||
<div class="upload">
|
||||
<AiUploader :limit="9" v-model="files"></AiUploader>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<u-select v-model="leaveMessageTypeShow" :list="leaveMessageTypeList" @confirm="confirmMessageType"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<div class="fixed-bottom confirm-btn" @click="confirm">提交</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "my",
|
||||
computed: {
|
||||
...mapState(['global'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: '',
|
||||
typeName: '',
|
||||
areaId: '',
|
||||
areaName: "",
|
||||
areaRange: "",
|
||||
title: '',
|
||||
content: '',
|
||||
files: [],
|
||||
flag: false,
|
||||
leaveMessageTypeList: [],
|
||||
leaveMessageTypeShow: false
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.$dict.load('leaveMessageType').then((res) => {
|
||||
this.$nextTick(() => {
|
||||
this.$dict.getDict('leaveMessageType').map(i => {
|
||||
var item = {
|
||||
label: i.dictName,
|
||||
value: i.dictValue
|
||||
}
|
||||
this.leaveMessageTypeList.push(item)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
if (this.flag) return
|
||||
this.$loading()
|
||||
var params = {
|
||||
type: this.type,
|
||||
areaId: this.areaId,
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
images: JSON.stringify(this.files),
|
||||
status: 0
|
||||
}
|
||||
if (!params.type) {
|
||||
return this.$toast('请选择留言类型')
|
||||
}
|
||||
if (!params.areaId) {
|
||||
return this.$toast('请选择所在地区')
|
||||
}
|
||||
if (!params.title) {
|
||||
return this.$toast('请输入提问标题')
|
||||
}
|
||||
if (!params.content) {
|
||||
return this.$toast('请输入提问内容')
|
||||
}
|
||||
this.flag = true
|
||||
this.$instance.post(`/app/appleavemessage/addOrUpdate-wx`, params).then(res => {
|
||||
if (res && res.code == 0) {
|
||||
this.$hideLoading()
|
||||
uni.showModal({
|
||||
title: '您已成功提交留言',
|
||||
confirmText: "查看记录",
|
||||
confirmColor: "#197DF0",
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.flag = false
|
||||
uni.redirectTo({
|
||||
url: './questionList'
|
||||
})
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
this.flag = false
|
||||
})
|
||||
},
|
||||
confirmMessageType(e) {
|
||||
this.typeName = e[0].label
|
||||
this.type = e[0].value
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.add-form {
|
||||
padding-bottom: 112px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
padding: 34px 32px 34px 12px;
|
||||
line-height: 44px;
|
||||
background-color: #fff;
|
||||
|
||||
.item-tips {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
font-size: 32px;
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
min-width: 126px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-left: 8px;
|
||||
|
||||
.mini-label {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: 518px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
width: 520px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.color-333 {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-input {
|
||||
padding-bottom: 4px;
|
||||
margin-left: 24px;
|
||||
margin-top: 32px input {
|
||||
line-height: 42px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.upload {
|
||||
margin: 32px 0 024px;
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
299
src/mods/AppPlease/detail.vue
Normal file
299
src/mods/AppPlease/detail.vue
Normal file
@@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="detail">
|
||||
<div class="detail-header">
|
||||
<p class="info-title">[{{ $dict.getLabel('leaveMessageType', detailInfo.type) }}] {{ detailInfo.title }}</p>
|
||||
<div class="info-item">
|
||||
<span class="label">留言编号:</span>
|
||||
<span class="value">{{ detailInfo.msgCode }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">留言时间:</span>
|
||||
<span class="value">{{ detailInfo.createTime }}</span>
|
||||
</div>
|
||||
<!-- <div class="info-item">
|
||||
<span class="label">受理单位:</span>
|
||||
<span class="value">{{detailInfo.createTime}}</span>
|
||||
</div> -->
|
||||
<div class="info-item">
|
||||
<span class="label">处理状态:</span>
|
||||
<span class="value">{{ $dict.getLabel('leaveMessageStatus', detailInfo.status) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<p class="info-content">{{ detailInfo.content }}</p>
|
||||
<div class="img-list" v-if="detailInfo.iamgeList.length">
|
||||
<img :src="item.url" alt="" v-for="(item,index) in detailInfo.iamgeList" key="index"
|
||||
@click="previewdealListImage(index, detailInfo.iamgeList)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="reply-content" v-if="appLeaveMessageReplyList.length">
|
||||
<div class="reply-title">
|
||||
<img src="https://cdn.cunwuyun.cn/img/dialogue.svg" alt="">沟通记录
|
||||
</div>
|
||||
<div class="reply-list">
|
||||
<div class="item" v-for="(item, index) in appLeaveMessageReplyList" :key="index">
|
||||
<div class="item-top">
|
||||
<div class="user-img-bg" v-if="item.createUnitName">{{ item.first }}</div>
|
||||
<img :src="item.headPortrait" alt="" class="user-img"
|
||||
v-if="!item.createUnitName && item.createUserName && !item.openId">
|
||||
<img :src="avatarUrl" alt="" class="user-img" v-if="item.openId">
|
||||
|
||||
<span class="item-title" v-if="item.createUnitName">{{ item.createUnitName }} 回复</span>
|
||||
<span class="item-title" v-if="!item.createUnitName && item.createUserName && !item.openId">{{
|
||||
item.createUserName
|
||||
}} 回复</span>
|
||||
<span class="item-title" v-if="item.openId">我的 回复</span>
|
||||
|
||||
<span class="item-time">{{ item.createTime }}</span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
<p>{{ item.content }}</p>
|
||||
<div class="img-list">
|
||||
<img :src="items.url" alt="" v-for="(items,indexs) in item.images" :key="indexs"
|
||||
@click="previewdealListImage(indexs, item.images)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="no-more">------------ 没有更多回复了 ------------</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed-bottom confirm-btn" @click="toReply" v-if="detailInfo.status != 2">发表回复</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "my",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
detailInfo: {},
|
||||
appLeaveMessageReplyList: [],
|
||||
avatarUrl: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = options.id
|
||||
this.avatarUrl = this.user.avatarUrl
|
||||
},
|
||||
onShow() {
|
||||
this.$dict.load('leaveMessageType', 'leaveMessageStatus')
|
||||
this.getEventDetail()
|
||||
},
|
||||
methods: {
|
||||
getEventDetail() {
|
||||
this.$instance.post(`/app/appleavemessage/queryDetailById-wx?id=${this.id}`).then(res => {
|
||||
console.log(res)
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
res.data.iamgeList = JSON.parse(res.data.images)
|
||||
this.detailInfo = res.data;
|
||||
res.data.appLeaveMessageReplyList.map(item => {
|
||||
if (item.createUnitName) {
|
||||
item.first = item.createUnitName.substring(0, 1);
|
||||
}
|
||||
if (item.images) {
|
||||
item.images = JSON.parse(item.images);
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.appLeaveMessageReplyList = res.data.appLeaveMessageReplyList;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
previewdealListImage(current, imgList) {
|
||||
var tempList = []
|
||||
for (var i in imgList) {
|
||||
tempList.push(imgList[i].url)
|
||||
}
|
||||
uni.previewImage({
|
||||
current: tempList[current],
|
||||
urls: tempList
|
||||
})
|
||||
},
|
||||
//回复
|
||||
toReply() {
|
||||
this.$linkTo(`./reply?code=${this.detailInfo.msgCode}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #f3f6f9;
|
||||
|
||||
.detail {
|
||||
padding-bottom: 112px;
|
||||
|
||||
.detail-header {
|
||||
width: 100%;
|
||||
background: #197DF0;
|
||||
padding: 24px 32px 16px 32px;
|
||||
box-sizing: border-box;
|
||||
color: #FFF;
|
||||
|
||||
.info-title {
|
||||
font-weight: 500;
|
||||
line-height: 64px;
|
||||
word-break: break-all;
|
||||
font-size: 40px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
line-height: 40px;
|
||||
font-size: 28px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
text-align: justify;
|
||||
text-align-last: justify;
|
||||
width: 148px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: calc(100% - 148px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
background-color: #fff;
|
||||
padding: 32px 32px 032px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.info-content {
|
||||
line-height: 56px;
|
||||
color: #666;
|
||||
font-size: 32px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.img-list {
|
||||
padding-bottom: 16px img {
|
||||
width: 218px;
|
||||
height: 218px;
|
||||
margin: 0 16px 16px 0;
|
||||
}
|
||||
|
||||
img:nth-of-type(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reply-content {
|
||||
background-color: #fff;
|
||||
padding: 032px;
|
||||
|
||||
.reply-title {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
font-size: 32px img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-list {
|
||||
.item {
|
||||
margin-bottom: 32px;
|
||||
|
||||
.item-top {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.user-img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
margin-right: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.user-img-bg {
|
||||
display: inline-block;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
border-radius: 50%;
|
||||
margin-right: 16px;
|
||||
vertical-align: middle;
|
||||
background-color: #197DF0;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
display: inline-block;
|
||||
width: 342px;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #197DF0;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.item-time {
|
||||
font-size: 28px;
|
||||
color: #999;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-content {
|
||||
width: 606px;
|
||||
padding: 16px 16px 0;
|
||||
box-sizing: border-box;
|
||||
background: #F3F6F9;
|
||||
margin-left: 72px p {
|
||||
line-height: 40px;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
word-break: break-all;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.img-list {
|
||||
img {
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
margin: 0 16px 16px 0;
|
||||
}
|
||||
|
||||
img:nth-of-type(4n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-more {
|
||||
padding: 64px 0;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
src/mods/AppPlease/questionList.vue
Normal file
229
src/mods/AppPlease/questionList.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="fixed-top">
|
||||
<div class="header-tab">
|
||||
<div class="tab-item" v-for="(item, index) in tabList" :key="index" @click="tabClick(index)">{{ item }}<span
|
||||
class="active-line" v-if="tabIndex == index"></span></div>
|
||||
</div>
|
||||
<div class="header-search">
|
||||
<div class="search-input-content">
|
||||
<img src="https://cdn.cunwuyun.cn/img/search-blue.svg" alt="" class="search-icon">
|
||||
<input type="text" placeholder="请输入标题或者编号" class="search-input" placeholder-style="color:#E2E8F1;"
|
||||
v-model="inputValue" @confirm="getList" confirm-type="search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-select">
|
||||
<div class="select-item" @click="leaveMessageTypeShow = true">
|
||||
<span>{{ typeName || '提问类型' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
<div class="select-item" @click="timeSelectShow = true">
|
||||
<span>{{ searchTime || '提问时间' }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" alt="" class="down-icon">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="please-list">
|
||||
<div class="item" v-for="(item, index) in messageList" :key="index" @click="toDetail(item.id)">
|
||||
<p class="item-title"><span class="item-type"
|
||||
:class="'color-'+item.type">{{
|
||||
$dict.getLabel('leaveMessageType', item.type)
|
||||
}}</span>{{ item.title }}
|
||||
</p>
|
||||
<div>
|
||||
<span>提问人:{{ item.leaveName }}</span>
|
||||
<span>{{ ittem.createTime }}</span>
|
||||
</div>
|
||||
<img :src="'https://cdn.cunwuyun.cn/dvcp/question/status'+item.status+'.png'" alt="" class="item-status">
|
||||
</div>
|
||||
<AiEmpty v-if="!messageList.length" class="pad-t168"/>
|
||||
</div>
|
||||
<u-select v-model="leaveMessageTypeShow" :list="leaveMessageTypeList" @confirm="confirmMessageType"
|
||||
confirm-color="#07c160"></u-select>
|
||||
<u-picker v-model="timeSelectShow" mode="time" :params="params" :start-year="startDate" :end-year="endDate"
|
||||
:default-selector="defaultDate"
|
||||
confirm-color="#07c160" @confirm="timeSelectConfirm"></u-picker>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "my",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabList: ['全部', '待回复', '已回复', '处理完成'],
|
||||
tabIndex: 0,
|
||||
status: '',
|
||||
inputValue: '',
|
||||
timeSelectShow: false,
|
||||
params: {
|
||||
year: true,
|
||||
month: true,
|
||||
day: false,
|
||||
hour: false,
|
||||
minute: false,
|
||||
second: false,
|
||||
},
|
||||
startYear: '',
|
||||
endYear: '',
|
||||
defaultDate: [],
|
||||
searchTime: '',
|
||||
leaveMessageTypeShow: false,
|
||||
leaveMessageTypeList: [],
|
||||
type: '',
|
||||
typeName: '',
|
||||
messageList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.$dict.load('leaveMessageType').then((res) => {
|
||||
this.$nextTick(() => {
|
||||
this.$dict.getDict('leaveMessageType').map(i => {
|
||||
var item = {
|
||||
label: i.dictName,
|
||||
value: i.dictValue
|
||||
}
|
||||
this.leaveMessageTypeList.push(item)
|
||||
})
|
||||
})
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.messageList = []
|
||||
var searchParams = {
|
||||
createTime: this.searchTime ? this.searchTime + "08" + ' ' + '00' + ":" + "00" + ":" + "00" : '',
|
||||
title: this.inputValue,
|
||||
type: this.type,
|
||||
status: this.status,
|
||||
userType: 0,//小程序用户
|
||||
openId: this.user.openId
|
||||
}
|
||||
this.$instance.post(`/app/appleavemessage/listForWx`, searchParams).then(res => {
|
||||
if (res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
// var reg = new RegExp('(?<=.).', 'g')
|
||||
// item.leaveName = item.leaveName.replace(reg, '*')
|
||||
item.leaveName = item.leaveName.substring(0, 1) + '**'
|
||||
})
|
||||
this.messageList = res.data.records
|
||||
}
|
||||
})
|
||||
},
|
||||
timeSelectConfirm(e) {
|
||||
this.searchTime = e.year + '-' + e.month
|
||||
this.getList()
|
||||
},
|
||||
confirmMessageType(e) {
|
||||
this.typeName = e[0].label
|
||||
this.type = e[0].value
|
||||
this.getList()
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
if (type === 'start') {
|
||||
year = year - 10;
|
||||
} else if (type === 'end') {
|
||||
year = year;
|
||||
}
|
||||
return `${year}`;
|
||||
},
|
||||
toDetail(id) {
|
||||
this.$linkTo(`./detail?id=${id}`)
|
||||
},
|
||||
tabClick(index) {
|
||||
this.tabIndex = index
|
||||
if (!this.tabIndex) {
|
||||
this.status = ''
|
||||
} else {
|
||||
this.status = this.tabIndex - 1
|
||||
}
|
||||
this.getList()
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.please-list {
|
||||
padding: 336px 32px 144px;
|
||||
|
||||
.item {
|
||||
width: 686px;
|
||||
background: #FFF;
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 32px;
|
||||
position: relative;
|
||||
|
||||
.item-title {
|
||||
word-break: break-all;
|
||||
line-height: 44px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.item-type {
|
||||
border-radius: 8px;
|
||||
padding: 8px 8px 4px;
|
||||
font-size: 26px;
|
||||
line-height: 36px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.item-status {
|
||||
width: 136px;
|
||||
height: 136px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.color-0 {
|
||||
background: #FFEBEF;
|
||||
color: #F46;
|
||||
}
|
||||
|
||||
.color-1 {
|
||||
background: #E8EFFF;
|
||||
color: #26f;
|
||||
}
|
||||
|
||||
.color-2 {
|
||||
background: #E8EFFF;
|
||||
color: #26f;
|
||||
}
|
||||
|
||||
.fixed-top {
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
161
src/mods/AppPlease/reply.vue
Normal file
161
src/mods/AppPlease/reply.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="pad-b112">
|
||||
<div class="bg-197DF0"></div>
|
||||
<div class="add-form">
|
||||
<div class="form-item">
|
||||
<span class="item-tips">*</span>
|
||||
<span class="label">留言内容</span>
|
||||
<div class="item-input title-line">
|
||||
<u-input type="textarea" height="200" placeholder="请输入留言内容(500字以内)" placeholder-style="color:#999;"
|
||||
maxlength="500" v-model="content"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<span class="item-tips"></span>
|
||||
<span class="label">图片上传<span class="mini-label">(最多9张)</span></span>
|
||||
<div class="upload">
|
||||
<AiUploader :limit="9" v-model="files"></AiUploader>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed-bottom confirm-btn" @click="reply">提交</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import AiUploader from '@/components/AiUploader/AiUploader'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "my",
|
||||
components: {
|
||||
AiUploader
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
files: [],
|
||||
avatarUrl: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.msgCode = options.code
|
||||
this.avatarUrl = this.user.avatarUrl
|
||||
},
|
||||
methods: {
|
||||
reply() {
|
||||
if (!this.content) {
|
||||
return this.$toast('请输入留言内容')
|
||||
}
|
||||
var params = {
|
||||
"content": this.content,
|
||||
"images": JSON.stringify(this.files),
|
||||
"msgCode": this.msgCode,
|
||||
"userType": 0,
|
||||
'headPortrait': this.avatarUrl
|
||||
}
|
||||
this.$instance.post(`/app/appleavemessagereply/addOrUpdateForWX`, params).then(res => {
|
||||
if (res.code == 0) {
|
||||
uni.showModal({
|
||||
title: '留言回复成功',
|
||||
confirmText: "查看详情",
|
||||
confirmColor: "#197DF0",
|
||||
showCancel: false,
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
background-color: #F3F6F9;
|
||||
|
||||
.pad-b112 {
|
||||
padding-bottom: 112px;
|
||||
}
|
||||
|
||||
.bg-197DF0 {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background: #197DF0;
|
||||
}
|
||||
|
||||
.add-form {
|
||||
width: 686px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
margin: -68px 0 032px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
padding: 34px 32px 012px;
|
||||
line-height: 44px;
|
||||
|
||||
.item-tips {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
font-size: 32px;
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
min-width: 126px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
margin-left: 8px;
|
||||
|
||||
.mini-label {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
display: inline-block;
|
||||
width: 520px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.item-input {
|
||||
padding-bottom: 4px;
|
||||
margin-left: 24px input {
|
||||
line-height: 42px;
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.upload {
|
||||
margin: 32px 0 024px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
220
src/mods/AppPolice/AppPolice.vue
Normal file
220
src/mods/AppPolice/AppPolice.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div class="wrapper" v-if="pageShow">
|
||||
<div class="area">
|
||||
<ai-area-picker ref="area" class="ai-area" :value="areaId" :name.sync="areaName" :areaId="$areaId"
|
||||
@select="handleSelect">
|
||||
<div class="ai-area__wrapper">
|
||||
<span class="label" v-if="areaName">{{ areaName }}</span>
|
||||
<span v-else>请选择</span>
|
||||
<image src="/static/img/area-bottom.png"/>
|
||||
</div>
|
||||
</ai-area-picker>
|
||||
</div>
|
||||
<tempate v-if="list.length">
|
||||
<header>
|
||||
<span>辅警列表</span>
|
||||
<div class="total">
|
||||
共<em>{{ list.length }}</em>名辅警
|
||||
</div>
|
||||
</header>
|
||||
<div class="list-wrap">
|
||||
<div class="card" v-for="(item,index) in list" :key="index">
|
||||
<img
|
||||
:src="item.picture || require('../../static/img/police.png')"
|
||||
@click="preview(index)"
|
||||
alt="">
|
||||
<div class="right">
|
||||
<span class="user-name">{{ item.name }}</span>
|
||||
<span class="state">驻村辅警</span>
|
||||
<span class="phone" @click="call(item)">{{ item.phone }}</span>
|
||||
<span>{{ item.areaName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</tempate>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppPolice',
|
||||
appName: "驻村辅警",
|
||||
data() {
|
||||
return {
|
||||
current: 1,
|
||||
areaId: "",
|
||||
list: [],
|
||||
areaName: '',
|
||||
$areaId: '',
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.$loading()
|
||||
this.areaId = this.$areaId
|
||||
this.areaName = this.$areaName
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
call({phone: phoneNumber}) {
|
||||
uni.makePhoneCall({phoneNumber})
|
||||
},
|
||||
preview(index) {
|
||||
if (this.list[index]["picture"]?.startsWith("http")) {
|
||||
uni.previewImage({
|
||||
current: this.list[index]["picture"],
|
||||
urls: [this.list[index]["picture"]]
|
||||
})
|
||||
}
|
||||
},
|
||||
handleSelect(val) {
|
||||
this.$loading()
|
||||
this.areaId = val
|
||||
this.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post(`/app/appvillageauxiliarypolice/list`, null, {
|
||||
params: {
|
||||
isPublic: 1,
|
||||
areaId: this.areaId,
|
||||
current: this.current
|
||||
}
|
||||
}).then(res => {
|
||||
if (res?.data) {
|
||||
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records;
|
||||
}
|
||||
|
||||
this.pageShow = true
|
||||
this.$hideLoading()
|
||||
})
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current++;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding-top: 124px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
height: 124px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #4181FF;
|
||||
padding-left: 32px;
|
||||
|
||||
.ai-area__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-right: 16px;
|
||||
color: #FFFFFF;
|
||||
font-size: 44px;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 16px;
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
|
||||
& > span {
|
||||
font-size: 38px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.total {
|
||||
margin-left: auto;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > em {
|
||||
color: #4181FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
box-sizing: border-box;
|
||||
padding: 0 32px;
|
||||
|
||||
.card {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
& > img {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 8px;
|
||||
margin-right: 32px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
height: 200px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 26px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
|
||||
.user-name {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.state {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.phone {
|
||||
color: #4181FF;
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
255
src/mods/AppProgress/AppProgress.vue
Normal file
255
src/mods/AppProgress/AppProgress.vue
Normal file
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div class="progressList">
|
||||
<div class="search">
|
||||
<div class="search-container">
|
||||
<i class="iconfont"></i>
|
||||
<input placeholder="请输入需要搜索的内容" placeholder-style="color:rgba(255,255,255,0.5)" v-model="param" @confirm="reset"
|
||||
:focus="focus" confirm-type="search">
|
||||
</div>
|
||||
</div>
|
||||
<div class="progressList-list">
|
||||
<div class="item" v-for="(item, index) in list" :key="index" hover-class="bg-hover"
|
||||
@click="$linkTo('./progressDetail?id=' + item.id)">
|
||||
<div class="top">
|
||||
<h2>{{ item.processDefName }}</h2>
|
||||
<!-- <AiIcon class="progressList-icon" :icon="iconList[item.approvalStatus]" size="56"></AiIcon> -->
|
||||
<div class="item-info">
|
||||
<span>申请类型</span>
|
||||
<div>{{ item.classificationName }}</div>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span>申请日期</span>
|
||||
<div>{{ item.createTime }}</div>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span>完成日期</span>
|
||||
<div>{{ item.overTime || '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<em :style="{background: mapColor(item.approvalStatus)}"></em>
|
||||
<span
|
||||
:style="{color: mapColor(item.approvalStatus)}">{{
|
||||
$dict.getLabel('approvalStatus', item.approvalStatus)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="!list.length"></AiEmpty>
|
||||
|
||||
<!-- <u-loadmore :status="loadingStatus" :margin-top="30" :margin-bottom="30" color="#999" font-size="26"/> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "AppProgress",
|
||||
appName: "办事进度",
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
title: '',
|
||||
subTitle: '',
|
||||
current: 0,
|
||||
focus: false,
|
||||
param: '',
|
||||
list: [],
|
||||
loadingStatus: 'loadmore',
|
||||
iconList: {
|
||||
'0': 'icon1',
|
||||
'1': 'icon2',
|
||||
'2': 'icon3'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
if (query.focus === '1') {
|
||||
this.focus = true
|
||||
}
|
||||
this.id = query.id
|
||||
this.title = query.title
|
||||
this.subTitle = query.subTitle
|
||||
this.$dict.load(['approvalStatus']).then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
reset() {
|
||||
this.current = 0
|
||||
this.loadingStatus = 'loading'
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
mapColor(status) {
|
||||
return {
|
||||
'0': '#FF883C',
|
||||
'1': '#42D784',
|
||||
'2': '#FF4466'
|
||||
}[status]
|
||||
},
|
||||
|
||||
getList() {
|
||||
if (this.loadingStatus === 'nomore') return
|
||||
|
||||
this.loadingStatus = 'loading'
|
||||
this.$instance.post(`/app/approv-alapply-info/xcx-list`, null, {
|
||||
params: {
|
||||
current: this.current + 1,
|
||||
size: 10,
|
||||
param: this.param
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (!res.data.records.length) {
|
||||
if (this.current === 0) this.list = []
|
||||
this.loadingStatus = 'nomore'
|
||||
return false
|
||||
}
|
||||
|
||||
const data = res.data.records.map(item => {
|
||||
return item
|
||||
})
|
||||
if (this.current === 0) this.list = []
|
||||
|
||||
this.list.push(...data);
|
||||
|
||||
this.current = this.current + 1
|
||||
this.loadingStatus = 'loadmore'
|
||||
|
||||
if (this.list.length < 10) {
|
||||
this.loadingStatus = 'nomore'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.getList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
div, label, i, view {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.progressList {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.search {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 104px;
|
||||
padding: 20px 32px;
|
||||
box-sizing: border-box;
|
||||
background: #4181FF;
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 64px;
|
||||
padding: 032px;
|
||||
border-radius: 32px;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
|
||||
i {
|
||||
padding-right: 12px;
|
||||
font-size: 32px;
|
||||
color: rgba(255, 255, 255, .5);
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
font-size: 26px;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progressList-list {
|
||||
padding-top: 104px;
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
width: 686px;
|
||||
margin: 24px auto 0;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16px;
|
||||
|
||||
.top {
|
||||
box-sizing: border-box;
|
||||
padding: 32px;
|
||||
border-bottom: 1px solid #DDDDDD;
|
||||
|
||||
.progressList-icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 56px;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 42px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
span {
|
||||
color: #999999;
|
||||
font-size: 26px;
|
||||
line-height: 36px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
div {
|
||||
color: #343D65;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 24px;
|
||||
padding-right: 56px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
text-align: justify;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
height: 104px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 32px;
|
||||
|
||||
& > em {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #FF883C;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #FF883C;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
122
src/mods/AppProgress/progressAnnex.vue
Normal file
122
src/mods/AppProgress/progressAnnex.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div class="annex">
|
||||
<div class="annex-list">
|
||||
<div class="annex-item">
|
||||
<div class="annex-item__left">
|
||||
<image :src="img" @click="preview"/>
|
||||
<h2>{{ name }}</h2>
|
||||
</div>
|
||||
<i class="iconfont" @click="download"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
img: '',
|
||||
name: ''
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.img = query.img
|
||||
this.name = query.name
|
||||
},
|
||||
|
||||
methods: {
|
||||
preview() {
|
||||
uni.previewImage({
|
||||
urls: [this.img],
|
||||
current: this.img
|
||||
})
|
||||
},
|
||||
|
||||
download() {
|
||||
uni.downloadFile({
|
||||
url: this.img,
|
||||
success: res => {
|
||||
const img = res.tempFilePath
|
||||
this.$hideLoading()
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: img,
|
||||
success: () => {
|
||||
this.$toast('保存成功')
|
||||
},
|
||||
fail: () => {
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
if (!res.authSetting['scope.writePhotosAlbum']) {
|
||||
this.$dialog.confirm({
|
||||
content: '未授权',
|
||||
confirmText: '去设置'
|
||||
}).then(() => {
|
||||
wx.openSetting({
|
||||
success: res => {
|
||||
if (!res.authSetting['scope.writePhotosAlbum']) {
|
||||
this.$toast({
|
||||
title: '此功能需获取相册权限',
|
||||
duration: 3000
|
||||
})
|
||||
} else {
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
this.$hideLoading()
|
||||
this.$toast('保存失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.annex {
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.annex-list {
|
||||
padding-top: 40px;
|
||||
|
||||
.annex-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 032px i {
|
||||
font-size: 52px;
|
||||
color: #197DF0;
|
||||
}
|
||||
|
||||
.annex-item__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
751
src/mods/AppProgress/progressDetail.vue
Normal file
751
src/mods/AppProgress/progressDetail.vue
Normal file
@@ -0,0 +1,751 @@
|
||||
<template>
|
||||
<div class="progressDetail" v-if="pageShow">
|
||||
<div class="status" v-if="info.approvalStatus === '1'">
|
||||
<h2>审批通过:</h2>
|
||||
<div class="status-content">
|
||||
<span>[{{ info.processDefName }}]已签署完成,</span>
|
||||
<i @click="$linkTo('./progressAnnex?img=' + info.pdfPicFile.url + '&name=' + info.processDefName)">点击查看和保存</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<h2 :style="{maxWidth: info.approvalStatus !== '1' ? '100%' : '550rpx'}">{{ info.processDefName }}</h2>
|
||||
<AiIcon class="info-status" v-if="info.approvalStatus === '1'" size="96" icon="iconsp-pass"></AiIcon>
|
||||
<div class="info-user">
|
||||
<image v-if="info.createUserAvatar" :src="info.createUserAvatar"/>
|
||||
<span v-else>{{ nameAvatar(info.createUserName) }}</span>
|
||||
<div class="inf-user__right flex1">
|
||||
<h2>{{ info.createUserName }}</h2>
|
||||
<p>{{ info.createTime }}</p>
|
||||
</div>
|
||||
<i :style="{color: mapStatusColor(info.approvalStatus)}"
|
||||
v-if="info.approvalStatus !== '1'">{{ $dict.getLabel('approvalStatus', info.approvalStatus) }}</i>
|
||||
</div>
|
||||
<div class="info-list">
|
||||
<div class="info-item">
|
||||
<span>所属类型:</span>
|
||||
<div>{{ info.classificationName || '-' }}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span>所属部门:</span>
|
||||
<div>{{ $dict.getLabel('hbDepartment', info.department) || '-' }}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span>审批编号:</span>
|
||||
<div>{{ info.serialNumber }}</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span>附件资料:</span>
|
||||
<div v-if="!!info.annexs && info.annexs.length">
|
||||
<div class="imgs" v-for="(item, index) in info.annexs" :key="index">
|
||||
<img :src="item.annexFile.url" mode="aspectFill" @click="preview(info.annexs, item.annexFile.url)">
|
||||
<span>{{ item.annexName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>暂无附件</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="detail-tab">
|
||||
<div @click="currIndex = 0" :class="[currIndex === 0 ? 'active' : '']">申请表单</div>
|
||||
<div @click="currIndex = 1" :class="[currIndex === 1 ? 'active' : '']">流程信息</div>
|
||||
</div>
|
||||
<!--申请表单-->
|
||||
<div class="detail-form" v-if="currIndex==0">
|
||||
<div class="detail-form__item" v-for="(item, index) in tableForm" :key="index">
|
||||
<div class="detail-form__item--title" @click="showMore(index)">
|
||||
<div class="left">
|
||||
<span></span>
|
||||
<h2>{{ item[0].groupName }}</h2>
|
||||
</div>
|
||||
<i class="iconfont" :class="[index === formIndex ? 'title-active' : '']"></i>
|
||||
</div>
|
||||
<div class="detail-form__item--list" v-show="index === formIndex">
|
||||
<div class="detail-form__item--info" v-for="(field, i) in item" :key="i">
|
||||
<h2>{{ field.fieldName }}{{ field.fieldNameSuffix || '' }}</h2>
|
||||
<span v-if="!field.dictionaryCode">{{ field.fieldValue || '-' }}</span>
|
||||
<span v-if="field.dictionaryCode && field.fieldDataType !== '5'">{{
|
||||
$dict.getLabel(field.dictionaryCode, field.fieldValue) || '-'
|
||||
}}</span>
|
||||
<span v-if="field.dictionaryCode && field.fieldDataType === '5'">{{
|
||||
getDictValue(field.dictionaryCode, field.fieldValue)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--流程信息-->
|
||||
<div class="detail-list" v-if="currIndex==1">
|
||||
<div class="step-item" v-for="(item, index) in stepList" :key="index">
|
||||
<div class="line"></div>
|
||||
<div class="detail-left">
|
||||
<image class="avatar" v-if="item.stepAvatar && item.userName" :src="item.stepAvatar"/>
|
||||
<span v-if="!item.stepAvatar && item.userName">{{ item.userName.substr(item.userName.length - 2) }}</span>
|
||||
<image v-if="index !== 0 && item.candidates && item.candidates.length > 1" class="detail-left__statusicon"
|
||||
src="/static/img/notice.png"/>
|
||||
<image class="avatar"
|
||||
v-if="index !== 0 && item.candidates && item.candidates.length === 1 && item.candidates[0].avatar"
|
||||
:src="item.candidates[0].avatar"/>
|
||||
<span v-if="index !== 0 && item.candidates && item.candidates.length === 1 && !item.candidates[0].avatar">{{
|
||||
item.candidates[0].name.substr(item.candidates[0].name - 2)
|
||||
}}</span>
|
||||
<image class="detail-left__icon" src="/static/img/gou.png"
|
||||
v-if="index === 0 || ['0', '1', '6', '5'].indexOf(item.stepType) > -1"/>
|
||||
<image class="detail-left__icon" src="/static/img/point.png" v-else-if="item.stepType !== '2'"/>
|
||||
</div>
|
||||
<div class="detail-right">
|
||||
<div class="detail-right__title">
|
||||
<h2>{{ item.title }}</h2>
|
||||
<span v-if="item.approvalTime">{{ item.approvalTime }}</span>
|
||||
</div>
|
||||
<div class="detail-right__subtitle" v-if="item.stepType === '0'">
|
||||
<span>{{ item.userName || '-' }}</span>
|
||||
<i>({{ stepTypeList[item.stepType] }})</i>
|
||||
</div>
|
||||
<div class="detail-right__subtitle" v-else-if="item.stepType !== '2'">
|
||||
<span>{{ item.title2 }}</span>
|
||||
<i v-if="item.title2Desc" :style="{color: mapColor(item.stepType)}">{{ item.title2Desc }}</i>
|
||||
</div>
|
||||
<div class="detail-right__subtitle" v-else-if="item.stepType === '2'">
|
||||
<span>{{ item.title2 }} </span>
|
||||
<i style="color: #F14242"> {{ item.title2Desc }}</i>
|
||||
</div>
|
||||
<div class="detail-right__subtitle" v-if="item.stepType === '2'">
|
||||
<span>审批意见</span>
|
||||
<i style="color: #F14242;">{{ item.opinion || '-' }}</i>
|
||||
</div>
|
||||
<div class="detail-right__subtitle detail-right__text" style="display: block"
|
||||
v-if="item.candidateFieldInfos && item.candidateFieldInfos.length"
|
||||
v-for="(candidateField, z) in item.candidateFieldInfos" :key="z">
|
||||
<span>{{ candidateField.fieldName }}</span>
|
||||
<i style="color: #343D65;display: contents;">{{
|
||||
candidateField.dictionaryCode ? $dict.getLabel(candidateField.dictionaryCode, candidateField.fieldValue) || '-' : candidateField.fieldValue || '-'
|
||||
}}</i>
|
||||
</div>
|
||||
<div class="detail-right__imgs" v-if="item.pictureFiles && item.pictureFiles.length">
|
||||
<image :src="img.url" mode="aspectFill" v-for="(img, i) in item.pictureFiles" :key="i"
|
||||
@click="previewPic(item.pictureFiles, img.url)"/>
|
||||
</div>
|
||||
<div class="detail-right__doc" v-if="item.annexFiles && item.annexFiles.length">
|
||||
<div class="doc-item" v-for="(file, j) in item.annexFiles" :key="j" @click="saveFile(file)">
|
||||
<h2>{{ file.name }}</h2>
|
||||
<span>{{ (file.size / 1024).toFixed(2) }}KB</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-right__userlist" v-if="item.candidates && item.candidates.length">
|
||||
<div class="detail-right__userinfo" v-for="(user, z) in item.candidates" :key="z">
|
||||
<image v-if="user.avatar" :src="user.avatar"/>
|
||||
<span v-else>{{ user.name.substr(user.name.length - 2) }}</span>
|
||||
<h2>{{ user.name }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
currIndex: 0,
|
||||
id: '',
|
||||
info: {},
|
||||
formIndex: 0,
|
||||
tableForm: [],
|
||||
pageShow: false,
|
||||
nodeApprovalStatusList: {
|
||||
'0': '待审批',
|
||||
'1': '审批通过',
|
||||
'2': '审批驳回'
|
||||
},
|
||||
stepTypeList: {
|
||||
'0': '发起',
|
||||
'1': '审批通过',
|
||||
'2': '审批拒绝',
|
||||
'3': '抄送',
|
||||
'4': '转办审批中',
|
||||
'5': '转办审批同意',
|
||||
'6': '转办审批拒绝',
|
||||
'7': '发起人撤回',
|
||||
'8': '待审批',
|
||||
'9': '未到达该节点'
|
||||
},
|
||||
stepList: []
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.id = query.id
|
||||
this.getInfo(query.id)
|
||||
},
|
||||
methods: {
|
||||
showMore(index) {
|
||||
if (index === this.formIndex) {
|
||||
this.formIndex = -1
|
||||
} else {
|
||||
this.formIndex = index
|
||||
}
|
||||
},
|
||||
|
||||
mapStatusColor(status) {
|
||||
return {
|
||||
'0': '#FF9B2B',
|
||||
'1': '#3078E1',
|
||||
'2': '#F14242'
|
||||
}[status]
|
||||
},
|
||||
|
||||
mapColor(status) {
|
||||
if (status === '1') {
|
||||
return '#2EA222'
|
||||
}
|
||||
|
||||
if (status === '2' || status === '6' || status === '7') {
|
||||
return '#F14242'
|
||||
}
|
||||
|
||||
return '#FF8822'
|
||||
},
|
||||
|
||||
saveFile(file) {
|
||||
if (['.png', '.jpg', '.jpeg'].indexOf(file.postfix) > -1) {
|
||||
uni.previewImage({
|
||||
urls: [file.url],
|
||||
current: file.url
|
||||
})
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
uni.downloadFile({
|
||||
url: file.url,
|
||||
success: res => {
|
||||
const filePath = res.tempFilePath
|
||||
this.$hideLoading()
|
||||
wx.openDocument({
|
||||
filePath: filePath,
|
||||
success: function (res) {
|
||||
console.log('打开文档成功')
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
this.$hideLoading()
|
||||
this.$toast('保存失败')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
previewPic(imgList, img) {
|
||||
uni.previewImage({
|
||||
urls: imgList.map(v => v.url),
|
||||
current: img
|
||||
})
|
||||
},
|
||||
|
||||
preview(imgList, img) {
|
||||
uni.previewImage({
|
||||
urls: imgList.map(v => v.annexFile.url),
|
||||
current: img
|
||||
})
|
||||
},
|
||||
|
||||
getDictValue(dictKey, value) {
|
||||
return value.split(',').map(item => {
|
||||
return this.$dict.getLabel(dictKey, item)
|
||||
}).join(',')
|
||||
},
|
||||
|
||||
getInfo(id) {
|
||||
this.$loading()
|
||||
this.$instance.post(`/app/approv-alapply-info/info-id-table?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
const groupFormIds = this.unique(res.data.tableInfo.tableFieldInfos.filter(v => v.fieldType !== '1').map(v => v.groupIndex))
|
||||
const dictKeys = res.data.tableInfo.tableFieldInfos.filter(v => !!v.dictionaryCode).map(v => v.dictionaryCode)
|
||||
this.$dict.load([...dictKeys, 'hbDepartment', 'nodeApprovalStatus', 'nodeType']).then(() => {
|
||||
this.info = res.data
|
||||
this.$instance.post(`/app/approv-alapply-info/processinfo-id2?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
let dictKeys = []
|
||||
res.data.forEach(item => {
|
||||
if (item.candidateFieldInfos && item.candidateFieldInfos.length) {
|
||||
item.candidateFieldInfos.forEach(v => {
|
||||
v.dictionaryCode && dictKeys.push(v.dictionaryCode)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (dictKeys.length) {
|
||||
this.$dict.load([...dictKeys]).then(() => {
|
||||
this.stepList = res.data
|
||||
})
|
||||
} else {
|
||||
this.stepList = res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
this.pageShow = true
|
||||
})
|
||||
this.tableForm = groupFormIds.map(index => {
|
||||
return res.data.tableInfo.tableFieldInfos.filter(v => v.fieldType !== '1' && v.groupIndex === index)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 数组去重
|
||||
*/
|
||||
unique(arr) {
|
||||
return arr.filter((item, index) => {
|
||||
return arr.indexOf(item, 0) === index
|
||||
})
|
||||
},
|
||||
nameAvatar(name) {
|
||||
return name?.split("")?.slice(-2) || "游客"
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
div, label, i, view {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.progressDetail {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
padding: 40px 32px;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding-bottom: 88px;
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
|
||||
.line {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-right__doc {
|
||||
padding-top: 8px;
|
||||
|
||||
.doc-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
background: #F7F7F7;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #DDDDDD;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #999999;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
max-width: 444px;
|
||||
line-height: 32px;
|
||||
color: #333333;
|
||||
font-size: 24px;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-right {
|
||||
flex: 1;
|
||||
|
||||
.detail-right__title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
|
||||
span {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
& > h2 {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-right__userlist {
|
||||
margin-top: 16px;
|
||||
font-size: 0;
|
||||
|
||||
.detail-right__userinfo {
|
||||
display: inline-block;
|
||||
margin-right: 32px;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
|
||||
image, span {
|
||||
display: inline-block;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 26px;
|
||||
border-radius: 50%;
|
||||
background: #2266FF;
|
||||
}
|
||||
|
||||
h2 {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #666666;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-right__subtitle {
|
||||
display: flex;
|
||||
margin-bottom: 6px span {
|
||||
margin-right: 10px;
|
||||
color: #666666;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
i {
|
||||
flex: 1;
|
||||
text-align: justify;
|
||||
word-break: break-all;
|
||||
color: #2EA222;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-right__text {
|
||||
// color: #343D65;
|
||||
// font-size: 28px;
|
||||
// margin: 6px 0;
|
||||
}
|
||||
|
||||
.detail-right__imgs {
|
||||
font-size: 0;
|
||||
|
||||
image {
|
||||
display: inline-block;
|
||||
width: 136px;
|
||||
height: 136px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
position: absolute;
|
||||
left: 38px;
|
||||
top: 80px;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background: #EEEEEE;
|
||||
}
|
||||
|
||||
.detail-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-right: 40px;
|
||||
flex-shrink: 1;
|
||||
border-radius: 50%;
|
||||
background: #2266FF;
|
||||
|
||||
.detail-left__statusicon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.detail-left__icon {
|
||||
position: absolute;
|
||||
top: 48px;
|
||||
right: -4px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
span, .avatar {
|
||||
display: block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background: #2266FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
width: 100%;
|
||||
padding: 20px 32 px20px;
|
||||
font-weight: 600;
|
||||
background: #EFF4FF;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 10px;
|
||||
color: #3A7EE2;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.status-content {
|
||||
span {
|
||||
display: inline;
|
||||
font-size: 28px;
|
||||
color: #3A7EE2;
|
||||
}
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
font-size: 28px;
|
||||
color: #3A7EE2;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
position: relative;
|
||||
padding: 32px 32px 20px;
|
||||
background: #fff;
|
||||
|
||||
& > h2 {
|
||||
max-width: 550px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.info-status {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
font-size: 96px;;
|
||||
}
|
||||
|
||||
.info-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 112px;
|
||||
border-bottom: 1px solid #D8DDE6;
|
||||
|
||||
i {
|
||||
font-size: 28px;
|
||||
color: #FF8822;
|
||||
}
|
||||
|
||||
span, image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
margin-right: 16px;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
font-size: 28px;
|
||||
border-radius: 50%;
|
||||
background: #2266FF;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 4px;
|
||||
font-size: 24px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-list {
|
||||
padding-top: 32px;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:first-child {
|
||||
div {
|
||||
color: #1365DD;
|
||||
}
|
||||
}
|
||||
|
||||
.imgs {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 0;
|
||||
|
||||
image {
|
||||
width: 170px;
|
||||
height: 170px;
|
||||
}
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
flex-shrink: 1;
|
||||
color: #999999;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
& > div {
|
||||
flex: 1;
|
||||
color: #343D65;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail {
|
||||
margin-top: 16px;
|
||||
background: #fff;
|
||||
|
||||
.detail-tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 96px;
|
||||
border-bottom: 1px solid #D8DDE6;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
line-height: 96px;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
font-size: 34px;
|
||||
font-weight: 600;
|
||||
border-bottom: 4px solid transparent;
|
||||
|
||||
&.active {
|
||||
color: #1365DD;
|
||||
border-bottom: 4px solid #1365DD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-form {
|
||||
.detail-form__item {
|
||||
border-bottom: 1px solid #D8DDE6;
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-form__item--title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 96px;
|
||||
padding: 0 32px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
width: 4px;
|
||||
height: 32px;
|
||||
margin-right: 12px;
|
||||
background: #1365DD;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
position: relative;
|
||||
font-size: 32px;
|
||||
color: #cfcfcf;
|
||||
transform: rotate(180deg);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.title-active {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-form__item--list {
|
||||
background: #FAFAFA;
|
||||
padding: 0 32px;
|
||||
|
||||
.detail-form__item--info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 0;
|
||||
|
||||
span {
|
||||
text-align: right;
|
||||
max-width: 500px;
|
||||
padding-left: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
339
src/mods/AppSupermarket/AppSupermarket.vue
Normal file
339
src/mods/AppSupermarket/AppSupermarket.vue
Normal file
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<section class="supermarket">
|
||||
<template v-if="Object.keys(list).length">
|
||||
<div class="nav-left">
|
||||
<scroll-view scroll-y style="height: 100%;">
|
||||
<div class="nav-left-item" v-for="(val, key, index) in list" :key="index"
|
||||
@click="clickSort(key,index)">
|
||||
{{ key }}分区
|
||||
<u-badge size="mini" :count="sortCountList[index]" absolute :offset="[5,5]"></u-badge>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<scroll-view scroll-y style="height: 100%;">
|
||||
<div class="category-item" v-for="(item,index) in categoryList" :key="index">
|
||||
<img
|
||||
:src="parseObj(item.photo)"
|
||||
class="category-img" alt="">
|
||||
<div class="category-info">
|
||||
<label class="hidden">{{ item.merchandiseName }}</label>
|
||||
<span class="score">{{ item.costIntegral }}
|
||||
<span>积分</span>
|
||||
</span>
|
||||
<div class="wrap">
|
||||
<div class="lxc-count">
|
||||
<div class="less" @click="less(item,index)">-</div>
|
||||
<div class="num">{{ item.merchandiseNumber }}</div>
|
||||
<div class="less" @click="add(item,index)">+</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="sum">
|
||||
<span>共{{ totalCount }}件商品</span>
|
||||
<span>合计:{{ totalScore }}
|
||||
<span>积分</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="btn" @click="handleSubmit">去结算</div>
|
||||
</div>
|
||||
</template>
|
||||
<AiEmpty v-else></AiEmpty>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AppSupermarket",
|
||||
appName:"信用好超市",
|
||||
data() {
|
||||
return {
|
||||
list: {},
|
||||
idx: 0,
|
||||
totalScore: 0,
|
||||
sortCountList: [],
|
||||
mark: 0,
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
watch: {
|
||||
list: {
|
||||
handler(val) {
|
||||
let sum = 0
|
||||
Object.keys(val).map(e => {
|
||||
val[e].map(p => {
|
||||
if (p.merchandiseNumber != 0) {
|
||||
sum += (p.merchandiseNumber) * (p.costIntegral)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.totalScore = sum
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
totalCount() {
|
||||
return this.sortCountList.reduce((pre, cur) => (pre + cur), 0)
|
||||
},
|
||||
|
||||
categoryList() {
|
||||
return this.idx == 0 ? this.list[Object.keys(this.list)[0]] : this.list[this.idx]
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleSubmit() {
|
||||
if (this.totalCount == 0) {
|
||||
return uni.showToast({
|
||||
title: "您还没有选择商品",
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
let filter = []
|
||||
Object.keys(this.list).map(e => {
|
||||
this.list[e].map(p => {
|
||||
if (p.merchandiseNumber > 0) {
|
||||
filter.push(p)
|
||||
}
|
||||
})
|
||||
})
|
||||
uni.navigateTo({
|
||||
url: "/pages/supermarket/balance?category=" + JSON.stringify(filter)
|
||||
})
|
||||
},
|
||||
active(key) {
|
||||
const flag = key == this.idx
|
||||
return {
|
||||
borderLeft: flag ? '3px solid #1D58FE' : '',
|
||||
background: flag ? 'linear-gradient(270deg, #FFFFFF 0%, #FFFFFF 77%, #E7EAFA 100%)' : ''
|
||||
}
|
||||
},
|
||||
add(item, index) {
|
||||
this.list[this.idx][index]["merchandiseNumber"] = this.list[this.idx][index]["merchandiseNumber"] + 1
|
||||
this.$set(this.sortCountList, this.mark, this.list[this.idx]?.reduce((pre, curr) => {
|
||||
return (pre + curr.merchandiseNumber)
|
||||
}, 0))
|
||||
},
|
||||
less(item, index) {
|
||||
if (item.merchandiseNumber > 0) {
|
||||
this.list[this.idx][index]["merchandiseNumber"] = this.list[this.idx][index]["merchandiseNumber"] - 1
|
||||
this.$set(this.sortCountList, this.mark, this.list[this.idx]?.reduce((pre, curr) => {
|
||||
return (pre + curr.merchandiseNumber)
|
||||
}, 0))
|
||||
}
|
||||
},
|
||||
clickSort(key, index) {
|
||||
this.mark = index
|
||||
this.idx = key.toString()
|
||||
},
|
||||
parseObj(json) {
|
||||
return JSON.parse(json || '[]')[0]?.url
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post(`/app/appvillagerintegralmerchandise/listByIntegral`, null, {
|
||||
params: {
|
||||
areaId: this.user?.areaId
|
||||
}
|
||||
}).then(res => {
|
||||
if (res && res.data) {
|
||||
Object.keys(res.data).map(e => {
|
||||
res.data[e].map(p => {
|
||||
p.merchandiseNumber = 0
|
||||
})
|
||||
})
|
||||
this.list = res.data
|
||||
this.idx = Object.keys(res.data)[0]
|
||||
this.sortCountList = Array(Object.keys(res.data).length).fill(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
uni-page-body {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.supermarket {
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 104px;
|
||||
|
||||
.nav-left {
|
||||
width: 168px;
|
||||
height: 100%;
|
||||
|
||||
.nav-left-item {
|
||||
height: 104px;
|
||||
background: #FAF9FB;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
color: #333333;
|
||||
border-top: 1px solid #D8E5FF;
|
||||
border-left: 2px solid transparent;
|
||||
position: relative;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 1px solid #D8E5FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-right {
|
||||
width: calc(100% - 168px - 24px);
|
||||
height: 100%;
|
||||
|
||||
.category-item {
|
||||
height: 264px;
|
||||
box-sizing: border-box;
|
||||
padding: 28px 32px 44px 30px;
|
||||
display: flex;
|
||||
|
||||
.category-img {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
border: 1px solid #F6F6F6;
|
||||
flex-shrink: 0;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.category-info {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
& > label {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
color: #333333;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.score {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
color: #FA4A51;
|
||||
line-height: 40px;
|
||||
|
||||
& > span {
|
||||
font-size: 24px;
|
||||
color: #FA4A51;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.lxc-count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.less {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.num {
|
||||
width: 89px;
|
||||
height: 61px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F6F6F6;
|
||||
border-radius: 10px;
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #333333;
|
||||
margin: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
z-index: 100;
|
||||
height: 104px;
|
||||
box-shadow: 0px -2px 8px 0px rgba(214, 214, 214, 0.5);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
.sum {
|
||||
width: calc(100% - 212px);
|
||||
box-sizing: border-box;
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
& > span:nth-child(1), span:nth-child(2) {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #F94246;
|
||||
|
||||
& > span {
|
||||
font-size: 24px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 212px;
|
||||
height: 100%;
|
||||
background-color: #1365DD;
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
284
src/mods/AppSupermarket/balance.vue
Normal file
284
src/mods/AppSupermarket/balance.vue
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div class="balance">
|
||||
<div class="operate">
|
||||
<div class="target">结算对象</div>
|
||||
<div class="select" @click="handleSelect">
|
||||
{{
|
||||
selected
|
||||
? `${selected.familyName}家 剩余积分:${selected.familyIntegral}分`
|
||||
: '请选择'
|
||||
}}
|
||||
<u-icon name="arrow-right" color="#E2E2E2" size="28"></u-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="line" :style="{ backgroundImage: 'url(' + uri + ')' }"></div>
|
||||
|
||||
<scroll-view scroll-y class="category-wrap">
|
||||
<div
|
||||
class="category-item"
|
||||
v-for="(item, index) in categoryList"
|
||||
:key="index"
|
||||
>
|
||||
<img class="category-img" :src="parseObj(item.photo)" alt=""/>
|
||||
<div class="category-info">
|
||||
<label class="hidden">{{ item.merchandiseName }}</label>
|
||||
<span class="score"
|
||||
>{{ item.costIntegral }}
|
||||
<span>积分</span>
|
||||
</span>
|
||||
<div class="wrap">×{{ item.merchandiseNumber }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</scroll-view>
|
||||
<div class="footer">
|
||||
<div class="sum">
|
||||
<span>共{{ totalCount }}件商品</span>
|
||||
<span
|
||||
>合计:{{ totalScore }}
|
||||
<span>积分</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="btn" @click="hanldeSubmit">确认领取</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'balance',
|
||||
data() {
|
||||
return {
|
||||
selected: null,
|
||||
categoryList: [],
|
||||
totalScore: 0,
|
||||
totalCount: 0
|
||||
}
|
||||
},
|
||||
onLoad(opt) {
|
||||
if (opt.category) {
|
||||
let sum = 0
|
||||
let count = 0
|
||||
this.categoryList = JSON.parse(opt.category)
|
||||
this.categoryList.map(e => {
|
||||
count += e.merchandiseNumber
|
||||
if (e.merchandiseNumber != 0) {
|
||||
sum += e.merchandiseNumber * e.costIntegral
|
||||
}
|
||||
})
|
||||
this.totalScore = sum
|
||||
this.totalCount = count
|
||||
}
|
||||
uni.$on('selected', data => {
|
||||
if (data) {
|
||||
this.selected = data
|
||||
}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
uri() {
|
||||
return this.$cdn + 'other/' + 'line.png'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseObj(json) {
|
||||
return JSON.parse(json || '[]')[0]?.url
|
||||
},
|
||||
hanldeSubmit() {
|
||||
if (!this.selected)
|
||||
return uni.showToast({
|
||||
title: '请选择结算对象',
|
||||
icon: 'none'
|
||||
})
|
||||
let {memberId, familyId} = this.selected
|
||||
this.$instance
|
||||
.post(`/app/appvillagerintegralshoporder/addOrder`, {
|
||||
shopId: this.categoryList[0].shopId,
|
||||
memberId,
|
||||
familyId,
|
||||
orderIntegral: this.totalScore,
|
||||
merchandiseList: this.categoryList.map(e => {
|
||||
return {
|
||||
...e,
|
||||
merchandiseId: e.id
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code == 0) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/supermarket/components/resultPage/resultPage'
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
'/pages/supermarket/components/resultPage/resultPage?flag=' +
|
||||
false
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
uni.showToast({
|
||||
title: e || '网络异常',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
},
|
||||
handleSelect() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/supermarket/search'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.balance {
|
||||
min-height: 100%;
|
||||
background-color: #ffffff;
|
||||
|
||||
.operate {
|
||||
height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 30px;
|
||||
|
||||
.target {
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
|
||||
&:before {
|
||||
content: '*';
|
||||
font-size: 32px;
|
||||
color: #ff4466;
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
font-size: 32px;
|
||||
color: #666666;
|
||||
|
||||
& > i {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
// margin: 0 30px;
|
||||
padding: 0 15px;
|
||||
height: 8px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.category-wrap {
|
||||
padding: 16px 0 110px;
|
||||
|
||||
.category-item {
|
||||
box-sizing: border-box;
|
||||
padding: 28px 32px 44px 30px;
|
||||
height: 264px;
|
||||
display: flex;
|
||||
|
||||
.category-img {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
border: 1px solid #f6f6f6;
|
||||
flex-shrink: 0;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.category-info {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
& > label {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
color: #333333;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.score {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
color: #fa4a51;
|
||||
|
||||
& > span {
|
||||
font-size: 24px;
|
||||
color: #fa4a51;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
z-index: 100;
|
||||
height: 104px;
|
||||
box-shadow: 0px -2px 8px 0px rgba(214, 214, 214, 0.5);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
.sum {
|
||||
width: calc(100% - 212px);
|
||||
box-sizing: border-box;
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
& > span:nth-child(1),
|
||||
span:nth-child(2) {
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
color: #f94246;
|
||||
|
||||
& > span {
|
||||
font-size: 24px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 212px;
|
||||
height: 100%;
|
||||
background-color: #1365dd;
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
117
src/mods/AppSupermarket/search.vue
Normal file
117
src/mods/AppSupermarket/search.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<div class="search-wrap">
|
||||
<u-search :show-action="false" placeholder="请输入手机号或身份证号搜索" v-model.trim="keyword" @search="search"></u-search>
|
||||
</div>
|
||||
<div class="result-body">
|
||||
<div class="res-item" v-if="result" @click="selected">
|
||||
<span>{{ result.familyName }}家</span>
|
||||
<span>剩余积分:{{ result.familyIntegral }}分</span>
|
||||
</div>
|
||||
<span class="placeholder" v-else>请通过搜索“
|
||||
<strong>手机号或身份证号</strong>
|
||||
”后选择结算对象
|
||||
</span>
|
||||
</div>
|
||||
<u-modal v-model="show" title="温馨提示" @confirm="confirm" content="该手机号绑定了多个居民,请通过身份证号进行查询"
|
||||
:confirm-style="{fontWeight:800}"></u-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "search",
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
show: false,
|
||||
result: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selected() {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
success: () => {
|
||||
uni.$emit('selected', this.result)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
search() {
|
||||
if (this.keyword == "") {
|
||||
return uni.showToast({
|
||||
title: "请输入搜索关键字",
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
this.$instance.post(`/app/appresident/queryFamilyByPhone`, null, {
|
||||
params: {
|
||||
phone: this.keyword
|
||||
}
|
||||
}).then(res => {
|
||||
if (res && res.data) {
|
||||
this.result = res.data
|
||||
}
|
||||
}).catch(e => {
|
||||
this.result = null
|
||||
uni.showToast({
|
||||
title: e,
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
},
|
||||
confirm() {
|
||||
this.show = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
min-height: 100%;
|
||||
background-color: #ffffff;
|
||||
|
||||
.search-wrap {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 24px 32px;
|
||||
}
|
||||
|
||||
.result-body {
|
||||
|
||||
.res-item {
|
||||
height: 112px;
|
||||
border-bottom: 1px solid #F5F5F5;
|
||||
box-sizing: border-box;
|
||||
padding: 0 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
& > span {
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 144px;
|
||||
font-size: 28px;
|
||||
color: #999999;
|
||||
|
||||
& > strong {
|
||||
color: #135AB8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
240
src/mods/AppTopic/AppTopic.vue
Normal file
240
src/mods/AppTopic/AppTopic.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="news">
|
||||
<div class="header">
|
||||
<div class="header-search">
|
||||
<u-icon name="search" class="icon-search" size="40" color="rgba(255,255,255,0.5)"></u-icon>
|
||||
<input placeholder="请输入标题" v-model="title" @confirm="onConfirm" confirm-type="search"
|
||||
placeholder-style="color:rgba(255,255,255,0.5);">
|
||||
</div>
|
||||
</div>
|
||||
<div class="topic-list">
|
||||
<div class="topic-item" v-for="(item, index) in list" :key="index" hover-class="bg-hover"
|
||||
@click="$linkTo(`./detail?id=${item.id}`)">
|
||||
<div class="topic-item__left">
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item.publishTime }}</p>
|
||||
</div>
|
||||
<image :src="item.thumbUrl" mode="aspectFill"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loading">
|
||||
<u-loadmore :status="loadingStatus"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"AppTopic",
|
||||
appName:"热点话题",
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
isLoading: false,
|
||||
list: [],
|
||||
isShowEmpty: false,
|
||||
isMore: false,
|
||||
current: 0,
|
||||
areaId: '',
|
||||
loadingStatus: 'loadmore'
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.areaId = uni.getStorageSync('areaId')
|
||||
this.getList(uni.getStorageSync('areaId'))
|
||||
},
|
||||
|
||||
methods: {
|
||||
onConfirm() {
|
||||
this.loadingStatus = 'loadmore'
|
||||
this.current = 0
|
||||
this.$loading()
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList(this.areaId)
|
||||
})
|
||||
},
|
||||
|
||||
getList(areaId) {
|
||||
if (this.loadingStatus === 'loading' || this.loadingStatus === 'nomore') return
|
||||
|
||||
this.loadingStatus = 'loading'
|
||||
this.$instance.post(`/app/apphotsubject/listForWx?current=${this.current + 1}&size=10&status=1&title=${this.title}`, null, {
|
||||
withoutToken: 1
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
if (this.current === 0) {
|
||||
this.list = []
|
||||
}
|
||||
|
||||
const data = res.data.records
|
||||
this.list.push(...data)
|
||||
this.current = this.current + 1
|
||||
this.loadingStatus = 'loadmore'
|
||||
if (!res.data.records.length || res.data.records.length < 10) {
|
||||
this.loadingStatus = 'nomore'
|
||||
}
|
||||
} else {
|
||||
this.loadingStatus = 'loadmore'
|
||||
}
|
||||
}).catch(() => {
|
||||
this.loadingStatus = 'loadmore'
|
||||
})
|
||||
},
|
||||
|
||||
toDetail(id) {
|
||||
this.$linkTo(`./newsDetail?id=${id}&areaId=${this.areaId}`)
|
||||
}
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
this.getList(this.areaId)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.news {
|
||||
min-height: 100vh;
|
||||
background: #F3F6F9;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.topic-item {
|
||||
display: flex;
|
||||
width: 686px;
|
||||
height: 208px;
|
||||
margin: 32px auto 0;
|
||||
padding: 32px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
.topic-item__left {
|
||||
flex: 1;
|
||||
margin-right: 32px h2 {
|
||||
height: 88px;
|
||||
line-height: 44px;
|
||||
margin-bottom: 16px;
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
text-align: justify;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
flex-shrink: 1;
|
||||
width: 192px;
|
||||
height: 144px;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.noMore {
|
||||
line-height: 90px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.topic-list {
|
||||
padding-top: 112px;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 11;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
padding: 20px 0 0 0;
|
||||
background: #4181FF;
|
||||
|
||||
.header-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 690px;
|
||||
height: 60px;
|
||||
margin: 0 auto8px;
|
||||
padding: 032px;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
border-radius: 30px;
|
||||
|
||||
.icon-search {
|
||||
flex-shrink: 1;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.header-tab {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 80px;
|
||||
padding-top: 16px;
|
||||
background: #2D80FB;
|
||||
|
||||
span {
|
||||
margin-right: 50px;
|
||||
padding-bottom: 24px;
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
border-bottom: 4px solid transparent;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #fff;
|
||||
border-bottom: 4px solid #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-more {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
|
||||
image {
|
||||
width: 400px;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
204
src/mods/AppTopic/detail.vue
Normal file
204
src/mods/AppTopic/detail.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div class="topic-detail" v-if="pageShow">
|
||||
<div class="topic-header">
|
||||
<h2>{{ info.title }}</h2>
|
||||
<p>{{ info.publishTime }}</p>
|
||||
<div class="topic-tags">
|
||||
<span v-for="(item, index) in info.keyWords" :key="index">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topic-list">
|
||||
<div class="topic-item" v-for="(item, index) in info.contents" :key="index">
|
||||
<div class="topic-item__top">
|
||||
<image src="/static/img/rmht.png"/>
|
||||
<div class="topic-item__top--right">
|
||||
<h2>{{ item.question }}</h2>
|
||||
<p>{{ item.questionSource }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topic-item__bottom">
|
||||
<h2 v-if="item.answerSource">
|
||||
<span style="color:#000;"> {{ item.answerSource }} </span>
|
||||
回复
|
||||
</h2>
|
||||
<h2 v-else>话题回复</h2>
|
||||
<p>{{ item.answer }}</p>
|
||||
<div class="topic-item__img">
|
||||
<image v-for="(img, i) in item.files" :key="i" :src="img.url" mode="aspectFill" hover-class="text-hover"
|
||||
@click="preview(img.url, item.files)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
info: {},
|
||||
id: '',
|
||||
pageShow: false
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(query) {
|
||||
this.$loading()
|
||||
this.id = query.id
|
||||
this.getInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo() {
|
||||
this.$instance.post(`/app/apphotsubject/detailForWx?id=${this.id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
if (res.data.keyWords) {
|
||||
this.info.keyWords = res.data.keyWords.split(',')
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
this.$hideLoading()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
preview(img, imgs) {
|
||||
uni.previewImage({
|
||||
current: img,
|
||||
urls: imgs.map(v => v.url)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.info.title,
|
||||
path: `/mods/AppTopic/detail?id=${this.id}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topic-detail {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.topic-list {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.topic-item__bottom {
|
||||
margin-top: 22px;
|
||||
padding: 24px 24px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #D8DDE6;
|
||||
|
||||
.topic-item__img {
|
||||
margin-top: 16px;
|
||||
font-size: 0;
|
||||
|
||||
image {
|
||||
width: 206px;
|
||||
height: 206px;
|
||||
margin: 0 10px 10px 0;
|
||||
border-radius: 8px;
|
||||
|
||||
&:nth-of-type(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 16px;
|
||||
color: #1365DD;
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-item {
|
||||
margin-bottom: 16px;
|
||||
padding: 32px;
|
||||
background: #fff;
|
||||
|
||||
.topic-item__top--right {
|
||||
flex: 1;
|
||||
|
||||
h2 {
|
||||
line-height: 1.3;
|
||||
margin-bottom: 16px;
|
||||
font-size: 32px;
|
||||
color: #333;
|
||||
text-align: justify;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #343D65;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.topic-item__top {
|
||||
display: flex;
|
||||
|
||||
image {
|
||||
position: relative;
|
||||
top: 6px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topic-header {
|
||||
padding: 32px 32px 16px;
|
||||
background: #FFFFFF;
|
||||
border-bottom: 1px solid #D8DDE6;
|
||||
|
||||
.topic-tags {
|
||||
font-size: 0;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
margin: 0 16px 16px 0;
|
||||
padding: 016px;
|
||||
color: #6179A7;
|
||||
font-size: 28px;
|
||||
background: #F4F5FA;
|
||||
border-radius: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
line-height: 1.3;
|
||||
margin-bottom: 16px;
|
||||
font-size: 40px;
|
||||
color: #333333;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
color: #999999;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
src/mods/AppVillageInfo/AppVillageInfo.vue
Normal file
229
src/mods/AppVillageInfo/AppVillageInfo.vue
Normal file
@@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="village-info">
|
||||
<div class="header-content">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/villgroup/group.png" alt="" class="group-img">
|
||||
<div class="group-name">{{ info.areaName || '' }}</div>
|
||||
<p>已有{{ info.peopleNum || 0 }}户居民</p>
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/villgroup/head.png" alt="" class="banner-img">
|
||||
<div class="qrcode-content">
|
||||
<img :src="info.codeUrl" class="qrcode-img">
|
||||
<div>用微信或政务微信扫码加入</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="user-content">
|
||||
<div class="title">联村政干</div>
|
||||
<div class="item">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/villgroup/group.png" alt="" class="user-img">
|
||||
<div class="user-info">
|
||||
<div class="item-line20 flex-b">
|
||||
<div>余国明<span class="item-position">(组长)</span></div>
|
||||
<div class="item-type">在岗</div>
|
||||
</div>
|
||||
<div class="item-line18 flex-b">
|
||||
<div>上街组、建新组、后街组</div>
|
||||
<div>13617896755</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "AppVillageInfo",
|
||||
appName: "一村一码",
|
||||
computed: {
|
||||
...mapState(['user', 'token'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
areaId: '',
|
||||
info: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (uni.getStorageSync('areaId')) {
|
||||
this.areaId = uni.getStorageSync('areaId')
|
||||
}
|
||||
this.getDetail()
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.$instance.post(`/app/appeveryvillagecode/queryDetailByAreaId?areaId=${this.areaId}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '一村一码',
|
||||
path: `/mods/AppVillageInfo/AppVillageInfo`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../common/common.scss";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding-top: 30px;
|
||||
background-color: #f3f6f9;
|
||||
|
||||
.village-info {
|
||||
padding-bottom: 48px;
|
||||
|
||||
.header-content {
|
||||
padding: 40px 70px 56px;
|
||||
width: 690px;
|
||||
background: #FFF;
|
||||
border-radius: 16px;
|
||||
margin: 0 0 24px 30px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.group-img {
|
||||
width: 92px;
|
||||
height: 96px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.group-name {
|
||||
font-size: 36px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 50px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
line-height: 34px;
|
||||
margin-bottom: 38px;
|
||||
}
|
||||
|
||||
.banner-img {
|
||||
width: 100%;
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.qrcode-content {
|
||||
width: 100%;
|
||||
height: 592px;
|
||||
background: #F6F9FF;
|
||||
border-radius: 12px;
|
||||
border: 2px solid #E6EEFF;
|
||||
padding: 56px 66px;
|
||||
box-sizing: border-box;
|
||||
margin-top: -8px;
|
||||
|
||||
.qrcode-img {
|
||||
width: 420px;
|
||||
height: 420px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
div {
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #333;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-content {
|
||||
padding: 16px 30px 64px;
|
||||
width: 690px;
|
||||
background: #FFF;
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
margin-left: 30px;
|
||||
|
||||
.title {
|
||||
line-height: 80px;
|
||||
padding-left: 10px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
padding: 28px 0 30px 0;
|
||||
border-bottom: 2px solid #D8DDE6;
|
||||
|
||||
.user-img {
|
||||
display: inline-block;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.user-name-bg {
|
||||
display: inline-block;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
line-height: 72px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background-color: #4E8EEE;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: inline-block;
|
||||
width: calc(100% - 72px);
|
||||
padding-left: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.flex-b {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item-line20 {
|
||||
line-height: 40px;
|
||||
font-size: 28px;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.item-position {
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.item-type {
|
||||
padding: 010px;
|
||||
background: #E8EFFF;
|
||||
color: #2266FF;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-line18 {
|
||||
line-height: 36px;
|
||||
color: #666;
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
466
src/mods/party/AppOnlineAnswer/AppOnlineAnswer.vue
Normal file
466
src/mods/party/AppOnlineAnswer/AppOnlineAnswer.vue
Normal file
@@ -0,0 +1,466 @@
|
||||
<template>
|
||||
<section class="AppOnlineAnswer">
|
||||
<div class="page" v-if="list.length">
|
||||
<img src="./static/img/answer-bg.png" alt="" class="bg-img">
|
||||
<div class="subject-content" v-if="!showAnwser">
|
||||
<div class="btn" v-if="showTopBtn" @click="confirm()">{{ topBtnText }}</div>
|
||||
<div class="bg-fff pad-b48">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<span class="tips"></span>{{ list[index].type == 1 ? '单选' : '多选' }}题
|
||||
</div>
|
||||
<div class="right">
|
||||
<span class="big-num">{{ index + 1 }}</span>/{{ list.length }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text">{{ list[index].title }}</div>
|
||||
<!-- 单选 -->
|
||||
<div v-if="list[index].type == 1">
|
||||
<div class="item" v-for="(item, i) in list[index].items" :key="i" @click="itemClick(i)"
|
||||
:class="{ 'item-click': clickIndex === i, 'item-success': showAnalysis && item.checked == 1, 'item-error': showAnalysis && clickIndex == i && item.checked == 0}">
|
||||
<img src="./static/img/success-icon.png" alt="" v-if="showAnalysis && item.checked == 1">
|
||||
<img src="./static/img/error-icon.png" alt=""
|
||||
v-if="showAnalysis && clickIndex == i && item.checked == 0">
|
||||
{{ item.sort }} {{ item.content }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- 多选 -->
|
||||
<div v-if="list[index].type == 2">
|
||||
<div class="item" v-for="(item, i) in list[index].items" :key="i" @click="itemClick(i)"
|
||||
:class="{ 'item-click': item.isCheked, 'item-success': showAnalysis && item.checked == 1, 'item-error': showAnalysis && item.isCheked && item.checked == 0}">
|
||||
<img src="./static/img/success-icon.png" alt="" v-if="showAnalysis && item.checked == 1">
|
||||
<img src="./static/img/error-icon.png" alt=""
|
||||
v-if="showAnalysis && clickIndex == i && item.checked == 0">
|
||||
{{ item.sort }} {{ item.content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="item item-click">A. 吴起镇</div>
|
||||
<div class="item item-success"> <img src="./static/img/success-icon.png" alt="">吴起镇</div>
|
||||
<div class="item item-error"> <img src="./static/img/error-icon.png" alt="">吴起镇</div>
|
||||
<div class="item">A. 吴起镇</div> -->
|
||||
</div>
|
||||
<div class="bg-fff mar-t32" v-if="showAnalysis">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<span class="tips"></span>答案解析
|
||||
</div>
|
||||
</div>
|
||||
<div class="success-title">正确答案:{{ list[index].answer }}</div>
|
||||
<div class="success-text">
|
||||
<u-parse :html="list[index].analysis"></u-parse>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="subject-content" v-else>
|
||||
<div class="bg-fff pad-b48">
|
||||
<img src="./static/img/answer-head.png" alt="" class="head-img">
|
||||
<div class="head-content">
|
||||
<p>本次答对题目数</p>
|
||||
<div>{{ resultInfo.right }}</div>
|
||||
</div>
|
||||
<div class="info-content">
|
||||
<span class="info-item">正确率: {{ resultInfo.rate }}</span>
|
||||
<span class="info-item">用时: {{ useTime }}</span>
|
||||
<span class="info-item mar-b132">错题数: {{ resultInfo.wrong }}</span>
|
||||
</div>
|
||||
<span class="big-btn mar-r22" @click="back">返回</span>
|
||||
<span class="big-btn bg-red" @click="again">再来一组</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="list.length == 0"/>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AppOnlineAnswer",
|
||||
appName: "在线答题",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAnwser: false,
|
||||
index: 0,
|
||||
clickIndex: '',
|
||||
list: [],
|
||||
showTopBtn: false,
|
||||
topBtnText: '',
|
||||
showAnalysis: false,
|
||||
createdTime: '',
|
||||
endTime: '',
|
||||
useTime: '',
|
||||
resultInfo: {}
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.createdTime = Date.parse(new Date())
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
itemClick(i) {
|
||||
if (this.showAnalysis) return
|
||||
|
||||
if (this.list[this.index].type == 1) { //单选
|
||||
this.clickIndex = i
|
||||
this.showTopBtn = true
|
||||
}
|
||||
if (this.list[this.index].type == 2) { //多选
|
||||
this.showTopBtn = false
|
||||
this.list[this.index].items[i].isCheked = !this.list[this.index].items[i].isCheked
|
||||
this.list[this.index].items.map((item) => {
|
||||
if (item.isCheked) {
|
||||
this.showTopBtn = true
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
this.topBtnText = '确定'
|
||||
},
|
||||
confirm() {
|
||||
if (this.list[this.index].type == 1) { //单选
|
||||
this.list[this.index].result = this.list[this.index].items[this.clickIndex].sort
|
||||
}
|
||||
if (this.list[this.index].type == 2) { //多选
|
||||
var resultList = []
|
||||
this.list[this.index].items.map((item) => {
|
||||
if (item.isCheked) {
|
||||
resultList.push(item.sort)
|
||||
}
|
||||
})
|
||||
this.list[this.index].result = resultList.join(',')
|
||||
}
|
||||
|
||||
console.log(this.list)
|
||||
|
||||
|
||||
if (this.topBtnText == '下一题') { //next
|
||||
if (this.index < this.list.length - 1) {
|
||||
this.index++
|
||||
this.init()
|
||||
} else { //答完了
|
||||
this.showTopBtn = false
|
||||
this.endTime = Date.parse(new Date());
|
||||
this.useTime = this.intervalTime(this.endTime - this.createdTime)
|
||||
this.getResult()
|
||||
}
|
||||
}
|
||||
if (this.topBtnText == '确定') { //确定选项
|
||||
this.showAnalysis = true
|
||||
this.topBtnText = '下一题'
|
||||
}
|
||||
},
|
||||
getResult() {
|
||||
this.$instance.post(`/app/apppartyquestion/checkAnswer`, this.list).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.resultInfo = res.data
|
||||
this.showAnwser = true
|
||||
}
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
this.$instance.post(`/app/apppartyquestion/getQuestions`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
res.data.map((item) => {
|
||||
item.answerList = []
|
||||
item.items.map((i) => {
|
||||
if (i.checked == 1) {
|
||||
item.answerList.push(i.sort)
|
||||
}
|
||||
})
|
||||
item.answer = item.answerList.join(',')
|
||||
|
||||
if (item.type == 2) { //多选
|
||||
item.isCheck = false
|
||||
}
|
||||
})
|
||||
this.list = res.data
|
||||
}
|
||||
});
|
||||
},
|
||||
intervalTime(time) {
|
||||
var leave1 = time % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
|
||||
var hours = Math.floor(leave1 / (3600 * 1000));
|
||||
hours = hours < 10 ? '0' + hours : hours
|
||||
var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
|
||||
var minutes = Math.floor(leave2 / (60 * 1000));
|
||||
minutes = minutes < 10 ? '0' + minutes : minutes
|
||||
var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
|
||||
var seconds = Math.round(leave3 / 1000);
|
||||
seconds = seconds < 10 ? '0' + seconds : seconds
|
||||
return hours + ":" + minutes + ":" + seconds
|
||||
},
|
||||
back() {
|
||||
uni.navigateBack({delta: 1})
|
||||
},
|
||||
again() {
|
||||
this.init()
|
||||
this.index = 0
|
||||
this.list = []
|
||||
this.getList()
|
||||
this.createdTime = Date.parse(new Date())
|
||||
},
|
||||
init() {
|
||||
this.showAnwser = false
|
||||
this.clickIndex = ''
|
||||
this.showTopBtn = false
|
||||
this.topBtnText = ''
|
||||
this.showAnalysis = false
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.AppOnlineAnswer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #F6F6F6;
|
||||
|
||||
.bg-img {
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
.subject-content {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 24px 36px 48px 36px;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 124px;
|
||||
z-index: 9;
|
||||
|
||||
.btn {
|
||||
padding: 0 30px;
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
text-align: center;
|
||||
background: #D03A28;
|
||||
border-radius: 4px;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FFF;
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
right: 36px;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.pad-top {
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
.pad-b48 {
|
||||
padding-bottom: 48px;
|
||||
}
|
||||
|
||||
.mar-t32 {
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.bg-fff {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 6px 8px 4px rgba(218, 227, 234, 0.42);
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-bottom: 1px solid #F2F3F5;
|
||||
padding: 24px 30px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.left {
|
||||
font-size: 36px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
line-height: 50px;
|
||||
|
||||
.tips {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 36px;
|
||||
background: #E02617;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #999;
|
||||
line-height: 48px;
|
||||
|
||||
.big-num {
|
||||
font-size: 72px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
padding: 48px 40px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 612px;
|
||||
background: #FAFBFC;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #F2F3F5;
|
||||
margin-bottom: 28px;
|
||||
margin-left: 32px;
|
||||
padding: 26px 48px;
|
||||
box-sizing: border-box;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #687178;
|
||||
line-height: 44px;
|
||||
|
||||
img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
margin-right: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-click {
|
||||
background: #F5F5F2;
|
||||
border: 1px solid #AD9B8D;
|
||||
color: #B7A38E;
|
||||
}
|
||||
|
||||
.item-success {
|
||||
background: #E9FAF0;
|
||||
border: 1px solid #E9FAF0;
|
||||
color: #40BF6F;
|
||||
}
|
||||
|
||||
.item-error {
|
||||
background: #FDEBEB;
|
||||
border: 1px solid #FDEBEB;
|
||||
color: #D03A28;
|
||||
}
|
||||
|
||||
.success-title {
|
||||
padding: 32px 0 0 40px;
|
||||
font-size: 32px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
}
|
||||
|
||||
.success-text {
|
||||
padding: 32px 40px 56px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.head-img {
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
.head-content {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 56px 0 0 72px;
|
||||
box-sizing: border-box;
|
||||
|
||||
p {
|
||||
font-size: 38px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FBE5E6;
|
||||
line-height: 52px;
|
||||
}
|
||||
|
||||
div {
|
||||
font-size: 100px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #FBE5E6;
|
||||
line-height: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-content {
|
||||
padding: 88px 32px 40px;
|
||||
|
||||
.info-item {
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
line-height: 48px;
|
||||
margin-bottom: 42px;
|
||||
}
|
||||
|
||||
.mar-b132 {
|
||||
margin-bottom: 132px;
|
||||
}
|
||||
}
|
||||
|
||||
.big-btn {
|
||||
display: inline-block;
|
||||
width: 296px;
|
||||
height: 88px;
|
||||
line-height: 88px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #E4E5E7;
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.bg-red {
|
||||
border: 0;
|
||||
background: #D03A28;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mar-r22 {
|
||||
margin: 0 22px 0 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
src/mods/party/AppOnlineAnswer/static/img/answer-bg.png
Normal file
BIN
src/mods/party/AppOnlineAnswer/static/img/answer-bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
src/mods/party/AppOnlineAnswer/static/img/answer-head.png
Normal file
BIN
src/mods/party/AppOnlineAnswer/static/img/answer-head.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
BIN
src/mods/party/AppOnlineAnswer/static/img/error-icon.png
Normal file
BIN
src/mods/party/AppOnlineAnswer/static/img/error-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/mods/party/AppOnlineAnswer/static/img/success-icon.png
Normal file
BIN
src/mods/party/AppOnlineAnswer/static/img/success-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
389
src/mods/party/AppPartyHistory/AppPartyHistory.vue
Normal file
389
src/mods/party/AppPartyHistory/AppPartyHistory.vue
Normal file
@@ -0,0 +1,389 @@
|
||||
<template>
|
||||
<section class="AppPartyHistory">
|
||||
<div v-if="isShow" style="height: 100%">
|
||||
<!-- 头部搜索样式 -->
|
||||
<div class="fixed-top" style="width:100%;">
|
||||
<div class="search-box">
|
||||
<div class="search-input flex-row" @click="changeSearchBox">
|
||||
<img src="https://cdn.cunwuyun.cn/img/search-red.svg"/>
|
||||
<span class="color-fff">请输入文章标题</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 选择时间和类型 -->
|
||||
<div class="slect flex-row">
|
||||
<!-- 类型选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker @change="bindPickerChange" :value="index" :range="array" range-key="dictName">
|
||||
<div class="uni-input">{{ partyType }}</div>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg"/>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
mode="date"
|
||||
:value="date"
|
||||
:start="startDate"
|
||||
:end="endDate"
|
||||
@change="bindDateChange"
|
||||
fields="month"
|
||||
>
|
||||
<div class="uni-input">{{ day }}</div>
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg"/>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 党务公开列表 -->
|
||||
<div class="affairs-list">
|
||||
<div class="affairs" v-if="affairsList.length > 0">
|
||||
<!-- 循环 v-for -->
|
||||
<div v-for="(item, index) in affairsList" :key="index">
|
||||
<div class="affairs-item" @click="getDetail(item.id)">
|
||||
<div class="break-word">
|
||||
<span class="type">{{ $dict.getLabel(`partyHistoryType${style}`, item.type) }}</span>
|
||||
<span class="affirs-title">{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="created-unit flex-row">
|
||||
<span>{{ item.organizationName || "" }}</span>
|
||||
<span>{{ item.createDate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="affairsList.length == 0"/>
|
||||
</div>
|
||||
<div v-if="!isShow" class="search-input">
|
||||
<div class="input-box flex-row">
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
placeholder="请输入文章标题"
|
||||
focus="false"
|
||||
v-model="searchValue"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
<img
|
||||
class="sousuo"
|
||||
src="https://cdn.cunwuyun.cn/img/search-active.svg"
|
||||
/>
|
||||
<img
|
||||
v-if="searchValue"
|
||||
@tap="clearInput"
|
||||
class="clear"
|
||||
src="https://cdn.cunwuyun.cn/img/empty-Input.svg"
|
||||
/>
|
||||
<div class="search-word" @click="search">搜索</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AppPartyHistory",
|
||||
appName: "党史文章",
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true,
|
||||
});
|
||||
return {
|
||||
inputValue: "请输入文章标题",
|
||||
isShow: true,
|
||||
array: [],
|
||||
index: 0,
|
||||
partyType: "类型",
|
||||
partyTypeIndex: "", //类型index 0:党务公开,1:三会一课
|
||||
date: currentDate,
|
||||
day: "时间",
|
||||
createData: "", //创建时间
|
||||
affairsList: [],
|
||||
searchValue: "", //搜索框输入值
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pages: 2,
|
||||
style: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startDate() {
|
||||
return this.getDate("start");
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate("end");
|
||||
},
|
||||
...mapState(["user"]),
|
||||
},
|
||||
onLoad(option) {
|
||||
this.style = option.style
|
||||
this.$dict.load("partyHistoryType0", "partyHistoryType1", "partyHistoryType2").then(() => {
|
||||
this.array = this.$dict.getDict(`partyHistoryType${this.style}`)
|
||||
this.array.unshift({dictName: "全部类型", dictValue: ""})
|
||||
this.getPartyList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
bindPickerChange(e) {
|
||||
this.partyType = this.array[e.detail.value].dictName;
|
||||
this.partyTypeIndex = this.array[e.detail.value].dictValue;
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getPartyList();
|
||||
},
|
||||
bindDateChange: function (e) {
|
||||
this.day = e.target.value;
|
||||
this.createData =
|
||||
e.target.value + "-" + "08" + " " + "00" + ":" + "00" + ":" + "00";
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getPartyList();
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === "start") {
|
||||
year = year - 60;
|
||||
} else if (type === "end") {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : "0" + month;
|
||||
day = day > 9 ? day : "0" + day;
|
||||
|
||||
return `${year}-${month}-08 00:00:00 `;
|
||||
},
|
||||
changeSearchBox() {
|
||||
this.isShow = false;
|
||||
},
|
||||
onBlur(e) {
|
||||
this.searchValue = e.target.value;
|
||||
|
||||
if (this.searchValue) {
|
||||
this.inputValue = this.searchValue;
|
||||
} else {
|
||||
this.inputValue = "请输入文章标题";
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.isShow = true;
|
||||
this.pageNum = 1;
|
||||
this.pageSize = 10;
|
||||
this.pages = 2;
|
||||
this.getPartyList();
|
||||
},
|
||||
clearInput() {
|
||||
this.searchValue = "";
|
||||
this.inputValue = "请输入文章标题";
|
||||
},
|
||||
getDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: `./detail?id=${id}`,
|
||||
});
|
||||
},
|
||||
getPartyList() {
|
||||
if (this.pageNum > this.pages) return;
|
||||
this.$instance.post(`/app/apppartyhistory/listWechat`, {
|
||||
condition: this.searchValue,
|
||||
style: this.style,
|
||||
type: this.partyTypeIndex,
|
||||
createDate: this.createData,
|
||||
current: this.pageNum,
|
||||
size: this.pageSize,
|
||||
// organizationId: this.user.partyOrgId
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
const affairsList = this.pageNum > 1 ? [...this.affairsList, ...res.data.records] : res.data.records;
|
||||
this.pages = Math.ceil(res.data.total / 10);
|
||||
this.affairsList = affairsList;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.pageNum = this.pageNum + 1;
|
||||
this.getPartyList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.AppPartyHistory {
|
||||
.search-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search-input {
|
||||
line-height: 64px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ce0010;
|
||||
// background:rgba(0,0,0,1);
|
||||
border-radius: 32px;
|
||||
// opacity: 0.1;
|
||||
color: #f0cbcd;
|
||||
font-size: 26px;
|
||||
|
||||
img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 8px 8px 8px 24px;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.color-fff {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slect {
|
||||
width: 100%;
|
||||
height: 96px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.type-slect {
|
||||
width: 50%;
|
||||
border-right: 1px solid #f7f7f7;
|
||||
margin: 30px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
|
||||
.uni-input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.type-slect:nth-child(2) {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.affairs-list {
|
||||
width: 100%;
|
||||
// height:calc(100% - 210px);
|
||||
// overflow-y: auto;
|
||||
padding-top: 200px;
|
||||
|
||||
.affairs {
|
||||
background-color: #fff;
|
||||
margin: 32px;
|
||||
|
||||
.affairs-item {
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.type {
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
background-color: #e6edf7;
|
||||
color: #135ab8;
|
||||
font-size: 26px;
|
||||
margin-right: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.affirs-title {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.created-unit {
|
||||
font-size: 28px;
|
||||
color: #999;
|
||||
justify-content: space-between;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-affairs {
|
||||
width: 100%;
|
||||
height: calc(100% - 210px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
// width:100%;
|
||||
// height:112px;
|
||||
.input-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #fff;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.sousuo {
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 60px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.input {
|
||||
background-color: #f3f3f3;
|
||||
width: 598px;
|
||||
height: 64px;
|
||||
color: #999999;
|
||||
font-size: 26px;
|
||||
margin-left: 8px;
|
||||
border-radius: 32px;
|
||||
padding-left: 70px;
|
||||
padding-right: 60px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.clear {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 130px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.search-word {
|
||||
font-size: 28px;
|
||||
color: #135ab8;
|
||||
line-height: 60px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
147
src/mods/party/AppPartyHistory/commentList.vue
Normal file
147
src/mods/party/AppPartyHistory/commentList.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div>
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="commentList"
|
||||
@scrolltolower="page.current++, getComments()"
|
||||
>
|
||||
<div class="comments-list" v-if="commentList.length">
|
||||
<div
|
||||
class="comments-item flex-row"
|
||||
v-for="(item, i) in commentList"
|
||||
:key="i"
|
||||
>
|
||||
<div class="user-avatar">
|
||||
<image v-if="item.avatar" :src="item.avatar"></image>
|
||||
<image v-else src="https://cdn.cunwuyun.cn/img/personal.png"></image>
|
||||
</div>
|
||||
<div class="content flex-column">
|
||||
<div class="flex-row" style="justify-content: space-between">
|
||||
<text>{{ item.createUser }}</text>
|
||||
<text class="commentTime">{{ item.commentTime }}</text>
|
||||
</div>
|
||||
<div>{{ item.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-else/>
|
||||
<view class="tips" v-if="commentList.length"> 已加载全部评论</view>
|
||||
</scroll-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "commentList",
|
||||
props: {
|
||||
detail: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
commentList: [],
|
||||
page: {
|
||||
current: 1,
|
||||
size: 10000,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getComments() {
|
||||
this.$instance.post(`/app/apppartyhistorycomment/list?partyHistoryId=${this.detail.id}&size=10000`).then((res) => {
|
||||
if (res && res.data) {
|
||||
this.commentList = res.data.records;
|
||||
this.$emit("comments", res.data.total);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => this.getComments());
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.commentList {
|
||||
width: 100%;
|
||||
margin-bottom: 135px;
|
||||
overflow-y: auto;
|
||||
|
||||
.comments-list {
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
|
||||
.user-avatar {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
margin: 46px 20px 0 0;
|
||||
|
||||
image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-bg {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
background-color: #26f;
|
||||
color: #fff;
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.comments-item {
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
padding: 0 32px;
|
||||
color: #333;
|
||||
font-size: 28px;
|
||||
background-color: #fff;
|
||||
|
||||
& + .comments-item {
|
||||
border-top: 4px solid #eee;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
width: calc(100% - 120px);
|
||||
background-color: #fff;
|
||||
padding: 46px 0 32px 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.name {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.commentTime {
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips {
|
||||
line-height: 90px;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
background-color: #f3f6f9;
|
||||
}
|
||||
|
||||
.no-comment-list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
280
src/mods/party/AppPartyHistory/detail.vue
Normal file
280
src/mods/party/AppPartyHistory/detail.vue
Normal file
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div>
|
||||
<div v-if="!showCommentList" class="detail">
|
||||
<!-- 文章标题 -->
|
||||
<div class="created-unit">
|
||||
<div class="artical-title break-word">{{ affairs.title }}</div>
|
||||
<div class="artical-unit">
|
||||
<span> 发布党组织 :{{ affairs.organizationName || "-" }}</span>
|
||||
</div>
|
||||
<div class="artical-unit">
|
||||
<text>发布时间:{{ affairs.createDate }}</text>
|
||||
<text/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 文章内容 -->
|
||||
<div class="artical-content break-word">
|
||||
<u-parse :html="affairs.content" class="content" v-if="affairs.content"></u-parse>
|
||||
</div>
|
||||
<!-- 语音播报-->
|
||||
<AiTransSpeech :src="affairs.speech" v-if="affairs.speech"/>
|
||||
</div>
|
||||
<commentList v-else :detail="affairs"></commentList>
|
||||
<AiComment
|
||||
:comment-count="commentCount"
|
||||
@submitComment="submitComment"
|
||||
@showCommentList="showCommentList = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import commentList from './commentList'
|
||||
|
||||
export default {
|
||||
name: "policyDetail",
|
||||
components: {commentList},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
affairs: {},
|
||||
showCommentList: false,
|
||||
commentCount: 0,
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.$dict.load("policyPromotionType");
|
||||
this.id = options.id;
|
||||
this.getPartyAffairsDetail(this.id);
|
||||
this.getCount();
|
||||
},
|
||||
methods: {
|
||||
getCount() {
|
||||
this.$instance.post(`/app/apppartyhistorycomment/list?partyHistoryId=${this.id}`).then((res) => {
|
||||
if (res && res.data) {
|
||||
this.commentCount = res.data.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
getPartyAffairsDetail(id) {
|
||||
this.$instance.post(`/app/apppartyhistory/queryDetailByIdWeChat?id=${id}`).then((res) => {
|
||||
if (res && res.data) {
|
||||
res.data.createDate = res.data.createDate.substring(0, 10);
|
||||
const regex = new RegExp("<img", "gi");
|
||||
res.data.content = res.data.content
|
||||
.replace(
|
||||
regex,
|
||||
`<img style="max-width:100%!important;" calss="img"`
|
||||
)
|
||||
.replace(/<p([\s\w"=\/\.:;]+)((?:(class="[^"]+")))/gi, "<p")
|
||||
.replace(/<p>/gi, '<p class="p_class">')
|
||||
.replace(/style=""/g, 'style="max-width:100%!important;"');
|
||||
res.data.content = res.data.content.replace(
|
||||
/<img[^>]*>/gi,
|
||||
function (match) {
|
||||
return match.replace(
|
||||
/style\s*?=\s*?([‘"])[\s\S]*?\1/gi,
|
||||
'style="max-width:100%;"'
|
||||
); // 替换style
|
||||
}
|
||||
);
|
||||
|
||||
if (res.data.files && res.data.files.length) {
|
||||
res.data.files.map(item => {
|
||||
var size = item.size / 1024;
|
||||
item.fileSize = size.toFixed(0);
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
this.affairs = {...res.data};
|
||||
}
|
||||
});
|
||||
},
|
||||
back() {
|
||||
if (getCurrentPages().length === 1) {
|
||||
uni.switchTab({
|
||||
url: "/pages/home/home",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.showCommentList
|
||||
? (this.showCommentList = false)
|
||||
: uni.navigateBack();
|
||||
},
|
||||
submitComment(content) {
|
||||
this.$instance
|
||||
.post("/app/apppartyhistorycomment/addOrUpdate", {
|
||||
partyHistoryId: this.affairs.id,
|
||||
content: content,
|
||||
name: this.user.nickName,
|
||||
avatar: this.user.avatarUrl,
|
||||
organizationId: this.affairs.organizationId
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.code == 0) {
|
||||
uni.showToast({icon: "success", title: "评论成功"});
|
||||
this.showCommentList = true
|
||||
this.getCount()
|
||||
} else {
|
||||
uni.showToast({icon: "none", title: res.msg});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.showToast({icon: "none", title: err});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
.navHeadBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #135ab8;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.created-unit {
|
||||
width: 100%;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
background-color: #D40A05;
|
||||
color: #fff;
|
||||
|
||||
.artical-title {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.artical-unit {
|
||||
font-size: 28px;
|
||||
margin-top: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.artical-content {
|
||||
color: #666666;
|
||||
font-size: 32px;
|
||||
padding: 32px 32px 128px 32px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
|
||||
.p_class {
|
||||
margin-top: 40px;
|
||||
font-size: 32px;
|
||||
color: #333;
|
||||
text-indent: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment {
|
||||
width: 100%;
|
||||
padding: 32px 32px 96px 32px;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
margin-top: 16px;
|
||||
|
||||
.attachment-title {
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
|
||||
image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.p_class {
|
||||
margin-top: 40px;
|
||||
font-size: 32px;
|
||||
color: #333;
|
||||
text-indent: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.attachment {
|
||||
width: 100%;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
background-color: #FFFFFF;
|
||||
margin-top: 16px;
|
||||
|
||||
.attachment-title {
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
|
||||
image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
border: 1px solid rgba(204, 204, 204, 1);
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
margin-top: 34px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
|
||||
.file-name {
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.size {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
display: flex;
|
||||
justify-content: cemter;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,335 @@
|
||||
<template>
|
||||
<section class="AppPartyHistoryEducation">
|
||||
<div class="page">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<span class="tips"></span>党史上的今天
|
||||
</div>
|
||||
<div class="right" @click="handleGoto('./todayList')">
|
||||
查看全部
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" class="right-icon">
|
||||
</div>
|
||||
</div>
|
||||
<div class="header" v-for="(item, index) in todayList" :key="index"
|
||||
@click="handleGoto(`./todayDetail?id=${item.id}`)">
|
||||
<img :src="item.thumbUrl[0].url" alt="" v-if="item.thumbUrl && item.thumbUrl.length">
|
||||
<p class="text">{{ item.title }}</p>
|
||||
<p class="time">{{ item.organizationName }} {{ item.publishDate || '' }}</p>
|
||||
</div>
|
||||
<AiEmpty v-if="todayList.length == 0"/>
|
||||
<div class="line-bg"></div>
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<span class="tips"></span>党史课堂
|
||||
</div>
|
||||
<div class="right" @click="handleGoto('./classroomList')">
|
||||
查看全部
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" class="right-icon">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="tab-item" v-for="(item, index) in classList" :key="index"
|
||||
@click="handleGoto(`./videoDetail?id=${item.id}`)">
|
||||
<img :src="item.thumbUrl[0].url" alt="" v-if="item.thumbUrl && item.thumbUrl.length">
|
||||
<p>{{ item.title }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="classList.length == 0"/>
|
||||
<div class="line-bg"></div>
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<span class="tips"></span>党史知识
|
||||
</div>
|
||||
<div class="right" @click="handleGoto('./knowledgeList?type=knowledge')">
|
||||
查看全部
|
||||
<img src="https://cdn.cunwuyun.cn/img/down.svg" class="right-icon">
|
||||
</div>
|
||||
</div>
|
||||
<div class="new-list">
|
||||
<div class="list-content">
|
||||
<div class="bg-fff" v-for="(item, index) in knowledgeList" :key="index"
|
||||
@click="handleGoto(`./todayDetail?type=know&id=${item.id}`)">
|
||||
<div class="item">
|
||||
<div class="info">
|
||||
<p>{{ item.title }}</p>
|
||||
<span>{{ item.organizationName }} {{ item.createDate }}</span>
|
||||
</div>
|
||||
<img :src="item.thumbUrl[0].url" alt="" v-if="item.thumbUrl && item.thumbUrl.length"/>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="knowledgeList.length == 0"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "AppPartyHistoryEducation",
|
||||
appName: "党史教育",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
todayList: [],
|
||||
classList: [],
|
||||
knowledgeList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getTodayList()
|
||||
this.getClassList()
|
||||
this.getKnowledgeList()
|
||||
},
|
||||
methods: {
|
||||
getTodayList() {
|
||||
this.$instance.post(`/app/apppartyeducation/list?style=2&size=1&status=1`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data && res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
if (item.thumbUrl) {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
}
|
||||
if (item.publishDate) {
|
||||
item.publishDate = item.publishDate.substring(0, 10)
|
||||
}
|
||||
})
|
||||
this.todayList = res.data.records
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getClassList() {
|
||||
this.$instance.post(`/app/apppartyclassroom/list?size=3&status=1`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data && res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
})
|
||||
this.classList = res.data.records
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getKnowledgeList() {
|
||||
this.$instance.post(`/app/apppartyeducation/list?style=0&size=4&status=1`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data && res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
if (item.thumbUrl) {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
}
|
||||
if (item.createDate) {
|
||||
item.createDate = item.createDate.substring(0, 10)
|
||||
}
|
||||
})
|
||||
this.knowledgeList = res.data.records
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleGoto(url) {
|
||||
uni.navigateTo({url});
|
||||
},
|
||||
toNewDetail(id) {
|
||||
this.handleGoto(`/pages/party/partyHistory/detail?id=${id}`);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.AppPartyHistoryEducation {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
padding: 28px 16px 28px 28px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.tips {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 32px;
|
||||
background: #E02617;
|
||||
vertical-align: middle;
|
||||
margin-right: 18px;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
float: right;
|
||||
vertical-align: middle;
|
||||
transform: rotate(270deg);
|
||||
padding: 0 8px 0 0;
|
||||
}
|
||||
|
||||
.left {
|
||||
font-size: 34px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
.right {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 34px 40px 34px;
|
||||
|
||||
img {
|
||||
width: 684px;
|
||||
height: 252px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 16px;
|
||||
height: 96px;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.line-bg {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background: #F2F2F2;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 0 0 40px 30px;
|
||||
overflow-x: hidden;
|
||||
height: 236px;
|
||||
width: 800px;
|
||||
|
||||
.tab-item {
|
||||
float: left;
|
||||
width: 236px;
|
||||
height: 236px;
|
||||
background: #FFF;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.12);
|
||||
border-radius: 8px;
|
||||
margin-right: 16px;
|
||||
|
||||
img {
|
||||
width: 236px;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 12px 8px 0;
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 36px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.new-list {
|
||||
background-color: #fff;
|
||||
|
||||
.list-content {
|
||||
.bg-fff {
|
||||
padding: 0 30px;
|
||||
border-top: 1px solid #ddd;
|
||||
|
||||
.item {
|
||||
padding: 24px 0 32px 0;
|
||||
border-bottom: 2px solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
// width: 410px;
|
||||
p {
|
||||
// width: 410px;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 46px;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 52px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 224px;
|
||||
height: 168px;
|
||||
margin-left: 56px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.view-more {
|
||||
background-color: #fff;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #c50000;
|
||||
line-height: 40px;
|
||||
padding: 30px 0 40px 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
114
src/mods/party/AppPartyHistoryEducation/classroomList.vue
Normal file
114
src/mods/party/AppPartyHistoryEducation/classroomList.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<section class="home">
|
||||
<div class="page">
|
||||
<div class="item" v-for="(item, index) in classList" :key="index" @click.stop="toDetail(item.id)">
|
||||
<img :src="item.thumbUrl[0].url" alt="" class="banner-img">
|
||||
<img src="https://cdn.cunwuyun.cn/dvcp/pay-btn.png" alt="" class="play-img">
|
||||
<p>{{ item.title }}</p>
|
||||
<div>{{ item.organizationName }} {{ item.createDate }}</div>
|
||||
</div>
|
||||
<AiEmpty v-if="classList.length == 0"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current: 1,
|
||||
pages: 2,
|
||||
classList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getClassList()
|
||||
},
|
||||
methods: {
|
||||
getClassList() {
|
||||
if (this.current > this.pages) return;
|
||||
this.$instance.post(`/app/apppartyclassroom/list?size=10&status=1¤t=${this.current}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data && res.data.records) {
|
||||
res.data.records.map((item) => {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
item.createDate = item.createDate.substring(0, 10)
|
||||
})
|
||||
const classList = this.current > 1 ? [...this.classList, ...res.data.records] : res.data.records
|
||||
this.pages = Math.ceil(res.data.total / 10)
|
||||
this.classList = classList
|
||||
this.classList = res.data.records
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetail(id) {
|
||||
uni.navigateTo({url: `./videoDetail?id=${id}`})
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current = this.current + 1
|
||||
this.getClassList()
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 416px;
|
||||
// background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.banner-img {
|
||||
width: 100%;
|
||||
height: 416px;
|
||||
}
|
||||
|
||||
.play-img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
position: absolute;
|
||||
top: 148px;
|
||||
left: 334px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 20px 32px;
|
||||
width: 686px;
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 0 0 34px 32px;
|
||||
font-size: 22px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #999;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
111
src/mods/party/AppPartyHistoryEducation/detail.vue
Normal file
111
src/mods/party/AppPartyHistoryEducation/detail.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<section class="home">
|
||||
<div class="page">
|
||||
<div class="header">
|
||||
<p class="title">{{ info.title }}</p>
|
||||
<div class="info mar-b16"><span class="label">发布单位:</span><span class="value">{{ info.organizationName }}</span>
|
||||
</div>
|
||||
<div class="info">发布时间:{{ info.publishDate || info.createDate }}</div>
|
||||
|
||||
</div>
|
||||
<div class="content">
|
||||
<u-parse :html="info.content"></u-parse>
|
||||
</div>
|
||||
<AiTransSpeech :src="info.speech" v-if="info.speech"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
info: {},
|
||||
content: ''
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = options.id
|
||||
this.getDetail()
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.$instance.post(`/app/apppartyhistory/queryDetailByIdWeChat?id=${this.id}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data.publishDate) {
|
||||
res.data.publishDate = res.data.publishDate.substring(0, 10)
|
||||
}
|
||||
if (res.data.createDate) {
|
||||
res.data.createDate = res.data.createDate.substring(0, 10)
|
||||
}
|
||||
this.info = res.data
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
padding: 24px 32px 32px;
|
||||
box-sizing: border-box;
|
||||
background: #D03A28;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FFF;
|
||||
line-height: 64px;
|
||||
letter-spacing: 1px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #FFF;
|
||||
line-height: 40px;
|
||||
|
||||
.label {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: calc(100% - 140px);
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b16 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
320
src/mods/party/AppPartyHistoryEducation/knowledgeList.vue
Normal file
320
src/mods/party/AppPartyHistoryEducation/knowledgeList.vue
Normal file
@@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div style="height: 100%">
|
||||
<div class="fixed-top">
|
||||
<!-- 选择时间和类型 -->
|
||||
<div class="slect flex-row">
|
||||
<!-- 类型选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
@change="bindPickerChange"
|
||||
:range="array"
|
||||
range-key="dictName"
|
||||
>
|
||||
<div class="uni-input">{{ styleText }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
mode="date"
|
||||
:value="date"
|
||||
:start="startDate"
|
||||
:end="endDate"
|
||||
@change="bindDateChange"
|
||||
fields="month"
|
||||
>
|
||||
<div class="uni-input">{{ day }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session-list">
|
||||
<div class="session-item" v-for="(item, index) in meetList" :key="index" @click="toDetail(item.id)">
|
||||
<div class="info">
|
||||
<p v-if="fromType != 'style'"><span
|
||||
:class="item.style == 0 ? 'status0' : 'status1'">{{
|
||||
item.style == 0 ? '党史知识' : '党史图书馆'
|
||||
}}</span>{{ item.title }}
|
||||
</p>
|
||||
<p v-else><span class="status0">{{
|
||||
$dict.getLabel(`partyHistoryType${optionStyle}`, item.type)
|
||||
}}</span>{{ item.title }}</p>
|
||||
<span class="time">{{ item.organizationName }} {{ item.createDate }}</span>
|
||||
</div>
|
||||
<div class="img" v-if="item.thumbUrl && item.thumbUrl.length">
|
||||
<img :src="item.thumbUrl[0].url" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="meetList.length == 0"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true,
|
||||
});
|
||||
return {
|
||||
array: [],
|
||||
partyStudyType: "",
|
||||
date: currentDate,
|
||||
day: "时间",
|
||||
createDate: "", //创建时间
|
||||
meetList: [],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pages: 2,
|
||||
fromType: '', //style 0、党建要闻 1、政策解读 knowledge 党史知识 policy 党史图书馆
|
||||
style: '4',
|
||||
styleText: '类型',
|
||||
optionStyle: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startDate() {
|
||||
return this.getDate("start");
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate("end");
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
console.log(options)
|
||||
if (options.type == 'knowledge') {
|
||||
this.array = [{dictName: "全部类型", dictValue: "4"}, {dictName: "党史知识 ", dictValue: 0}, {
|
||||
dictName: "党史图书馆",
|
||||
dictValue: 1
|
||||
}]
|
||||
}
|
||||
if (options.type == 'style') {
|
||||
this.style = ''
|
||||
this.optionStyle = options.style
|
||||
this.$dict.load("partyHistoryType0", "partyHistoryType1").then(() => {
|
||||
this.array = this.$dict.getDict(`partyHistoryType${options.style}`)
|
||||
this.array.unshift({dictName: "全部类型", dictValue: ""})
|
||||
})
|
||||
}
|
||||
|
||||
this.fromType = options.type
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
bindPickerChange(e) {
|
||||
console.log(e)
|
||||
this.style = this.array[e.detail.value].dictValue
|
||||
if (this.style === '') {
|
||||
this.styleText = '类型'
|
||||
} else {
|
||||
this.styleText = this.array[e.detail.value].dictName
|
||||
}
|
||||
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
bindDateChange(e) {
|
||||
this.day = e.target.value;
|
||||
this.createDate = e.target.value;
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === "start") {
|
||||
year = year - 60;
|
||||
} else if (type === "end") {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : "0" + month;
|
||||
day = day > 9 ? day : "0" + day;
|
||||
|
||||
return `${year}-${month}-08 00:00:00 `;
|
||||
},
|
||||
|
||||
search() {
|
||||
this.pageNum = 1;
|
||||
this.pageSize = 10;
|
||||
this.pages = 2;
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
if (this.pageNum > this.pages) return;
|
||||
|
||||
var createDate = ''
|
||||
if (this.createDate) {
|
||||
createDate = this.createDate + '-01'
|
||||
}
|
||||
this.$instance.post(`/app/apppartyeducation/list?size=10¤t=${this.pageNum}&createDateParam=${createDate}&style=${this.style}&status=1`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
res.data.records.map((item) => {
|
||||
if (item.thumbUrl) {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
}
|
||||
if (item.createDate) {
|
||||
item.createDate = item.createDate.substring(0, 10)
|
||||
}
|
||||
})
|
||||
const meetList = this.pageNum > 1 ? [...this.meetList, ...res.data.records] : res.data.records
|
||||
this.pages = Math.ceil(res.data.total / 10)
|
||||
this.meetList = meetList
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: "./todayDetail?type=know&id=" + id,
|
||||
});
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.pageNum = this.pageNum + 1;
|
||||
this.getList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
.search-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slect {
|
||||
width: 100%;
|
||||
height: 96px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.type-slect {
|
||||
width: 50%;
|
||||
border-right: 1px solid #f7f7f7;
|
||||
margin: 30px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
|
||||
.uni-input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin-left: 8 spx;
|
||||
}
|
||||
}
|
||||
|
||||
.type-slect:nth-child(2) {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.session-list {
|
||||
padding-top: 112px;
|
||||
|
||||
.session-item {
|
||||
width: 686px;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto 32px auto;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
|
||||
.info {
|
||||
p {
|
||||
height: 88px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 24px;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
line-height: 44px;
|
||||
margin-right: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.status0 {
|
||||
color: #2266FF;
|
||||
background-color: #E8EFFF;
|
||||
}
|
||||
|
||||
.status1 {
|
||||
color: #FF8822;
|
||||
background-color: #FFF3E9;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
padding-left: 24px;
|
||||
|
||||
img {
|
||||
width: 192px;
|
||||
height: 144px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-affairs {
|
||||
width: 100%;
|
||||
height: calc(100% - 210px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
330
src/mods/party/AppPartyHistoryEducation/list.vue
Normal file
330
src/mods/party/AppPartyHistoryEducation/list.vue
Normal file
@@ -0,0 +1,330 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div style="height: 100%">
|
||||
<div class="fixed-top">
|
||||
<!-- 选择时间和类型 -->
|
||||
<div class="slect flex-row">
|
||||
<!-- 类型选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
@change="bindPickerChange"
|
||||
:range="array"
|
||||
range-key="dictName"
|
||||
>
|
||||
<div class="uni-input">{{ styleText }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
mode="date"
|
||||
:value="date"
|
||||
:start="startDate"
|
||||
:end="endDate"
|
||||
@change="bindDateChange"
|
||||
fields="month"
|
||||
>
|
||||
<div class="uni-input">{{ day }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session-list">
|
||||
<div class="session-item" v-for="(item, index) in meetList" :key="index" @click="toDetail(item.id)">
|
||||
<div class="info">
|
||||
<p v-if="fromType != 'style'"><span
|
||||
:class="item.style == 0 ? 'status0' : 'status1'">{{
|
||||
item.style == 0 ? '党史知识' : '党史图书馆'
|
||||
}}</span>{{ item.title }}
|
||||
</p>
|
||||
<p v-else><span class="status0">{{
|
||||
$dict.getLabel(`partyHistoryType${optionStyle}`, item.type)
|
||||
}}</span>{{ item.title }}</p>
|
||||
<span class="time">{{ item.organizationName }} {{ item.createDate }}</span>
|
||||
</div>
|
||||
<div class="img" v-if="item.thumbUrl && item.thumbUrl.length">
|
||||
<img :src="item.thumbUrl[0].url" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="meetList.length == 0"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true,
|
||||
});
|
||||
return {
|
||||
array: [],
|
||||
partyStudyType: "",
|
||||
date: currentDate,
|
||||
day: "时间",
|
||||
createDate: "", //创建时间
|
||||
meetList: [],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pages: 2,
|
||||
fromType: '', //style 0、党建要闻 1、政策解读 knowledge 党史知识 policy 党史图书馆
|
||||
style: '',
|
||||
styleText: '类型',
|
||||
optionStyle: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startDate() {
|
||||
return this.getDate("start");
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate("end");
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
console.log(options)
|
||||
if (options.type == 'knowledge') {
|
||||
this.array = [{dictName: "全部类型", dictValue: "0|1"}, {dictName: "党史知识 ", dictValue: 0}, {
|
||||
dictName: "党史图书馆",
|
||||
dictValue: 1
|
||||
}]
|
||||
}
|
||||
if (options.type == 'style') {
|
||||
this.style = ''
|
||||
this.optionStyle = options.style
|
||||
this.$dict.load("partyHistoryType0", "partyHistoryType1").then(() => {
|
||||
this.array = this.$dict.getDict(`partyHistoryType${options.style}`)
|
||||
this.array.unshift({dictName: "全部类型", dictValue: ""})
|
||||
})
|
||||
}
|
||||
|
||||
this.fromType = options.type
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
bindPickerChange(e) {
|
||||
console.log(e)
|
||||
this.style = this.array[e.detail.value].dictValue
|
||||
if (this.style === '') {
|
||||
this.styleText = '类型'
|
||||
} else {
|
||||
this.styleText = this.array[e.detail.value].dictName
|
||||
}
|
||||
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
bindDateChange(e) {
|
||||
this.day = e.target.value;
|
||||
this.createDate = e.target.value;
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === "start") {
|
||||
year = year - 60;
|
||||
} else if (type === "end") {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : "0" + month;
|
||||
day = day > 9 ? day : "0" + day;
|
||||
|
||||
return `${year}-${month}-08 00:00:00 `;
|
||||
},
|
||||
|
||||
search() {
|
||||
this.pageNum = 1;
|
||||
this.pageSize = 10;
|
||||
this.pages = 2;
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
if (this.pageNum > this.pages) return;
|
||||
|
||||
var createDate = ''
|
||||
if (this.createDate) {
|
||||
createDate = this.createDate + '-01 00:00:00'
|
||||
}
|
||||
this.$instance.post(`/app/apppartyhistory/listWechat`, {
|
||||
style: this.fromType == 'style' ? this.optionStyle : this.style,
|
||||
type: this.style,
|
||||
createDate: createDate,
|
||||
current: this.pageNum,
|
||||
size: this.pageSize,
|
||||
status: 1
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
res.data.records.map((item) => {
|
||||
if (item.thumbUrl) {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
}
|
||||
if (item.createDate) {
|
||||
item.createDate = item.createDate.substring(0, 10)
|
||||
}
|
||||
})
|
||||
const meetList = this.pageNum > 1 ? [...this.meetList, ...res.data.records] : res.data.records
|
||||
this.pages = Math.ceil(res.data.total / 10)
|
||||
this.meetList = meetList
|
||||
// this.meetList.map((item) => {
|
||||
// item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
// })
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: "./detail?id=" + id,
|
||||
});
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.pageNum = this.pageNum + 1;
|
||||
this.getList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
.search-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slect {
|
||||
width: 100%;
|
||||
height: 96px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.type-slect {
|
||||
width: 50%;
|
||||
border-right: 1px solid #f7f7f7;
|
||||
margin: 30px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
|
||||
.uni-input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin-left: 8 spx;
|
||||
}
|
||||
}
|
||||
|
||||
.type-slect:nth-child(2) {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.session-list {
|
||||
padding-top: 112px;
|
||||
|
||||
.session-item {
|
||||
width: 686px;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto 32px auto;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
|
||||
.info {
|
||||
p {
|
||||
height: 88px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
text-overflow: -o-ellipsis-lastline;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 24px;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
line-height: 44px;
|
||||
margin-right: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.status0 {
|
||||
color: #2266FF;
|
||||
background-color: #E8EFFF;
|
||||
}
|
||||
|
||||
.status1 {
|
||||
color: #FF8822;
|
||||
background-color: #FFF3E9;
|
||||
}
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
padding-left: 24px;
|
||||
|
||||
img {
|
||||
width: 192px;
|
||||
height: 144px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-affairs {
|
||||
width: 100%;
|
||||
height: calc(100% - 210px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
84
src/mods/party/AppPartyHistoryEducation/select.vue
Normal file
84
src/mods/party/AppPartyHistoryEducation/select.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<section class="home">
|
||||
<div class="page">
|
||||
<p class="title">点击进入月份</p>
|
||||
<div class="tab-content">
|
||||
<span v-for="(item, index) in tabList" :key="index" class="tab-item" :class="tabIndex == index ? 'active' : ''"
|
||||
@click="back(index)">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabList: ['全部', '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
|
||||
tabIndex: 0,
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.tabIndex = options.index
|
||||
},
|
||||
methods: {
|
||||
back(index) {
|
||||
this.tabIndex = index
|
||||
uni.setStorageSync('partyTabIndex', this.tabIndex)
|
||||
uni.navigateBack({delta: 1})
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
padding: 32px 0 40px 30px;
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #B9B9B9;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding-left: 30px;
|
||||
|
||||
.tab-item {
|
||||
display: inline-block;
|
||||
width: 144px;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
border-radius: 24px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #CBCBCB;
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
margin: 0 38px 32px 0;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #DA2D1A;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
115
src/mods/party/AppPartyHistoryEducation/todayDetail.vue
Normal file
115
src/mods/party/AppPartyHistoryEducation/todayDetail.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<section class="home">
|
||||
<div class="page">
|
||||
<div class="header">
|
||||
<p class="title">{{ info.title }}</p>
|
||||
<div class="info mar-b16"><span class="label">发布单位:</span><span class="value">{{ info.organizationName }}</span>
|
||||
</div>
|
||||
<div class="info" v-if="type == 'know'">发布时间:{{ info.createDate || '-' }}</div>
|
||||
<div class="info" v-else>发布时间:{{ info.publishDate || '-' }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<u-parse :html="info.content"></u-parse>
|
||||
</div>
|
||||
<AiTransSpeech :src="info.speech" v-if="info.speech"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
info: {},
|
||||
content: '',
|
||||
type: '', //know 党史知识
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
console.log(options)
|
||||
this.id = options.id
|
||||
this.type = options.type
|
||||
this.getDetail()
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
this.$instance.post(`/app/apppartyeducation/queryDetailById?id=${this.id}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data.createDate) {
|
||||
res.data.createDate = res.data.createDate.substring(0, 10)
|
||||
}
|
||||
if (res.data.publishDate) {
|
||||
res.data.publishDate = res.data.publishDate.substring(0, 10)
|
||||
}
|
||||
this.info = res.data
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
padding: 24px 32px 32px;
|
||||
box-sizing: border-box;
|
||||
background: #D03A28;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #FFF;
|
||||
line-height: 64px;
|
||||
letter-spacing: 1px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #FFF;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
|
||||
.label {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: calc(100% - 140px);
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b16 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
175
src/mods/party/AppPartyHistoryEducation/todayList.vue
Normal file
175
src/mods/party/AppPartyHistoryEducation/todayList.vue
Normal file
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<section class="home">
|
||||
<div class="page">
|
||||
<div class="tab-content">
|
||||
<span v-for="(item, index) in tabList" :key="index" class="tab-item" :class="tabIndex == index ? 'active' : ''"
|
||||
@click="timeSelect(index)">{{ item }}</span>
|
||||
<img src="https://cdn.cunwuyun.cn/img/party_detail.png" alt=""
|
||||
@click="handleGoto(`./select?index=${tabIndex}`)">
|
||||
</div>
|
||||
<div class="item" v-for="(item, index) in todayList" :key="index"
|
||||
@click="handleGoto(`./todayDetail?id=${item.id}`)">
|
||||
<div class="header">
|
||||
<img :src="item.thumbUrl[0].url" alt="" v-if="item.thumbUrl && item.thumbUrl.length"/>
|
||||
<p class="text">{{ item.title }}</p>
|
||||
<p class="time">{{ item.organizationName }} {{ item.publishDate || '' }}</p>
|
||||
</div>
|
||||
<div class="line-bg"></div>
|
||||
</div>
|
||||
<AiEmpty v-if="todayList.length == 0"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabList: ['全部', '一月', '二月', '三月', '四月', '五月'],
|
||||
tabIndex: 0,
|
||||
todayList: [],
|
||||
current: 1,
|
||||
pages: 2
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getTodayList();
|
||||
},
|
||||
onShow() {
|
||||
if (uni.getStorageSync('partyTabIndex')) {
|
||||
this.tabIndex = uni.getStorageSync('partyTabIndex')
|
||||
uni.setStorageSync('partyTabIndex', '')
|
||||
this.timeSelect(this.tabIndex);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTodayList() {
|
||||
if (this.current > this.pages) return;
|
||||
var publishDate = ''
|
||||
if (this.tabIndex > 0) {
|
||||
var myDate = new Date();
|
||||
var tYear = myDate.getFullYear();
|
||||
var month = this.tabIndex < 10 ? '0' + this.tabIndex : this.tabIndex
|
||||
publishDate = tYear + '-' + month + '-01'
|
||||
}
|
||||
this.$instance.post(`/app/apppartyeducation/list?style=2¤t=${this.current}&size=10&publishDate=${publishDate}&status=1`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data.records && res.data.records.length) {
|
||||
res.data.records.map((item) => {
|
||||
console.log(item.thumbUrl)
|
||||
if (item.thumbUrl) {
|
||||
item.thumbUrl = JSON.parse(item.thumbUrl)
|
||||
}
|
||||
if (item.publishDate) {
|
||||
item.publishDate = item.publishDate.substring(0, 10)
|
||||
}
|
||||
})
|
||||
const todayList = this.current > 1 ? [...this.todayList, ...res.data.records] : res.data.records
|
||||
this.pages = Math.ceil(res.data.total / 10)
|
||||
this.todayList = todayList
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleGoto(url) {
|
||||
uni.navigateTo({url})
|
||||
},
|
||||
timeSelect(index) {
|
||||
this.tabIndex = index
|
||||
this.current = 1
|
||||
this.pages = 2
|
||||
this.todayList = []
|
||||
this.getTodayList()
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
this.current = this.current + 1
|
||||
this.getTodayList()
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.tab-content {
|
||||
width: 100%;
|
||||
height: 84px;
|
||||
padding: 0 30px;
|
||||
box-sizing: border-box;
|
||||
background: #FCF0ED;
|
||||
|
||||
.tab-item {
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
line-height: 80px;
|
||||
height: 80px;
|
||||
margin-right: 48px;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #70737B;
|
||||
}
|
||||
|
||||
.active {
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #DA2D1A;
|
||||
border-bottom: 4px solid #DE2C19;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 0 34px;
|
||||
|
||||
img {
|
||||
width: 684px;
|
||||
height: 252px;
|
||||
margin: 32px 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 30px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.line-bg {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background: #f2f2f2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
199
src/mods/party/AppPartyHistoryEducation/videoDetail.vue
Normal file
199
src/mods/party/AppPartyHistoryEducation/videoDetail.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<section class="home" v-if="pageShow">
|
||||
<div class="page" v-if="videoList.length">
|
||||
<video :src="videoList[activeIndex].videoUrl" :id="`video${activeIndex+1}`"></video>
|
||||
<p class="video-name">{{ videoList[activeIndex].title }}</p>
|
||||
<div class="time">{{ info.organizationName }} {{ info.createDate }}</div>
|
||||
<div class="title">
|
||||
<span>选集</span>
|
||||
<p @click="show=true" v-if="videoList.length > 7">查看全部 ></p>
|
||||
</div>
|
||||
<div class="select page-select">
|
||||
<div class="item" :class="index == activeIndex ? 'active' : ''" v-for="(item, index) in videoList" :key="index"
|
||||
@click="activeIndex=index">{{ item.num }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">
|
||||
<span>内容简介</span>
|
||||
</div>
|
||||
<div class="detail-content">
|
||||
<u-parse :html="info.content"></u-parse>
|
||||
</div>
|
||||
<u-popup v-model="show" mode="bottom">
|
||||
<div class="title">
|
||||
<span>选集</span>
|
||||
</div>
|
||||
<div class="select pop-select">
|
||||
<div class="item" :class="index == activeIndex ? 'active' : ''" v-for="(item, index) in videoList"
|
||||
:key="index" @click="activeIndex=index;show=false">{{ item.num }}
|
||||
</div>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
<AiEmpty v-else/>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "home",
|
||||
computed: {
|
||||
...mapState(["user", "token"]),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
id: '',
|
||||
info: {},
|
||||
videoList: [],
|
||||
activeIndex: 0,
|
||||
pageShow: false
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = options.id
|
||||
this.getClassDetail()
|
||||
this.getVideoList()
|
||||
},
|
||||
methods: {
|
||||
change(index) {
|
||||
this.current = index;
|
||||
},
|
||||
getClassDetail() {
|
||||
this.$instance.post(`/app/apppartyclassroom/queryDetailById?id=${this.id}`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
res.data.createDate = res.data.createDate.substring(0, 10)
|
||||
this.info = res.data
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getVideoList() {
|
||||
this.$instance.post(`/app/apppartyclassroomepisode/list?classroomId=${this.id}&size=10000`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
console.log(res)
|
||||
if (res.data && res.data.records) {
|
||||
this.videoList = res.data.records
|
||||
this.pageShow = true
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 416px;
|
||||
}
|
||||
|
||||
.video-name {
|
||||
padding: 24px 32px 20px;
|
||||
width: 686px;
|
||||
font-size: 34px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 30px;
|
||||
margin-bottom: 32px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
padding: 0 32px 16px 32px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
font-size: 34px;
|
||||
font-family: PingFang-SC-Heavy, PingFang-SC;
|
||||
font-weight: 800;
|
||||
color: #333;
|
||||
line-height: 80px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 26px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
line-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.select {
|
||||
padding: 0 0 24px 32px;
|
||||
width: 800px;
|
||||
overflow-x: hidden;
|
||||
|
||||
.item {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
line-height: 96px;
|
||||
text-align: center;
|
||||
background: #F0F4FB;
|
||||
border-radius: 8px;
|
||||
float: left;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-right: 11px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #DA2D1A;
|
||||
}
|
||||
}
|
||||
|
||||
.page-select {
|
||||
height: 96px;
|
||||
padding-bottom: 0;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
padding: 0 32px;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: #333;
|
||||
line-height: 48px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pop-select {
|
||||
.item {
|
||||
margin: 0 22px 22px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
304
src/mods/party/AppPartyOrganization/AppPartyOrganization.vue
Normal file
304
src/mods/party/AppPartyOrganization/AppPartyOrganization.vue
Normal file
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<div class="AppPartyOrganization">
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
<div class="party-org">
|
||||
<div class="title">所在组织</div>
|
||||
<p class="org-select" @click="selectShow = true">{{ detail.name || '请选择' }}<img
|
||||
src="https://cdn.cunwuyun.cn/img/down.svg"/></p>
|
||||
</div>
|
||||
<div class="org-info">
|
||||
<div class="title">组织信息</div>
|
||||
<div class="flex-row">
|
||||
<span class="color-666">组织类型</span>
|
||||
<span class="color-333">{{ $dict.getLabel("orgType", detail.orgType) }}</span>
|
||||
</div>
|
||||
<div class="flex-row">
|
||||
<span class="color-666">组织级别</span>
|
||||
<span class="color-333">{{ $dict.getLabel("orgPartyType", detail.partyType) }}</span>
|
||||
</div>
|
||||
<div class="flex-row">
|
||||
<span class="color-666">党员人数</span>
|
||||
<span class="color-333">{{ count }}人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="org-info">
|
||||
<div class="flex-row">
|
||||
<span class="title">报到状态</span>
|
||||
<span :class="userInfo.reportOrgId ? 'status1' : 'status0'">{{ userInfo.reportOrgId ? '已报到' : '未报到' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<u-select v-model="selectShow" :list="treeData" @confirm="confirm"></u-select>
|
||||
<u-popup v-model="dialog" mode="center" border-radius="8">
|
||||
<div class="estateNotice">
|
||||
<b>您已加入过党组织,是否变更?</b>
|
||||
<u-gap height="40"/>
|
||||
<div class="curEstate">
|
||||
<div class="flexRow">
|
||||
<b>当前党组织:</b>
|
||||
<span>{{ detail.name }}</span>
|
||||
</div>
|
||||
<div class="flexRow">
|
||||
<b>当前报到状态:</b>
|
||||
<span
|
||||
:class="userInfo.reportOrgId ? 'status1' : 'status0'">{{ userInfo.reportOrgId ? '已报到' : '未报到' }}</span>
|
||||
</div>
|
||||
<div class="flexRow">
|
||||
<b>变更党组织:</b>
|
||||
<span>{{ changeOrgInfo.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<u-gap height="34"/>
|
||||
<div class="alert">变更党组织后需尽快前往新党组织报到</div>
|
||||
<u-gap height="62"/>
|
||||
<div class="flexRow footer">
|
||||
<div class="fill"/>
|
||||
<span @click="dialog=false">取消</span>
|
||||
<span @click="dialog=false,bindEstate()">确认</span>
|
||||
</div>
|
||||
</div>
|
||||
</u-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AppPartyOrganization",
|
||||
appName: "党组织",
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
detail: {},
|
||||
treeData: [],
|
||||
selectShow: false,
|
||||
reportOrgName: '', //报到党组织名称
|
||||
reportOrgId: '',
|
||||
changeOrgInfo: {},
|
||||
userInfo: {},
|
||||
count: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.$dict.load("orgType", "orgPartyType").then(() => {
|
||||
this.getUserInfo()
|
||||
})
|
||||
|
||||
},
|
||||
methods: {
|
||||
getUserInfo() {
|
||||
this.$instance.post("/app/appparty/chanhudetail").then(res => {
|
||||
if (res?.data) {
|
||||
if (res.data.reportOrgId) {
|
||||
this.reportOrgName = res.data.reportOrgName
|
||||
this.reportOrgId = res.data.reportOrgId
|
||||
} else {
|
||||
this.reportOrgName = res.data.partyOrgName
|
||||
this.reportOrgId = res.data.partyOrgId
|
||||
}
|
||||
this.userInfo = res.data
|
||||
this.getDetail()
|
||||
this.getTree()
|
||||
}
|
||||
})
|
||||
},
|
||||
getTree() {
|
||||
this.$instance.post(`/admin/partyOrganization/queryAllChildren?id=${this.userInfo.topOrgId}`).then(res => {
|
||||
if (res?.data) {
|
||||
res.data.map((item) => {
|
||||
item.label = item.name
|
||||
item.value = item.id
|
||||
})
|
||||
this.treeData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetail() {
|
||||
this.$instance.post(`/admin/partyOrganization/detail?id=${this.userInfo.reportOrgId}`).then(res => {
|
||||
if (res?.data) {
|
||||
this.detail = res.data
|
||||
this.count = res.data.memberCount.one || 0
|
||||
}
|
||||
})
|
||||
},
|
||||
confirm(e) {
|
||||
this.treeData.map((item) => {
|
||||
if (item.id == e[0].value) {
|
||||
this.changeOrgInfo = item
|
||||
}
|
||||
})
|
||||
this.dialog = true
|
||||
},
|
||||
bindEstate() {
|
||||
this.$instance.post("/app/apppartyreportorgchange/changeReportOrg", {
|
||||
orgId: this.changeOrgInfo.id,
|
||||
orgName: this.changeOrgInfo.name,
|
||||
partyId: this.userInfo.id,
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$toast('党组织变更成功')
|
||||
this.getUserInfo()
|
||||
this.$store.commit("getUserInfo")
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppPartyOrganization {
|
||||
height: 100%;
|
||||
padding-bottom: 112px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
height: 160px;
|
||||
background: #D7261E;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 686px;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 32px;
|
||||
|
||||
.party-org {
|
||||
padding: 32px;
|
||||
margin-bottom: 16px;
|
||||
background: #FFFFFF;
|
||||
|
||||
.title {
|
||||
font-size: 34px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
.org-select {
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
line-height: 42px;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.org-info {
|
||||
padding: 0 32px;
|
||||
background: #FFFFFF;
|
||||
margin-bottom: 16px;
|
||||
|
||||
div {
|
||||
line-height: 100px;
|
||||
font-size: 30px;
|
||||
border-bottom: 2px solid #eee;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
div:nth-last-of-type(1) {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.color-666 {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.color-333 {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.status0 {
|
||||
color: #FF8822;
|
||||
}
|
||||
|
||||
.status1 {
|
||||
color: #2EA222;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
::v-deep .estateNotice {
|
||||
width: 560px;
|
||||
background: #FFFFFF;
|
||||
padding: 48px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.status0 {
|
||||
color: #FF8822;
|
||||
}
|
||||
|
||||
.status1 {
|
||||
color: #2EA222;
|
||||
}
|
||||
|
||||
.curEstate {
|
||||
color: #666;
|
||||
font-size: 28px;
|
||||
|
||||
b {
|
||||
color: #333
|
||||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
color: #F14242;
|
||||
}
|
||||
|
||||
.footer {
|
||||
span {
|
||||
width: 128px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #1365DD;
|
||||
font-size: 28px;
|
||||
transform: translateX(32px);
|
||||
|
||||
& + span {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottomBtn {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
background: #D7261E;
|
||||
font-size: 32px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
485
src/mods/party/AppPartyStudy/AppPartyStudy.vue
Normal file
485
src/mods/party/AppPartyStudy/AppPartyStudy.vue
Normal file
@@ -0,0 +1,485 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div v-if="isShow" style="height: 100%">
|
||||
<div class="fixed-top">
|
||||
<!-- 头部搜索样式 -->
|
||||
<div class="search-box">
|
||||
<div class="search-input flex-row" @click="changeSearchBox">
|
||||
<image src="https://cdn.cunwuyun.cn/img/search-red.svg"></image>
|
||||
<span>{{ inputValue }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 选择时间和类型 -->
|
||||
<div class="slect flex-row">
|
||||
<!-- 类型选择 -->
|
||||
<div class="uni-list type-select">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
@change="bindPickerChange"
|
||||
:range="array"
|
||||
range-key="dictName"
|
||||
>
|
||||
<div class="uni-input" v-if="partyStudyType === ''">
|
||||
学习类别
|
||||
</div>
|
||||
<div class="uni-input" v-else>
|
||||
{{ array[partyStudyType + 1].dictName }}
|
||||
</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间选择 -->
|
||||
<div class="uni-list type-select">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker
|
||||
mode="date"
|
||||
:value="date"
|
||||
:start="startDate"
|
||||
:end="endDate"
|
||||
@change="bindDateChange"
|
||||
fields="month"
|
||||
>
|
||||
<div class="uni-input">{{ day }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session-list">
|
||||
<div
|
||||
class="session-item"
|
||||
v-for="(item, index) in meetList"
|
||||
:key="index"
|
||||
>
|
||||
<div class="item-top" @click="toDetail(item.id)">
|
||||
<div class="item-title mar-b12">{{ item.title }}</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">学习类别:</span>
|
||||
<span class="info-value">{{
|
||||
$dict.getLabel("partyStudyType", item.type)
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">发布时间:</span>
|
||||
<span class="info-value">{{ item.publishTime }}</span>
|
||||
</div>
|
||||
<div class="item-info mar-b12">
|
||||
<span class="info-label">发布人员:</span>
|
||||
<span class="info-value">{{ item.publishUserName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-status" :class="'item-status' + item.studyStatus">
|
||||
{{ $dict.getLabel("partyStudyStatus", item.studyStatus) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="meetList.length == 0"/>
|
||||
</div>
|
||||
<div v-if="!isShow" class="search-input">
|
||||
<div class="input-box flex-row">
|
||||
<input
|
||||
type="span"
|
||||
class="input"
|
||||
placeholder="请输入学习标题"
|
||||
focus="false"
|
||||
v-model="searchValue"
|
||||
@blur="onBlur"
|
||||
/>
|
||||
<image
|
||||
class="sousuo"
|
||||
src="https://cdn.cunwuyun.cn/img/search-active.svg"
|
||||
></image>
|
||||
<image
|
||||
v-if="searchValue"
|
||||
@tap="clearInput"
|
||||
class="clear"
|
||||
src="https://cdn.cunwuyun.cn/img/empty-Input.svg"
|
||||
></image>
|
||||
<div class="search-word" @click="search">搜索</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
appName: "党员学习",
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true,
|
||||
});
|
||||
return {
|
||||
inputValue: "请输入学习标题",
|
||||
isShow: true,
|
||||
array: [],
|
||||
meetType: "",
|
||||
partyStudyType: "",
|
||||
index: 0,
|
||||
date: currentDate,
|
||||
day: "时间",
|
||||
createDate: "", //创建时间
|
||||
meetList: [],
|
||||
searchValue: "", //搜索框输入值
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pages: 2,
|
||||
userId: "",
|
||||
partyId: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startDate() {
|
||||
return this.getDate("start");
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate("end");
|
||||
},
|
||||
},
|
||||
onLoad(options) {
|
||||
this.partyId = options.partyId;
|
||||
this.$dict.load("partyStudyStatus", "partyStudyType").then((res) => {
|
||||
this.array = this.$dict.getDict("partyStudyType");
|
||||
this.array.unshift({dictName: "全部类型", dictValue: ""})
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
onShow() {
|
||||
this.$dict.load("partyStudyStatus", "partyStudyType");
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
bindPickerChange(e) {
|
||||
if (e.detail.value - 1 >= 0) {
|
||||
this.partyStudyType = e.detail.value - 1;
|
||||
} else {
|
||||
this.partyStudyType = "";
|
||||
}
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
bindDateChange: function (e) {
|
||||
this.day = e.target.value;
|
||||
this.createDate = e.target.value;
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList();
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === "start") {
|
||||
year = year - 60;
|
||||
} else if (type === "end") {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : "0" + month;
|
||||
day = day > 9 ? day : "0" + day;
|
||||
|
||||
return `${year}-${month}-08 00:00:00 `;
|
||||
},
|
||||
changeSearchBox() {
|
||||
this.isShow = false;
|
||||
},
|
||||
onBlur(e) {
|
||||
this.searchValue = e.target.value;
|
||||
if (this.searchValue) {
|
||||
this.inputValue = this.searchValue;
|
||||
} else {
|
||||
this.inputValue = "请输入学习标题";
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.isShow = true;
|
||||
this.pageNum = 1;
|
||||
this.pageSize = 10;
|
||||
this.pages = 2;
|
||||
this.getList();
|
||||
},
|
||||
clearInput() {
|
||||
this.searchValue = "";
|
||||
this.inputValue = "请输入学习标题";
|
||||
},
|
||||
getList() {
|
||||
if (this.pageNum > this.pages) return;
|
||||
|
||||
this.$instance.post(`/app/apppartystudy/listWechat`, {
|
||||
title: this.searchValue,
|
||||
type: this.partyStudyType,
|
||||
searchMonth: this.createDate,
|
||||
current: this.pageNum,
|
||||
size: this.pageSize,
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
const meetList = this.pageNum > 1 ? [...this.meetList, ...res.data.records] : res.data.records;
|
||||
this.pages = Math.ceil(res.data.total / 10);
|
||||
this.meetList = meetList;
|
||||
}
|
||||
});
|
||||
},
|
||||
toDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: "./partyStudyDetail?id=" + id,
|
||||
});
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.pageNum = this.pageNum + 1;
|
||||
this.getList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
.search-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search-input {
|
||||
line-height: 64px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ce0010;
|
||||
border-radius: 32px;
|
||||
color: #f0cbcd;
|
||||
font-size: 26px;
|
||||
|
||||
image {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
margin: 8px 8px 8px 24px;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
span-overflow: ellipsis;
|
||||
width: 600px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slect {
|
||||
width: 100%;
|
||||
height: 96px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.type-select {
|
||||
width: 50%;
|
||||
border-right: 1px solid #f7f7f7;
|
||||
margin: 30px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
|
||||
.uni-input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.type-select:nth-child(2) {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
.input-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #fff;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.sousuo {
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 60px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.input {
|
||||
background-color: #f3f3f3;
|
||||
width: 598px;
|
||||
height: 64px;
|
||||
color: #999999;
|
||||
font-size: 26px;
|
||||
margin-left: 8px;
|
||||
border-radius: 32px;
|
||||
padding-left: 70px;
|
||||
padding-right: 60px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.clear {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 130px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.search-word {
|
||||
font-size: 28px;
|
||||
color: #135ab8;
|
||||
line-height: 60px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.session-list {
|
||||
padding-top: 224px;
|
||||
|
||||
.session-item {
|
||||
width: 686px;
|
||||
margin: 0 auto 32px auto;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.item-top {
|
||||
padding: 32px 32px 0 32px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
word-break: break-all;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
line-height: 42px;
|
||||
font-size: 28px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.info-label {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
border-top: 2px solid #eee;
|
||||
text-align: right;
|
||||
padding-right: 64px;
|
||||
box-sizing: border-box;
|
||||
line-height: 96px;
|
||||
|
||||
.item-btn {
|
||||
display: inline-block;
|
||||
width: 152px;
|
||||
height: 52px;
|
||||
line-height: 52px;
|
||||
border-radius: 28px;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
margin-left: 32px;
|
||||
border: 2px solid #e1e1e1;
|
||||
}
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #343d65;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.item-status {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: -30px;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
line-height: 44px;
|
||||
font-size: 24px;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.item-status1 {
|
||||
color: #5a98f2;
|
||||
background-color: #f1f6ff;
|
||||
}
|
||||
|
||||
.item-status0 {
|
||||
color: #ff9b2b;
|
||||
background-color: #fff3e8;
|
||||
}
|
||||
|
||||
.color-1365DD {
|
||||
color: #1365dd;
|
||||
}
|
||||
|
||||
.color-FF4466 {
|
||||
color: #ff4466;
|
||||
}
|
||||
|
||||
.color-333333 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.color-606060 {
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.border-1365DD {
|
||||
border-color: #1365dd !important;
|
||||
color: #1365dd !important;
|
||||
}
|
||||
|
||||
.border-E1E1E1 {
|
||||
border-color: #e1e1e1 !important;
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.border-E1E1E1 {
|
||||
border-color: #e1e1e1 !important;
|
||||
}
|
||||
|
||||
.mar-b12 {
|
||||
margin-bottom: 26px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-affairs {
|
||||
width: 100%;
|
||||
height: calc(100% - 210px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
220
src/mods/party/AppPartyStudy/partyStudyContent.vue
Normal file
220
src/mods/party/AppPartyStudy/partyStudyContent.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<header></header>
|
||||
<div class="form">
|
||||
<div class="main">
|
||||
<div class="textarea">
|
||||
<div class="color-333 fs32">
|
||||
<span class="color-red">*</span>学习心得
|
||||
</div>
|
||||
<textarea
|
||||
type="textarea"
|
||||
placeholder="请输入学习心得(200字以内)"
|
||||
v-model="content"
|
||||
adjust-position="false"
|
||||
maxlength="200"
|
||||
class="fs32"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tips-span">说明 : 提交学习心得,意味着完成本次内容的学习。</p>
|
||||
<div class="report" @click="changeStatus()">提交</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "fillLog",
|
||||
data() {
|
||||
return {
|
||||
id: "",
|
||||
content: "",
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.id = options.id;
|
||||
this.getDetailInfo();
|
||||
},
|
||||
methods: {
|
||||
getDetailInfo() {
|
||||
this.$instance
|
||||
.post(`/app/apppartystudylog/queryStudyLog?id=${this.id}`, null, {})
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
if (res.data.content != null) {
|
||||
this.content = res.data.content;
|
||||
} else {
|
||||
this.content = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
changeStatus() {
|
||||
if (!this.content) {
|
||||
this.$toast("请输入学习心得");
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
studyId: this.id,
|
||||
content: this.content,
|
||||
};
|
||||
this.$instance
|
||||
.post(`/app/apppartystudylog/addStudyLog`, params)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$toast("学习心得提交完成");
|
||||
setTimeout(function () {
|
||||
uni.navigateBack({
|
||||
delta: 2,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.tips-span {
|
||||
width: 626px;
|
||||
font-size: 28px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
color: rgba(153, 153, 153, 1);
|
||||
line-height: 40px;
|
||||
margin-top: 20px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 688px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 100%;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
margin-top: -100px;
|
||||
|
||||
.main {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.basic-item {
|
||||
font-size: 32px;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
padding: 32px 32px 32px 12px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
input {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wid-110 {
|
||||
width: 214px;
|
||||
}
|
||||
|
||||
.skill-span {
|
||||
max-width: 432px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
span-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.picker {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
color: #999999;
|
||||
font-size: 32px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.picker > .AiArea {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wei-span {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.msg-value {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.msg-btn {
|
||||
width: 160px;
|
||||
text-align: right;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 28px;
|
||||
background-color: #fff;
|
||||
line-height: 48px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.button-hover {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
background-color: #fff !important;
|
||||
font-size: 28px;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
background: rgba(230, 0, 18, 1);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fs32 {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
351
src/mods/party/AppPartyStudy/partyStudyDetail.vue
Normal file
351
src/mods/party/AppPartyStudy/partyStudyDetail.vue
Normal file
@@ -0,0 +1,351 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="detail-content">
|
||||
<div class="detail-info">
|
||||
<div class="info-title">{{ data.title }}</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">学习类别:</span>
|
||||
<span class="info-value">{{ $dict.getLabel('partyStudyType', data.type) }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">发布人员:</span>
|
||||
<span class="info-value">{{ data.publishUserName }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">发布时间:</span>
|
||||
<span class="info-value">{{ data.publishTime }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">学习时间:</span>
|
||||
<span class="info-value">{{ data.studyBeginDate }}至{{ data.studyEndDate }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">学习状态:</span>
|
||||
<span class="info-value">{{ $dict.getLabel('partyStudyStatus', data.studyStatus) }}</span>
|
||||
</div>
|
||||
<div class="item-info" v-if="data.studyStatus == 1">
|
||||
<span class="info-label">完成时间:</span>
|
||||
<span class="info-value">{{ data.finishDate || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="page-title">学习内容</div> -->
|
||||
<u-parse :html="data.content" class="content" v-if="data.content"></u-parse>
|
||||
<AiTransSpeech :src="data.speech"/>
|
||||
</div>
|
||||
<div class="btn-box" @click="toContent()">
|
||||
<span class="active">学习心得</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
id: '',
|
||||
data: {},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.$dict.load('partyStudyStatus', 'partyStudyType')
|
||||
this.id = options.id
|
||||
this.getDetailInfo()
|
||||
},
|
||||
onShow() {
|
||||
this.getDetailInfo()
|
||||
},
|
||||
methods: {
|
||||
toContent() {
|
||||
uni.navigateTo({url: `./AppPartyStudy?id=${this.id}`})
|
||||
},
|
||||
getDetailInfo() {
|
||||
this.$instance.post(`/app/apppartystudy/queryDetailByIdWeChat?id=${this.id}`, null, {}).then(res => {
|
||||
if (res.data) {
|
||||
if (res.data.files && res.data.files.length) {
|
||||
res.data.files.map(item => {
|
||||
var size = item.size / 1024;
|
||||
item.fileSize = size.toFixed(0);
|
||||
return item
|
||||
})
|
||||
}
|
||||
this.data = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
background-color: #fff;
|
||||
|
||||
.detail-content {
|
||||
padding-bottom: 140px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.detail-info {
|
||||
padding: 16px 32px 8px 32px;
|
||||
border-bottom: 2px solid #D8DDE6;
|
||||
background-color: #D7261E;
|
||||
padding-bottom: 80px;
|
||||
position: relative;
|
||||
|
||||
.info-title {
|
||||
line-height: 64px;
|
||||
font-size: 40px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
word-break: break-all;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
line-height: 48px;
|
||||
font-size: 30px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.info-label {
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
display: inline-block;
|
||||
width: 510px;
|
||||
word-break: break-all;
|
||||
color: #FFE8E8;
|
||||
}
|
||||
|
||||
.item-status0 {
|
||||
color: #FF9B2B;
|
||||
}
|
||||
|
||||
.item-status1 {
|
||||
color: #2EA222;
|
||||
}
|
||||
|
||||
.item-status2 {
|
||||
color: #343D65;
|
||||
}
|
||||
|
||||
.item-status3 {
|
||||
color: #5A98F2;
|
||||
}
|
||||
|
||||
.item-status4 {
|
||||
color: #f46;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.retract-btn {
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 690px;
|
||||
|
||||
.down-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 4px;
|
||||
vertical-align: middle;
|
||||
transition: all .3s ease-in-out;
|
||||
}
|
||||
|
||||
.icon-active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-title {
|
||||
line-height: 96px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
padding-left: 32px;
|
||||
background-color: #fff;
|
||||
|
||||
span {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-content {
|
||||
padding: 16px 32px;
|
||||
background-color: #fff;
|
||||
line-height: 48px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.user-list {
|
||||
background-color: #fff;
|
||||
|
||||
.user-item {
|
||||
height: 112px;
|
||||
padding-top: 16px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.user-bg {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background-color: #4E8EEE;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 80px;
|
||||
margin: 0 16px 0 32px;
|
||||
font-size: 28px;
|
||||
border-radius: 50%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: inline-block;
|
||||
width: 622px;
|
||||
height: 96px;
|
||||
border-bottom: 2px solid #D8DDE6;
|
||||
box-sizing: border-box;
|
||||
|
||||
.user-name {
|
||||
line-height: 44px;
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.user-unit {
|
||||
line-height: 34px;
|
||||
color: #999;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-item:nth-last-of-type(1) {
|
||||
.user-info {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mar-b8 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.color-1365DD {
|
||||
color: #1365DD;
|
||||
}
|
||||
|
||||
.color-999999 {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.pad-l7 {
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
.attachment {
|
||||
width: 100%;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
background-color: #FFFFFF;
|
||||
margin-top: 16px;
|
||||
|
||||
.attachment-title {
|
||||
font-size: 32px;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
|
||||
image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
border: 1px solid rgba(204, 204, 204, 1);
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
margin-top: 34px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
|
||||
.file-name {
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #333333;
|
||||
font-size: 32px;
|
||||
word-break: break-all;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.size {
|
||||
color: #999;
|
||||
font-size: 28px;
|
||||
display: flex;
|
||||
justify-content: cemter;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
bottom: 0;
|
||||
height: 112px;
|
||||
line-height: 112px;
|
||||
width: 100%;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
font-size: 36px;
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: #D7261E;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.partyStudyContent {
|
||||
width: 100%;
|
||||
height: calc(100% - 184px);
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
color: #666;
|
||||
font-size: 32px;
|
||||
background-color: #fff;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
576
src/mods/party/AppThreeSessions/AppThreeSessions.vue
Normal file
576
src/mods/party/AppThreeSessions/AppThreeSessions.vue
Normal file
@@ -0,0 +1,576 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div v-if="isShow" style="height:100%;">
|
||||
<div class="fixed-top" style="width:100%;">
|
||||
<!-- 头部搜索样式 -->
|
||||
<div class="search-box">
|
||||
<div class="search-input flex-row" @click="changeSearchBox">
|
||||
<image src="https://cdn.cunwuyun.cn/img/search-red.svg"></image>
|
||||
<span>{{ inputValue }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 选择时间和类型 -->
|
||||
<div class='slect flex-row'>
|
||||
<!-- 类型选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker @change="bindPickerChange" :range="array" range-key="dictName">
|
||||
<div class="uni-input">{{ meetTypespan }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间选择 -->
|
||||
<div class="uni-list type-slect">
|
||||
<div class="uni-list-cell">
|
||||
<div class="uni-list-cell-db">
|
||||
<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange"
|
||||
fields='month'>
|
||||
<div class="uni-input">{{ day }}</div>
|
||||
<image src="https://cdn.cunwuyun.cn/img/down.svg"></image>
|
||||
</picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session-list">
|
||||
<div class="session-item" v-for="(item, index) in meetList" :key="index">
|
||||
<div class="item-top" @click="toSessionDetail(item.meetingId, item.status)">
|
||||
<div class="item-title mar-b12">{{ item.meetingAgenda }}</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">会议状态:</span>
|
||||
<span :class="'item-status'+item.postStatus" class="info-value">
|
||||
{{ $dict.getLabel('postStatus', item.postStatus) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">开始时间:</span>
|
||||
<span class="info-value">{{ item.startTime || '-' }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">会议地点:</span>
|
||||
<span class="info-value">{{ item.meetingAddress || '-' }}</span>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<span class="info-label">主持人员:</span>
|
||||
<span class="info-value">{{ item.hostName || '-' }}</span>
|
||||
</div>
|
||||
<div class="item-info mar-b12">
|
||||
<span class="info-label">会议类型:</span>
|
||||
<span class="info-value">{{ item.meetingClassification || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-bottom">
|
||||
<span class="item-btn border-E1E1E1" v-if="item.status == 3">已请假</span>
|
||||
<span class="item-btn border-1365DD" v-if="item.status == 0 && item.isSignEnd"
|
||||
@click="signMeeting(item.meetingId)">签到</span>
|
||||
<span class="item-btn border-E1E1E1" v-if="item.status == 1">已签到</span>
|
||||
<!-- <span class="item-btn border-E1E1E1" v-if="item.status == 4">不签到</span> -->
|
||||
</div>
|
||||
<div class="item-status" :class="'item-status'+item.postStatus">
|
||||
{{ $dict.getLabel('postStatus', item.postStatus) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<AiEmpty v-if="meetList.length == 0"/>
|
||||
</div>
|
||||
<div v-if="!isShow" class="search-input">
|
||||
<div class="input-box flex-row">
|
||||
<input class="input" placeholder="请输入会议标题" focus="false" v-model="searchValue" @blur="onBlur"/>
|
||||
<image class="sousuo" src="https://cdn.cunwuyun.cn/img/search-active.svg"></image>
|
||||
<image v-if="searchValue" @tap="clearInput" class="clear"
|
||||
src="https://cdn.cunwuyun.cn/img/empty-Input.svg"></image>
|
||||
<div class="search-word" @click="search">搜索</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
appName: "三会一课",
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
format: true
|
||||
})
|
||||
return {
|
||||
inputValue: "请输入会议标题",
|
||||
isShow: true,
|
||||
array: [],
|
||||
meetType: "",
|
||||
meetTypespan: "会议类型",
|
||||
index: 0,
|
||||
date: currentDate,
|
||||
day: "会议时间",
|
||||
createDate: "",//创建时间
|
||||
meetList: [],
|
||||
searchValue: "",//搜索框输入值
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pages: 2,
|
||||
userId: '',
|
||||
partyId: '',
|
||||
meetTypeIndex: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
startDate() {
|
||||
return this.getDate('start');
|
||||
},
|
||||
endDate() {
|
||||
return this.getDate('end');
|
||||
},
|
||||
...mapState(['user']),
|
||||
},
|
||||
onLoad() {
|
||||
this.partyId = this.user.id
|
||||
this.$dict.load('postStatus', 'meetingClassification').then(() => {
|
||||
this.array = this.$dict.getDict('meetingClassification')
|
||||
this.getList()
|
||||
})
|
||||
uni.$on('updateList', () => {
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
signMeeting(id) {
|
||||
this.$instance.post(`/app/appthreemeetinguser/signByMeetingIdAndUserIdForWX?meetingId=${id}&userId=${this.user.partyId}`, null, {}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$toast('签到成功')
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.getList()
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: err,
|
||||
duration: 2000
|
||||
});
|
||||
})
|
||||
},
|
||||
btnClick(span) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: span,
|
||||
duration: 2000
|
||||
});
|
||||
},
|
||||
bindPickerChange(e) {
|
||||
this.array.map((item, index) => {
|
||||
if (e.detail.value == item.dictValue) {
|
||||
this.meetTypespan = this.array[index].dictName
|
||||
}
|
||||
})
|
||||
this.meetTypeIndex = e.detail.value
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList()
|
||||
},
|
||||
bindDateChange: function (e) {
|
||||
this.day = e.target.value;
|
||||
this.createDate = e.target.value + '-' + "01"
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.pageSize = 10;
|
||||
this.getList()
|
||||
},
|
||||
getDate(type) {
|
||||
const date = new Date();
|
||||
let year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
let day = date.getDate();
|
||||
|
||||
if (type === 'start') {
|
||||
year = year - 60;
|
||||
} else if (type === 'end') {
|
||||
year = year + 2;
|
||||
}
|
||||
month = month > 9 ? month : '0' + month;
|
||||
day = day > 9 ? day : '0' + day;
|
||||
|
||||
return `${year}-${month}-08 00:00:00 `;
|
||||
},
|
||||
changeSearchBox() {
|
||||
this.isShow = false;
|
||||
},
|
||||
onBlur(e) {
|
||||
this.searchValue = e.target.value;
|
||||
if (this.searchValue) {
|
||||
this.inputValue = this.searchValue;
|
||||
} else {
|
||||
this.inputValue = "请输入会议标题";
|
||||
}
|
||||
},
|
||||
search() {
|
||||
this.isShow = true;
|
||||
this.pageNum = 1;
|
||||
this.pageSize = 10;
|
||||
this.pages = 2;
|
||||
this.getList()
|
||||
},
|
||||
clearInput() {
|
||||
this.searchValue = ''
|
||||
this.inputValue = "请输入会议标题";
|
||||
},
|
||||
getList() {
|
||||
if (this.pageNum > this.pages) return
|
||||
// var searchYMD = ''
|
||||
// if(this.createDate) {
|
||||
// searchYMD = this.createDate + '-01'
|
||||
// }
|
||||
this.$instance.post(`/app/appthreemeetinguser/listForWX?meetingUserId=${this.user.partyId}&meetingAgenda=${this.searchValue}&meetingClassification=${this.meetTypeIndex}&searchYMD=${this.createDate}¤t=${this.pageNum}&size=${this.pageSize}`
|
||||
).then(res => {
|
||||
if (res.code == 0) {
|
||||
const meetList = this.pageNum > 1 ? [...this.meetList, ...res.data.records] : res.data.records
|
||||
meetList.map(item => {
|
||||
if (item.meetingAfter) {
|
||||
var dEnd = new Date(item.startTime.replaceAll('-', '/'));
|
||||
item.isSignEnd = new Date(dEnd.getTime() + (Number(item.meetingAfter)) * 60000).getTime() > new Date().getTime()
|
||||
}
|
||||
if (item.meetingClassification.length == 1) {
|
||||
item.meetingClassification = this.$dict.getLabel('meetingClassification', item.meetingClassification)
|
||||
|
||||
} else {
|
||||
var typeList = item.meetingClassification.split(',')
|
||||
typeList.map((items, index) => {
|
||||
if (index == 0) {
|
||||
item.meetingClassification = this.$dict.getLabel('meetingClassification', items)
|
||||
} else {
|
||||
item.meetingClassification = item.meetingClassification + ',' + this.$dict.getLabel('meetingClassification', items)
|
||||
}
|
||||
return item.meetingClassification
|
||||
})
|
||||
return item.meetingClassification
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.pages = Math.ceil(res.data.total / 10)
|
||||
this.meetList = meetList
|
||||
}
|
||||
})
|
||||
},
|
||||
toSessionDetail(id, signStatus) {
|
||||
uni.navigateTo({
|
||||
url: `./threeSessionsDetail?id=${id}&signStatus=${signStatus}&token=${uni.getStorageSync("token")}`
|
||||
})
|
||||
},
|
||||
leave() {
|
||||
uni.showModal({
|
||||
title: '如需请假,请联系签到负责人',
|
||||
confirmspan: "确认",
|
||||
confirmColor: "#135AB8",
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
} else if (res.cancel) {
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
changeStatus(id, signStatus, joinStatus, signMethod, absence, meetingUserId, meetingId, successspan) {
|
||||
let signTime = new Date().getFullYear() + '-' + this.isDate(new Date().getMonth() + 1) + '-' + this.isDate(new Date().getDate()) + ' ' + this.isDate(new Date().getHours()) + ':' + this.isDate(new Date().getMinutes()) + ':' + this.isDate(new Date().getSeconds())
|
||||
var params = {
|
||||
id,
|
||||
signStatus,
|
||||
joinStatus,
|
||||
signMethod,
|
||||
absence,
|
||||
signUserId: this.user.id,
|
||||
signUserName: this.user.realName,
|
||||
signTime,
|
||||
meetingUserId,
|
||||
meetingId
|
||||
}
|
||||
this.$instance.post(`/app/appthreemeetinguser/addOrUpdate`, null, {
|
||||
data: params
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
uni.showToast({
|
||||
title: successspan + '成功!',
|
||||
duration: 2000
|
||||
});
|
||||
this.pageNum = 1;
|
||||
this.pages = 2;
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
},
|
||||
isDate(num) {
|
||||
if (num < 10) {
|
||||
num = '0' + num
|
||||
}
|
||||
return num
|
||||
},
|
||||
},
|
||||
onReachBottom() {
|
||||
this.pageNum = this.pageNum + 1
|
||||
this.getList()
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
|
||||
.page {
|
||||
.fixed-top {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #D7261E;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 64px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #CE0010;
|
||||
border-radius: 32px;
|
||||
color: #F0CBCD;
|
||||
font-size: 26px;
|
||||
|
||||
image {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
margin: 8px 8px 8px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slect {
|
||||
width: 100%;
|
||||
height: 96px;
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
|
||||
.type-slect {
|
||||
width: 50%;
|
||||
border-right: 1px solid #F7F7F7;
|
||||
margin: 30px 0;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
|
||||
.uni-input {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.type-slect:nth-child(2) {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
.input-box {
|
||||
width: 100%;
|
||||
height: 112px;
|
||||
background-color: #fff;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.sousuo {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 60px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.input {
|
||||
background-color: #F3F3F3;
|
||||
width: 598px;
|
||||
height: 64px;
|
||||
color: #999999;
|
||||
font-size: 26px;
|
||||
margin-left: 8px;
|
||||
border-radius: 32px;
|
||||
padding-left: 70px;
|
||||
padding-right: 60px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.clear {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 130px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.search-word {
|
||||
font-size: 28px;
|
||||
color: #135AB8;
|
||||
line-height: 60px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.session-list {
|
||||
padding-top: 224px;
|
||||
|
||||
.session-item {
|
||||
width: 686px;
|
||||
margin: 0 auto 32px auto;
|
||||
background-color: #fff;
|
||||
// height:462px; position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.item-top {
|
||||
padding: 32px 32px 0 32px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
line-height: 44px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
line-height: 42px;
|
||||
font-size: 28px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.info-label {
|
||||
display: inline-block;
|
||||
color: #999;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
display: inline-block;
|
||||
width: calc(100% - 200px);
|
||||
vertical-align: top;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
border-top: 2px solid #EEE;
|
||||
text-align: right;
|
||||
padding-right: 64px;
|
||||
box-sizing: border-box;
|
||||
line-height: 96px;
|
||||
|
||||
.item-btn {
|
||||
display: inline-block;
|
||||
width: 152px;
|
||||
height: 52px;
|
||||
line-height: 52px;
|
||||
border-radius: 28px;
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
margin-left: 32px;
|
||||
border: 2px solid #E1E1E1;
|
||||
}
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #343D65;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.item-status {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
right: -36px;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
line-height: 44px;
|
||||
font-size: 24px;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.item-status1 {
|
||||
color: #FF9B2B;
|
||||
background-color: #FFF3E8;
|
||||
}
|
||||
|
||||
.item-status0 {
|
||||
color: #2EA222;
|
||||
background-color: #EAF5E8;
|
||||
}
|
||||
|
||||
.item-status3 {
|
||||
color: #999;
|
||||
background-color: #F2F2F2;
|
||||
}
|
||||
|
||||
.item-status2 {
|
||||
color: #5A98F2;
|
||||
background-color: #F1F6FF;
|
||||
}
|
||||
|
||||
.color-1365DD {
|
||||
color: #1365DD;
|
||||
}
|
||||
|
||||
.color-FF4466 {
|
||||
color: #FF4466;
|
||||
}
|
||||
|
||||
.color-333333 {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.color-606060 {
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.border-1365DD {
|
||||
border-color: #1365DD !important;
|
||||
color: #1365DD !important;
|
||||
}
|
||||
|
||||
.border-E1E1E1 {
|
||||
border-color: #E1E1E1 !important;
|
||||
color: #606060;
|
||||
}
|
||||
|
||||
.border-E1E1E1 {
|
||||
border-color: #E1E1E1 !important;
|
||||
}
|
||||
|
||||
.mar-b12 {
|
||||
margin-bottom: 26px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-affairs {
|
||||
width: 100%;
|
||||
height: calc(100% - 210px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
209
src/mods/party/AppThreeSessions/qrcode.vue
Normal file
209
src/mods/party/AppThreeSessions/qrcode.vue
Normal file
@@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<!-- <span class="close-img" @click="closePage()">×</span> -->
|
||||
<image src="https://cdn.cunwuyun.cn/img/qrcode-sign-img.png" class="banner-img"></image>
|
||||
<div class="btn" @click="btnClick()">{{ btnspan }}</div>
|
||||
<div class="mask" v-if="showFail">
|
||||
<div class="mask-content">
|
||||
<image src="https://cdn.cunwuyun.cn/img/qrcode-sign-fail.png" class="fail-img"></image>
|
||||
<div class="mask-span">签到失败!请重新签到</div>
|
||||
<div class="mask-btn" @click="btnClick()">确认签到</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showFail: false,
|
||||
meetingId: '',
|
||||
btnspan: '',
|
||||
scene: '',
|
||||
userId: '',
|
||||
isSign: true
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (uni.getStorageSync('token')) {
|
||||
this.meetingId = this.$mp.query.scene
|
||||
// this.meetingId = 'c29aacb54f074c14ab93532e384a6daa'
|
||||
this.getUserInfo()
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您还未登录,请先登录!',
|
||||
confirmspan: "去登录",
|
||||
showCancel: false,
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
wx.switchTab({
|
||||
url: '../mine/mine',
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUserInfo() {
|
||||
this.$store.commit("getUserInfo", v => {
|
||||
if (v) {
|
||||
this.userId = res.data.id
|
||||
this.getDetailInfo()
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetailInfo() {
|
||||
this.$instance.post(`/app/appthreemeetinguser/queryWeathersignByMeetingIdAndUserIdForWX?meetingId=${this.meetingId}&userId=${this.userId}`, null, {}).then(res => {
|
||||
if (res.data) {
|
||||
this.isSign = true
|
||||
// if(res.data.status == 1) { //已签到
|
||||
// this.btnspan = '已签到'
|
||||
// }
|
||||
if (res.data.status == 0) { //未签
|
||||
this.btnspan = '确认签到'
|
||||
} else {
|
||||
this.btnspan = '已签到'
|
||||
}
|
||||
} else {
|
||||
this.btnspan = '确认签到'
|
||||
this.isSign = false //不是参会人员
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: err,
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
})
|
||||
},
|
||||
btnClick() {
|
||||
// if(!this.isSign) {
|
||||
// uni.showToast({
|
||||
// icon: 'none',
|
||||
// title: '您不是参会人员',
|
||||
// duration: 2000
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
if (this.btnspan == '已签到') {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已签到',
|
||||
duration: 2000
|
||||
});
|
||||
return
|
||||
}
|
||||
this.$instance.post(`/app/appthreemeetinguser/signByMeetingIdAndUserIdForWX?meetingId=${this.meetingId}&userId=${this.userId}`, null, {}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.btnspan = '已签到'
|
||||
uni.showToast({
|
||||
title: '签到成功',
|
||||
duration: 2000
|
||||
});
|
||||
} else {
|
||||
this.showFail = true
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: err,
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
})
|
||||
},
|
||||
closePage() {
|
||||
uni.reLaunch({
|
||||
url: "../home/portal"
|
||||
})
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import "../../../common/common.css";
|
||||
|
||||
.page {
|
||||
background-color: #FFFFFF;
|
||||
position: relative;
|
||||
|
||||
.close-img {
|
||||
position: absolute;
|
||||
font-size: 50px;
|
||||
left: 32px;
|
||||
}
|
||||
|
||||
.banner-img {
|
||||
width: 514px;
|
||||
height: 340px;
|
||||
margin: 48px 0 118px 96px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 622px;
|
||||
line-height: 96px;
|
||||
text-align: center;
|
||||
background: rgba(19, 90, 184, 1);
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
margin: 0 auto;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, .3);
|
||||
|
||||
.mask-content {
|
||||
width: 686px;
|
||||
height: 640px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
border: 2px solid rgba(151, 151, 151, 1);
|
||||
margin: 260px auto 0;
|
||||
|
||||
.fail-img {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 112px 0 32px 264px;
|
||||
}
|
||||
|
||||
.mask-span {
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
font-size: 36px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 700;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
text-align: center;
|
||||
margin-bottom: 134px;
|
||||
}
|
||||
|
||||
.mask-btn {
|
||||
width: 560px;
|
||||
line-height: 96px;
|
||||
text-align: center;
|
||||
background: rgba(19, 90, 184, 1);
|
||||
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
margin: 0 auto;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user