wangyue
2 years ago
88 changed files with 2054 additions and 901 deletions
@ -0,0 +1,140 @@ |
|||||
|
#!/usr/bin/env bash |
||||
|
|
||||
|
Help() |
||||
|
{ |
||||
|
echo "你也可以使用自定义参数进行指定查询" |
||||
|
echo |
||||
|
echo "格式: bash $0 [2021-01-01] [2022-04-04] [author]" |
||||
|
echo "示例: bash code996.sh 2021-01-01 2022-12-31 digua" |
||||
|
echo "参数:" |
||||
|
echo "1st 分析的起始时间." |
||||
|
echo "2nd 分析的结束时间." |
||||
|
echo "3rd 指定提交用户,可以是 name 或 email." |
||||
|
echo |
||||
|
} |
||||
|
|
||||
|
OS_DETECT() |
||||
|
{ |
||||
|
# Detect OS |
||||
|
case "$(uname -s)" in |
||||
|
|
||||
|
Linux) |
||||
|
# echo 'Linux' |
||||
|
open_url="xdg-open" |
||||
|
;; |
||||
|
|
||||
|
Darwin) |
||||
|
# echo 'macOS' |
||||
|
open_url="open" |
||||
|
;; |
||||
|
|
||||
|
CYGWIN*|MINGW32*|MSYS*|MINGW*) |
||||
|
# echo 'Windows' |
||||
|
open_url="start" |
||||
|
;; |
||||
|
|
||||
|
*) |
||||
|
echo 'Other OS' |
||||
|
echo "trying to use xdg-open to open the url" |
||||
|
open_url="xdg-open" |
||||
|
;; |
||||
|
esac |
||||
|
|
||||
|
} |
||||
|
OS_DETECT |
||||
|
|
||||
|
|
||||
|
time_start=$1 |
||||
|
|
||||
|
|
||||
|
if [ "$1" == "--help" ] |
||||
|
then |
||||
|
Help |
||||
|
exit 0 |
||||
|
elif [ "$1" == "-h" ] |
||||
|
then |
||||
|
Help |
||||
|
exit 0 |
||||
|
fi |
||||
|
|
||||
|
if [ -z $1 ] |
||||
|
then |
||||
|
time_start="2021-01-01" |
||||
|
fi |
||||
|
|
||||
|
time_end=$2 |
||||
|
if [ -z $2 ] |
||||
|
then |
||||
|
time_end=$(date "+%Y-%m-%d") |
||||
|
fi |
||||
|
|
||||
|
author=$3 |
||||
|
if [ -z $3 ] |
||||
|
then |
||||
|
author="" |
||||
|
fi |
||||
|
|
||||
|
|
||||
|
by_day_output=`git -C $PWD log --author=$author --date=format:%u --after="$time_start" --before="$time_end" |grep "Date:"|awk '{print $2}'|sort|uniq -c` |
||||
|
|
||||
|
by_hour_output=`git -C $PWD log --author=$author --date=format:%H --after="$time_start" --before="$time_end" |grep "Date:"|awk '{print $2}'|sort|uniq -c` |
||||
|
|
||||
|
for i in "${by_day_output[@]}" |
||||
|
do |
||||
|
by_day_result=`echo "$i"|sed -E 's/^ +//g'|sed 's/ /_/g'|tr '\n' ','` |
||||
|
|
||||
|
done |
||||
|
|
||||
|
|
||||
|
# should modify by day format %a or %A |
||||
|
# day_sorted=('Monday' 'Tuesday' 'Wednesday' 'Thursday' 'Friday' 'Saturday' 'Sunday') |
||||
|
# day_sorted=('Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat' 'Sun') |
||||
|
|
||||
|
RED='\033[1;91m' |
||||
|
NC='\033[0m' # No Color |
||||
|
|
||||
|
echo -e "${RED}统计时间范围:$time_start 至 $time_end" |
||||
|
|
||||
|
for i in "${by_day_output[@]}" |
||||
|
do |
||||
|
echo |
||||
|
echo -e "${NC}一周七天 commit 分布${RED}" |
||||
|
echo -e " 总提交次数 星期\n$i"|column -t |
||||
|
by_day_result=`echo "$i"|sed -E 's/^ +//g'|sed "s/ /_/g"|tr '\n' ','` |
||||
|
done |
||||
|
|
||||
|
|
||||
|
for i in "${by_hour_output[@]}" |
||||
|
do |
||||
|
echo |
||||
|
echo -e "${NC}24小时 commit 分布${RED}" |
||||
|
echo -e " 总提交次数 小时\n$i"|column -t |
||||
|
by_hour_result=`echo "$i"|sed -E 's/^ +//g'|sed "s/ /_/g"|tr '\n' ','` |
||||
|
done |
||||
|
|
||||
|
|
||||
|
by_day_result=`echo "$by_day_result"|sed -E 's/,$//g'` |
||||
|
|
||||
|
by_hour_result=`echo "$by_hour_result"|sed -E 's/,$//g'` |
||||
|
|
||||
|
|
||||
|
result=$time_start"_"$time_end"&week="$by_day_result"&hour="$by_hour_result |
||||
|
|
||||
|
# url |
||||
|
github_url="https://hellodigua.github.io/code996/#/result?time=$result" |
||||
|
vercel_url="https://code996.vercel.app/#/result?time=$result" |
||||
|
gitee_url="https://hellodigua.gitee.io/code996/#/result?time=$result" |
||||
|
|
||||
|
echo |
||||
|
echo -e "${NC}复制以下url以查看可视化分析结果:" |
||||
|
echo -e "${RED}$github_url" |
||||
|
echo -e "${NC}" |
||||
|
echo -e "${NC}若 GitHub 访问过慢,也可以访问以下镜像链接:" |
||||
|
echo -e "${NC}Vercel节点:" |
||||
|
echo -e "${RED}$vercel_url" |
||||
|
echo -e "${NC}" |
||||
|
echo -e "${NC}Gitee节点:" |
||||
|
echo -e "${RED}$gitee_url" |
||||
|
echo -e "${NC}" |
||||
|
|
||||
|
$open_url "$github_url" |
@ -0,0 +1,19 @@ |
|||||
|
pipeline { |
||||
|
agent { |
||||
|
node{ |
||||
|
label 'jnlp-slave' |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
stages { |
||||
|
stage('Highways4Good Api ......') { |
||||
|
steps { |
||||
|
sh 'switch-auth.sh anxinyun' |
||||
|
buildName "#${BUILD_NUMBER} ~/fs-cloud/${JOB_NAME}:${IMAGE_VERSION}" |
||||
|
buildDescription "registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}" |
||||
|
sh 'docker build -t registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION} ./scripts/0.0.1/data/3_init_report_pic_data' |
||||
|
sh 'docker push registry.cn-hangzhou.aliyuncs.com/${CLOUD}/${JOB_NAME}:${IMAGE_VERSION}' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 |
||||
|
|
||||
|
COPY . /var/app |
||||
|
|
||||
|
WORKDIR /var/app |
||||
|
|
||||
|
RUN npm cache clean -f |
||||
|
RUN rm -rf package-lock.json |
||||
|
RUN npm install --registry http://10.8.30.22:7000 |
||||
|
|
||||
|
CMD ["node", "index.js"] |
@ -0,0 +1,10 @@ |
|||||
|
-- ---------------------------- |
||||
|
-- Records of file_type |
||||
|
-- ---------------------------- |
||||
|
BEGIN; |
||||
|
INSERT INTO "public"."file_type" VALUES (1, '前期资料', NULL); |
||||
|
INSERT INTO "public"."file_type" VALUES (3, '竣工资料', NULL); |
||||
|
INSERT INTO "public"."file_type" VALUES (4, '维修资料', NULL); |
||||
|
INSERT INTO "public"."file_type" VALUES (5, '道路图片', NULL); |
||||
|
INSERT INTO "public"."file_type" VALUES (2, '施工资料', NULL); |
||||
|
COMMIT; |
@ -0,0 +1,3 @@ |
|||||
|
export default { |
||||
|
navigationBarTitleText: '视频监控' |
||||
|
} |
@ -0,0 +1,85 @@ |
|||||
|
import React, { useState, useEffect } from 'react' |
||||
|
import Taro from '@tarojs/taro' |
||||
|
import { View, Image, Input, Picker, LivePlayer } from '@tarojs/components' |
||||
|
import request from '@/services/request' |
||||
|
import './index.scss' |
||||
|
import '../patrolView/index.scss' |
||||
|
import patrolIcon from '../../static/img/patrolView/patrol.svg' |
||||
|
import patrolActiveIcon from '../../static/img/patrolView/patrol-active.svg' |
||||
|
import conserveIcon from '../../static/img/patrolView/conserve.svg' |
||||
|
import conserveActiveIcon from '../../static/img/patrolView/conserve-active.svg' |
||||
|
import chevronDown from '../../static/img/patrolView/chevron-down.png' |
||||
|
import searchIcon from '../../static/img/patrolView/search.png' |
||||
|
|
||||
|
function Index() { |
||||
|
const [isBus, setIsBus] = useState(true) |
||||
|
const [filterText, setFilterText] = useState('') |
||||
|
const [videoList, setVideoList] = useState([]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
getVideoList() |
||||
|
}, []) |
||||
|
|
||||
|
const getVideoList = () => { |
||||
|
let nextVideoList = [] |
||||
|
for (let i = 0; i < 10; i++) { |
||||
|
nextVideoList.push({ title: '视频' + i, url: '链接' + i }) |
||||
|
} |
||||
|
setVideoList(nextVideoList) |
||||
|
} |
||||
|
|
||||
|
const onTypeChange = bool => { |
||||
|
setIsBus(bool) |
||||
|
} |
||||
|
|
||||
|
const handleConfirm = e => { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
const handleInput = e => { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<View> |
||||
|
<View className='type-box'> |
||||
|
<View className='item' onClick={() => onTypeChange(true)}> |
||||
|
<Image className='type-img' src={isBus ? patrolActiveIcon : patrolIcon} /> |
||||
|
<View style={{ color: isBus ? '#346FC2' : '#999999' }}>公交</View> |
||||
|
</View> |
||||
|
<View className='line'></View> |
||||
|
<View className='item' onClick={() => onTypeChange(false)}> |
||||
|
<Image className='type-img' src={isBus ? conserveIcon : conserveActiveIcon} /> |
||||
|
<View style={{ color: isBus ? '#999999' : '#346FC2' }}>道路</View> |
||||
|
</View> |
||||
|
</View> |
||||
|
<View className='filter-box'> |
||||
|
<View className='filter-item'> |
||||
|
<View style={{ float: 'left', marginLeft: '20rpx', color: '#333' }}>路段:</View> |
||||
|
<Picker> |
||||
|
<View className='filter-name'>{'请选择'}</View> |
||||
|
<Image className='filter-img' src={chevronDown} /> |
||||
|
</Picker> |
||||
|
</View> |
||||
|
<View class='head-search'> |
||||
|
<Image className='search-img' src={searchIcon} /> |
||||
|
<Input class='heard-search-input' value={filterText} placeholder='请输入道路名称' onConfirm={handleConfirm} onInput={handleInput} /> |
||||
|
</View> |
||||
|
</View> |
||||
|
<View className='video-box'> |
||||
|
{ |
||||
|
videoList && videoList.map(v => { |
||||
|
return ( |
||||
|
<View className='video-card'> |
||||
|
<View className='title'>{v.title}</View> |
||||
|
<LivePlayer className='video' src={v.url} mode='live' /> |
||||
|
</View> |
||||
|
) |
||||
|
}) |
||||
|
} |
||||
|
</View> |
||||
|
</View> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default Index |
@ -0,0 +1,28 @@ |
|||||
|
page { |
||||
|
background-color: #f6f6f6; |
||||
|
|
||||
|
.video-box { |
||||
|
padding-top: 180px; |
||||
|
|
||||
|
.video-card { |
||||
|
background-color: #fff; |
||||
|
height: 488px; |
||||
|
margin-bottom: 20px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: left; |
||||
|
|
||||
|
.title { |
||||
|
height: 88px; |
||||
|
margin-left: 30px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.video { |
||||
|
height: 400px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,212 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
export function sort(arr, sortProperty) { |
||||
|
if (!Array.isArray(arr)) { |
||||
|
throw new Error('参数必须是数组'); |
||||
|
} |
||||
|
|
||||
|
const map = arr.reduce((p, n) => { |
||||
|
let sortProperty_ = sortProperty || 'name' |
||||
|
if (n[sortProperty_]) { |
||||
|
const sortKey = getOrderableString(n[sortProperty_]).join(''); |
||||
|
|
||||
|
if (p[sortKey]) { |
||||
|
if (Array.isArray(p[sortKey])) { |
||||
|
p[sortKey].push(n); |
||||
|
} else { |
||||
|
p[sortKey] = [p[sortKey], n]; |
||||
|
} |
||||
|
} else { |
||||
|
p[sortKey] = n; |
||||
|
} |
||||
|
return p; |
||||
|
} else { |
||||
|
throw new Error('排序对象不包含指定属性或name属性'); |
||||
|
} |
||||
|
}, {}); |
||||
|
|
||||
|
const keys = Object.keys(map); |
||||
|
|
||||
|
keys.sort(); |
||||
|
|
||||
|
let result = []; |
||||
|
keys.forEach(key => { |
||||
|
if (Array.isArray(map[key])) { |
||||
|
result = result.concat(map[key]); |
||||
|
} else { |
||||
|
result.push(map[key]); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
export function getOrderableString(source) { |
||||
|
// let result = source.includes('-') ? source.split('-') : source.includes('_') ? source.split('_') : source.split(''); //区分批量添加测点的-
|
||||
|
|
||||
|
// result = replaceNumber(result);
|
||||
|
|
||||
|
let result; |
||||
|
if (source.includes('-') || source.includes('_')) { |
||||
|
result = source.includes('-') ? source.split('-') : source; |
||||
|
result = Array.isArray(result) ? result.reduce((p, n) => { |
||||
|
if (!n.includes('_')) return p.concat(n); |
||||
|
|
||||
|
return p.concat(n.split('_')) |
||||
|
}, []) : result.includes('_') ? result.split('_') : result; |
||||
|
result = result.reduce((p, n) => { |
||||
|
p = p.concat(replaceNumber(n.split(''))) |
||||
|
|
||||
|
return p; |
||||
|
}, []); |
||||
|
} else { |
||||
|
result = replaceNumber(source.split('')) |
||||
|
} |
||||
|
|
||||
|
result = replaceChineseNumber(result); |
||||
|
|
||||
|
result = replaceSpecialWord(result); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
function replaceNumber(source) { |
||||
|
let result = source.concat([]); |
||||
|
let numFound = false; |
||||
|
let numStart = 0; |
||||
|
let baseLine = 0; |
||||
|
for (let i = 0; i < source.length; i++) { |
||||
|
let calc = false; |
||||
|
let len = 0; |
||||
|
let num = parseInt(source[i]); |
||||
|
if (!Number.isNaN(num)) { |
||||
|
if (!numFound) { |
||||
|
numFound = true; |
||||
|
numStart = i; |
||||
|
} |
||||
|
if (i == source.length - 1) { |
||||
|
calc = true; |
||||
|
len = source.length - numStart; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
if (numFound) { |
||||
|
numFound = false; |
||||
|
calc = true; |
||||
|
len = i - numStart; |
||||
|
} |
||||
|
} |
||||
|
if (calc) { |
||||
|
if (len < 5) { |
||||
|
let zeroes = ''; |
||||
|
for (let j = 0; j < 5 - len; j++) { |
||||
|
zeroes += "0"; |
||||
|
} |
||||
|
|
||||
|
if (baseLine > 0 && Number(num) < 10) { |
||||
|
//为解决[3d-12,3d-2]排序结果为[3d-12,3d-2]的问题,添加此处
|
||||
|
baseLine--; |
||||
|
} |
||||
|
result.splice(baseLine + numStart, 0, zeroes); |
||||
|
baseLine += zeroes.length; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result.join('').split(''); |
||||
|
} |
||||
|
|
||||
|
function replaceSpecialWord(source) { |
||||
|
const map = { "上": "1001", "中": "1002", "下": "1003", "左": "1001", "右": "1003" }; |
||||
|
|
||||
|
let result = source.join(''); |
||||
|
Object.keys(map).forEach(key => { |
||||
|
result = result.replace(key, map[key]); |
||||
|
}); |
||||
|
|
||||
|
return result.split(''); |
||||
|
} |
||||
|
|
||||
|
function replaceChineseNumber(source) { |
||||
|
var map = |
||||
|
{ |
||||
|
"零": 0, |
||||
|
"一": 1, |
||||
|
"二": 2, |
||||
|
"三": 3, |
||||
|
"四": 4, |
||||
|
"五": 5, |
||||
|
"六": 6, |
||||
|
"七": 7, |
||||
|
"八": 8, |
||||
|
"九": 9, |
||||
|
"十": 10 |
||||
|
}; |
||||
|
|
||||
|
var result = source; |
||||
|
var numFound = false; |
||||
|
var numStart = 0; |
||||
|
var baseLine = 0; |
||||
|
for (let i = 0; i < source.length; i++) { |
||||
|
var calc = false; |
||||
|
var len = 0; |
||||
|
if (map[source[i]]) {//零不作处理
|
||||
|
if (!numFound) { |
||||
|
numFound = true; |
||||
|
numStart = i; |
||||
|
} |
||||
|
if (i == source.length - 1) { |
||||
|
calc = true; |
||||
|
len = source.length - numStart; |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
if (numFound) { |
||||
|
numFound = false; |
||||
|
calc = true; |
||||
|
len = i - numStart; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (calc) { |
||||
|
var cp = ''; |
||||
|
var num = -1; |
||||
|
if (len == 1) { |
||||
|
num = map[source[numStart]]; |
||||
|
} |
||||
|
else if (len == 2) { |
||||
|
if (source[numStart] == '十') { |
||||
|
num = 10 + map[source[numStart + 1]]; |
||||
|
} |
||||
|
else if (source[numStart + 1] == '十') { |
||||
|
num = map[source[numStart]] * 10; |
||||
|
} |
||||
|
else { |
||||
|
num = map[source[numStart]] * 10 + map[source[numStart + 1]]; |
||||
|
} |
||||
|
} |
||||
|
else if (len == 3) { |
||||
|
if (source[numStart + 1] == '十') { |
||||
|
num = map[source[numStart]] * 10 + map[source[numStart + 2]]; |
||||
|
} |
||||
|
else { |
||||
|
num = map[source[numStart]] * 100 + map[source[numStart + 1]] * 10 + map[source[numStart + 2]]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (num != -1) { |
||||
|
var l = 3 - num.toString().length; |
||||
|
var zeroes = ''; |
||||
|
for (let j = 0; j < l; j++) { |
||||
|
zeroes += "0"; |
||||
|
} |
||||
|
cp = zeroes + num; |
||||
|
|
||||
|
result.splice(baseLine + numStart, len, cp); |
||||
|
baseLine += cp.length - len; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result.join('').split(''); |
||||
|
} |
Loading…
Reference in new issue