Parcourir la source

芯科出海平台项目首次代码提交

feix0518 il y a 2 semaines
commit
4bcc1ab857
100 fichiers modifiés avec 7798 ajouts et 0 suppressions
  1. 5 0
      xinkeaboard-admin/.gitignore
  2. 46 0
      xinkeaboard-admin/CODE_OF_CONDUCT.md
  3. 12 0
      xinkeaboard-admin/Dockerfile
  4. 11 0
      xinkeaboard-admin/Dockerfile.dev
  5. 11 0
      xinkeaboard-admin/Dockerfile.hub
  6. 21 0
      xinkeaboard-admin/LICENSE
  7. 137 0
      xinkeaboard-admin/README.md
  8. 102 0
      xinkeaboard-admin/README.ru-RU.md
  9. 121 0
      xinkeaboard-admin/README.zh-CN.md
  10. 26 0
      xinkeaboard-admin/appveyor.yml
  11. 126 0
      xinkeaboard-admin/config/config.js
  12. 0 0
      xinkeaboard-admin/config/config.local.js
  13. 0 0
      xinkeaboard-admin/config/config.test.js
  14. 33 0
      xinkeaboard-admin/config/plugin.config.js
  15. 1091 0
      xinkeaboard-admin/config/router.config.js
  16. 14 0
      xinkeaboard-admin/docker/docker-compose.dev.yml
  17. 21 0
      xinkeaboard-admin/docker/docker-compose.yml
  18. 22 0
      xinkeaboard-admin/docker/nginx.conf
  19. 13 0
      xinkeaboard-admin/firebase.json
  20. 9 0
      xinkeaboard-admin/functions/index.js
  21. 117 0
      xinkeaboard-admin/functions/matchMock.js
  22. 11 0
      xinkeaboard-admin/functions/mock/index.js
  23. 23 0
      xinkeaboard-admin/functions/package.json
  24. 15 0
      xinkeaboard-admin/jest-puppeteer.config.js
  25. 4 0
      xinkeaboard-admin/jest.config.js
  26. 10 0
      xinkeaboard-admin/jsconfig.json
  27. 13 0
      xinkeaboard-admin/netlify.toml
  28. 138 0
      xinkeaboard-admin/package.json
  29. 40 0
      xinkeaboard-admin/public/UEditor/dialogs/anchor/anchor.html
  30. 681 0
      xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.css
  31. 60 0
      xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.html
  32. 760 0
      xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.js
  33. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_chm.gif
  34. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_default.png
  35. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_doc.gif
  36. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_exe.gif
  37. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_jpg.gif
  38. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_mp3.gif
  39. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_mv.gif
  40. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_pdf.gif
  41. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_ppt.gif
  42. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_psd.gif
  43. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_rar.gif
  44. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_txt.gif
  45. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_xls.gif
  46. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/alignicon.gif
  47. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/alignicon.png
  48. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/bg.png
  49. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/file-icons.gif
  50. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/file-icons.png
  51. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/icons.gif
  52. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/icons.png
  53. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/image.png
  54. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/progress.png
  55. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/success.gif
  56. BIN
      xinkeaboard-admin/public/UEditor/dialogs/attachment/images/success.png
  57. 94 0
      xinkeaboard-admin/public/UEditor/dialogs/background/background.css
  58. 56 0
      xinkeaboard-admin/public/UEditor/dialogs/background/background.html
  59. 376 0
      xinkeaboard-admin/public/UEditor/dialogs/background/background.js
  60. BIN
      xinkeaboard-admin/public/UEditor/dialogs/background/images/bg.png
  61. BIN
      xinkeaboard-admin/public/UEditor/dialogs/background/images/success.png
  62. 65 0
      xinkeaboard-admin/public/UEditor/dialogs/charts/chart.config.js
  63. 165 0
      xinkeaboard-admin/public/UEditor/dialogs/charts/charts.css
  64. 89 0
      xinkeaboard-admin/public/UEditor/dialogs/charts/charts.html
  65. 519 0
      xinkeaboard-admin/public/UEditor/dialogs/charts/charts.js
  66. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts0.png
  67. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts1.png
  68. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts2.png
  69. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts3.png
  70. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts4.png
  71. BIN
      xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts5.png
  72. 43 0
      xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.css
  73. 54 0
      xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.html
  74. 186 0
      xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.js
  75. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/0.gif
  76. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/bface.gif
  77. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/cface.gif
  78. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/fface.gif
  79. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/jxface2.gif
  80. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/neweditor-tab-bg.png
  81. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/tface.gif
  82. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/wface.gif
  83. BIN
      xinkeaboard-admin/public/UEditor/dialogs/emotion/images/yface.gif
  84. 89 0
      xinkeaboard-admin/public/UEditor/dialogs/gmap/gmap.html
  85. 7 0
      xinkeaboard-admin/public/UEditor/dialogs/help/help.css
  86. 82 0
      xinkeaboard-admin/public/UEditor/dialogs/help/help.html
  87. 56 0
      xinkeaboard-admin/public/UEditor/dialogs/help/help.js
  88. 894 0
      xinkeaboard-admin/public/UEditor/dialogs/image/image.css
  89. 120 0
      xinkeaboard-admin/public/UEditor/dialogs/image/image.html
  90. 1031 0
      xinkeaboard-admin/public/UEditor/dialogs/image/image.js
  91. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/alignicon.jpg
  92. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/bg.png
  93. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/icons.gif
  94. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/icons.png
  95. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/image.png
  96. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/progress.png
  97. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/success.gif
  98. BIN
      xinkeaboard-admin/public/UEditor/dialogs/image/images/success.png
  99. 98 0
      xinkeaboard-admin/public/UEditor/dialogs/insertframe/insertframe.html
  100. 81 0
      xinkeaboard-admin/public/UEditor/dialogs/internal.js

+ 5 - 0
xinkeaboard-admin/.gitignore

@@ -0,0 +1,5 @@
+/yarn.lock
+/package-lock.json
+/.idea/*
+/.temp/
+node_modules

+ 46 - 0
xinkeaboard-admin/CODE_OF_CONDUCT.md

@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at afc163@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/

+ 12 - 0
xinkeaboard-admin/Dockerfile

@@ -0,0 +1,12 @@
+FROM circleci/node:latest-browsers
+
+WORKDIR /usr/src/app/
+USER root
+COPY package.json ./
+RUN yarn
+
+COPY ./ ./
+
+RUN npm run test:all
+
+CMD ["npm", "run", "build"]

+ 11 - 0
xinkeaboard-admin/Dockerfile.dev

@@ -0,0 +1,11 @@
+FROM node:latest
+
+WORKDIR /usr/src/app/
+
+COPY package.json ./
+RUN npm install --silent --no-cache
+
+COPY ./ ./
+
+
+CMD ["npm", "run", "start"]

+ 11 - 0
xinkeaboard-admin/Dockerfile.hub

@@ -0,0 +1,11 @@
+FROM nginx
+
+WORKDIR /usr/src/app/
+
+COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
+
+COPY ./dist  /usr/share/nginx/html/
+
+EXPOSE 80
+
+CMD ["nginx", "-g", "daemon off;"]

+ 21 - 0
xinkeaboard-admin/LICENSE

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

+ 137 - 0
xinkeaboard-admin/README.md

@@ -0,0 +1,137 @@
+English | [简体中文](./README.zh-CN.md) | [Русский](./README.ru-RU.md)
+
+<h1 align="center">Ant Design Pro</h1>
+
+<div align="center">
+
+An out-of-box UI solution for enterprise applications as a React boilerplate.
+
+[![CircleCI Status](https://circleci.com/gh/ant-design/ant-design-pro.svg?style=svg)](https://circleci.com/gh/ant-design/ant-design-pro/)
+[![Build status](https://ci.appveyor.com/api/projects/status/67fxu2by3ibvqtat/branch/master?svg=true)](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master)
+[![Dependencies](https://img.shields.io/david/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro)
+[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro?type=dev)
+[![Gitter](https://img.shields.io/gitter/room/ant-design/pro-english.svg)](https://gitter.im/ant-design/pro-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)(🇺🇸)
+[![Gitter](https://img.shields.io/gitter/room/ant-design/ant-design-pro.svg?style=flat-square)](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)(🇨🇳)
+
+
+![](https://user-images.githubusercontent.com/8186664/44953195-581e3d80-aec4-11e8-8dcb-54b9db38ec11.png)
+
+</div>
+
+- Preview: http://preview.pro.ant.design
+- Home Page: http://pro.ant.design
+- Documentation: http://pro.ant.design/docs/getting-started
+- ChangeLog: http://pro.ant.design/docs/changelog
+- FAQ: http://pro.ant.design/docs/faq
+- Mirror Site in China: http://ant-design-pro.gitee.io
+
+## 2.0 Released Now! 🎉🎉🎉
+[Announcing Ant Design Pro 2.0.0](https://medium.com/ant-design/beautiful-and-powerful-ant-design-pro-2-0-release-51358da5af95)
+
+## Translation Recruitment :loudspeaker:
+
+We need your help: https://github.com/ant-design/ant-design-pro/issues/120
+
+## Features
+
+- :gem: **Neat Design**: Follow [Ant Design specification](http://ant.design/)
+- :triangular_ruler: **Common Templates**: Typical templates for enterprise applications
+- :rocket: **State of The Art Development**: Newest development stack of React/umi/dva/antd
+- :iphone: **Responsive**: Designed for variable screen sizes
+- :art: **Theming**: Customizable theme with simple config
+- :globe_with_meridians: **International**: Built-in i18n solution
+- :gear: **Best Practices**: Solid workflow to make your code healthy
+- :1234: **Mock development**: Easy to use mock development solution
+- :white_check_mark: **UI Test**: Fly safely with unit and e2e tests
+
+## Templates
+
+```
+- Dashboard
+  - Analytic
+  - Monitor
+  - Workspace
+- Form
+  - Basic Form
+  - Step Form
+  - Advanced From
+- List
+  - Standard Table
+  - Standard List
+  - Card List
+  - Search List (Project/Applications/Article)
+- Profile
+  - Simple Profile
+  - Advanced Profile
+- Account
+  - Account Center
+  - Account Settings
+- Result
+  - Success
+  - Failed
+- Exception
+  - 403
+  - 404
+  - 500
+- User
+  - Login
+  - Register
+  - Register Result
+```
+
+## Usage
+
+### Use bash
+
+```bash
+$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1
+$ cd ant-design-pro
+$ npm install
+$ npm start         # visit http://localhost:8000
+```
+
+### Use by docker
+
+```bash
+# preview 
+$ docker pull chenshuai2144/ant-design-pro
+$ docker run -p 80:80 chenshuai2144/ant-design-pro
+# open http://localhost
+
+# dev 
+$ npm run docker:dev
+
+# build 
+$ npm run docker:build
+
+
+# production dev 
+$ npm run docker-prod:dev
+
+# production build 
+$ npm run docker-prod:build
+```
+
+More instructions at [documentation](http://pro.ant.design/docs/getting-started).
+
+## Browsers support
+
+Modern browsers and IE11.
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
+| --------- | --------- | --------- | --------- | --------- |
+| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
+
+## Contributing
+
+Any type of contribution is welcome, here are some examples of how you may contribute to this project:
+
+- Use Ant Design Pro in your daily work.
+- Submit [issues](http://github.com/ant-design/ant-design-pro/issues) to report bugs or ask questions.
+- Propose [pull requests](http://github.com/ant-design/ant-design-pro/pulls) to improve our code.
+
+
+**主题色转换需要调整两处:**
+1.defaultSettings.js
+2.themeColor.less
+3.更新antd主题色要重新install

+ 102 - 0
xinkeaboard-admin/README.ru-RU.md

@@ -0,0 +1,102 @@
+[English](./README.md) | [简体中文](./README.zh-CN.md) | Русский
+
+<h1 align="center">Ant Design Pro</h1>
+
+<div align="center">
+
+UI-решение "из коробки" для корпоративных приложений как React boilerplate
+
+[![CircleCI Status](https://circleci.com/gh/ant-design/ant-design-pro.svg?style=svg)](https://circleci.com/gh/ant-design/ant-design-pro/)
+[![Build status](https://ci.appveyor.com/api/projects/status/67fxu2by3ibvqtat/branch/master?svg=true)](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master)
+[![Dependencies](https://img.shields.io/david/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro)
+[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro?type=dev)
+[![Gitter](https://badges.gitter.im/ant-design/ant-design-pro.svg)](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+![](https://user-images.githubusercontent.com/8186664/44953195-581e3d80-aec4-11e8-8dcb-54b9db38ec11.png)
+
+</div>
+
+- Демо: http://preview.pro.ant.design
+- Домашняя страница: http://pro.ant.design
+- Документация: http://pro.ant.design/docs/getting-started
+- История изменений: http://pro.ant.design/docs/changelog
+- FAQ: http://pro.ant.design/docs/faq
+- Китайское зеркало сайта: http://ant-design-pro.gitee.io
+
+## Поиск переводчиков :loudspeaker:
+
+Нам нужна ваша помощь: https://github.com/ant-design/ant-design-pro/issues/120
+
+## Возможности
+
+- :gem: **Аккуратный дизайн**: Посмотрите [спецификацию Ant Design](http://ant.design/)
+- :triangular_ruler: **Общие шаблоны**: Стандартные шаблоны для корпоративных приложений
+- :rocket: **Разработка, как искусство**: Новейший стек технологий React/umi/dva/antd
+- :iphone: **Отзывчивая верстка**: Создан для экранов разных размеров
+- :art: **Темизация**: Возможность изменения темы с помощью конфигурации
+- :globe_with_meridians: **Мультиязычность**: Встроенное i18n решение
+- :gear: **Лучшие практики**: Надежные процессы для хорошего кода
+- :1234: **Разработка по шаблону**: Простое в использовании решение для разработки
+- :white_check_mark: **UI тесты**: Разрабатывайте безопасно с юнит и e2e тестами
+
+## Шаблоны
+
+```
+- Dashboard
+  - Analytic
+  - Monitor
+  - Workspace
+- Form
+  - Basic Form
+  - Step Form
+  - Advanced From
+- List
+  - Standard Table
+  - Standard List
+  - Card List
+  - Search List (Project/Applications/Article)
+- Profile
+  - Simple Profile
+  - Advanced Profile
+- Account
+  - Account Center
+  - Account Settings
+- Result
+  - Success
+  - Failed
+- Exception
+  - 403
+  - 404
+  - 500
+- User
+  - Login
+  - Register
+  - Register Result
+```
+
+## Использование
+
+```bash
+$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1
+$ cd ant-design-pro
+$ npm install
+$ npm start         # visit http://localhost:8000
+```
+
+Больше информации в [документации](http://pro.ant.design/docs/getting-started).
+
+## Совместимость
+
+Современные браузеры и IE11.
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
+| --------- | --------- | --------- | --------- | --------- |
+| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
+
+## Распространение
+
+Любые варианты распространения приветствуются! Вот несколько примеров того, как вы можете помочь распространению проекта:
+
+- Использовать Ant Design Pro в ежедневной работе.
+- Создавать [задачи](http://github.com/ant-design/ant-design-pro/issues) заводить баги или отвечать на вопросы.
+- Делать [pull-реквесты](http://github.com/ant-design/ant-design-pro/pulls) для совершенствования нашего кода.

+ 121 - 0
xinkeaboard-admin/README.zh-CN.md

@@ -0,0 +1,121 @@
+[English](./README.md) | 简体中文 | [Русский](./README.ru-RU.md)
+
+<h1 align="center">Ant Design Pro</h1>
+
+<div align="center">
+
+开箱即用的中台前端/设计解决方案。
+
+[![CircleCI Status](https://circleci.com/gh/ant-design/ant-design-pro.svg?style=svg)](https://circleci.com/gh/ant-design/ant-design-pro/)
+[![Build status](https://ci.appveyor.com/api/projects/status/67fxu2by3ibvqtat/branch/master?svg=true)](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master)
+[![Dependencies](https://img.shields.io/david/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro)
+[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro?type=dev)
+[![Gitter](https://badges.gitter.im/ant-design/ant-design-pro.svg)](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+![](https://user-images.githubusercontent.com/8186664/44953195-581e3d80-aec4-11e8-8dcb-54b9db38ec11.png)
+
+</div>
+
+- 预览:http://preview.pro.ant.design
+- 首页:http://pro.ant.design/index-cn
+- 使用文档:http://pro.ant.design/docs/getting-started-cn
+- 更新日志: http://pro.ant.design/docs/changelog-cn
+- 常见问题:http://pro.ant.design/docs/faq-cn
+- 国内镜像:http://ant-design-pro.gitee.io
+
+## 特性
+
+- :gem: **优雅美观**:基于 Ant Design 体系精心设计
+- :triangular_ruler: **常见设计模式**:提炼自中后台应用的典型页面和场景
+- :rocket: **最新技术栈**:使用 React/umi/dva/antd 等前端前沿技术开发
+- :iphone: **响应式**:针对不同屏幕大小设计
+- :art: **主题**:可配置的主题满足多样化的品牌诉求
+- :globe_with_meridians: **国际化**:内建业界通用的国际化方案
+- :gear: **最佳实践**:良好的工程实践助您持续产出高质量代码
+- :1234: **Mock 数据**:实用的本地数据调试方案
+- :white_check_mark: **UI 测试**:自动化测试保障前端产品质量
+
+## 模板
+
+```
+- Dashboard
+  - 分析页
+  - 监控页
+  - 工作台
+- 表单页
+  - 基础表单页
+  - 分步表单页
+  - 高级表单页
+- 列表页
+  - 查询表格
+  - 标准列表
+  - 卡片列表
+  - 搜索列表(项目/应用/文章)
+- 详情页
+  - 基础详情页
+  - 高级详情页
+- 用户
+  - 用户中心页
+  - 用户设置页
+- 结果
+  - 成功页
+  - 失败页
+- 异常
+  - 403 无权限
+  - 404 找不到
+  - 500 服务器出错
+- 帐户
+  - 登录
+  - 注册
+  - 注册成功
+```
+
+## 使用
+
+### 使用命令行
+```bash
+$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1
+$ cd ant-design-pro
+$ npm install
+$ npm start         # 访问 http://localhost:8000
+```
+
+### 使用 docker
+
+```bash
+# preview 
+$ docker pull chenshuai2144/ant-design-pro
+$ docker run -p 80:80 chenshuai2144/ant-design-pro
+# open http://localhost
+
+# dev 
+$ npm run docker:dev
+
+# build 
+$ npm run docker:build
+
+
+# production dev 
+$ npm run docker-prod:dev
+
+// production build 
+$ npm run docker-prod:build
+```
+
+更多信息请参考 [使用文档](http://pro.ant.design/docs/getting-started)。
+
+## 支持环境
+
+现代浏览器及 IE11。
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
+| --------- | --------- | --------- | --------- | --------- |
+| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
+
+## 参与贡献
+
+我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley::
+
+- 在你的公司或个人项目中使用 Ant Design Pro。
+- 通过 [Issue](http://github.com/ant-design/ant-design-pro/issues) 报告 bug 或进行咨询。
+- 提交 [Pull Request](http://github.com/ant-design/ant-design-pro/pulls) 改进 Pro 的代码。

+ 26 - 0
xinkeaboard-admin/appveyor.yml

@@ -0,0 +1,26 @@
+# Test against the latest version of this Node.js version
+environment:
+  nodejs_version: "8"
+
+# this is how to allow failing jobs in the matrix
+matrix:
+  fast_finish: true     # set this flag to immediately finish build once one of the jobs fails.
+
+# Install scripts. (runs after repo cloning)
+install:
+  # Get the latest stable version of Node.js or io.js
+  - ps: Install-Product node $env:nodejs_version
+  # install modules
+  - npm install
+  # Output useful info for debugging.
+  - node --version
+  - npm --version
+
+# Post-install test scripts.
+test_script:
+  - npm run lint
+  - npm run test:all
+  - npm run build
+
+# Don't actually build.
+build: off

+ 126 - 0
xinkeaboard-admin/config/config.js

@@ -0,0 +1,126 @@
+// https://umijs.org/config/
+import os from 'os';
+import pageRoutes from './router.config';
+import webpackPlugin from './plugin.config';
+import defaultSettings from '../src/defaultSettings';
+
+const plugins = [
+  [
+    'umi-plugin-react',
+    {
+      antd: true,
+      dva: {
+        hmr: true,
+      },
+      targets: {
+        ie: 11,
+      },
+      locale: {
+        enable: true, // default false
+        default: 'zh-CN', // default zh-CN
+        baseNavigator: false, // default true, when it is true, will use `navigator.language` overwrite default
+      },
+      dynamicImport: {
+        loadingComponent: './components/PageLoading/index',
+      },
+      pwa: {
+        workboxPluginMode: 'InjectManifest',
+        workboxOptions: {
+          importWorkboxFrom: 'local',
+        },
+      },
+      ...(!process.env.TEST && os.platform() === 'darwin'
+        ? {
+            dll: {
+              include: ['dva', 'dva/router', 'dva/saga', 'dva/fetch'],
+              exclude: ['@babel/runtime'],
+            },
+          }
+        : {}),
+    },
+  ],
+];
+
+// 针对 preview.pro.ant.design 的 GA 统计代码
+// 业务上不需要这个
+if (process.env.APP_TYPE === 'site') {
+  // plugins.push([
+  //   'umi-plugin-ga',
+  //   {
+  //     code: 'UA-72788897-6',
+  //   },
+  // ]);
+}
+const path = require('path')
+
+export default {
+  // add for transfer to umi
+  plugins,
+  targets: {
+    ie: 11,
+  },
+  define: {
+    APP_TYPE: process.env.APP_TYPE || '',
+  },
+  // 路由配置
+  routes: pageRoutes,
+  // Theme for antd
+  // https://ant.design/docs/react/customize-theme-cn
+  theme: {
+    'primary-color': defaultSettings.primaryColor,
+  },
+  externals: {
+    '@antv/data-set': 'DataSet',
+  },
+  // proxy: {
+  //   '/server/api/': {
+  //     target: 'https://preview.pro.ant.design/',
+  //     changeOrigin: true,
+  //     pathRewrite: { '^/server': '' },
+  //   },
+  // },
+  ignoreMomentLocale: true,
+  lessLoaderOptions: {
+    javascriptEnabled: true,
+  },
+  disableRedirectHoist: true,
+  cssLoaderOptions: {
+    modules: true,
+    getLocalIdent: (context, localIdentName, localName) => {
+      if (
+        context.resourcePath.includes('node_modules') ||
+        context.resourcePath.includes('ant.design.pro.less') ||
+        context.resourcePath.includes('global.less')
+      ) {
+        return localName;
+      }
+      const match = context.resourcePath.match(/src(.*)/);
+      if (match && match[1]) {
+        const antdProPath = match[1].replace('.less', '');
+        const arr = antdProPath
+          .split('/')
+          .map(a => a.replace(/([A-Z])/g, '-$1'))
+          .map(a => a.toLowerCase());
+        return `antd-pro${arr.join('-')}-${localName}`.replace(/--/g, '-');
+        // return `${localName}`;
+      }
+      return localName;
+    },
+
+    pluginOptions: {
+      "style-resources-loader": {
+        preProcessor: "less",
+        patterns: [
+          // 全局变量路径
+          path.resolve(__dirname, "./src/global.less"),
+        ],
+      },
+    }
+  },
+  manifest: {
+    basePath: '/',
+  },
+  publicPath: '/',
+
+  chainWebpack: webpackPlugin,
+};

+ 0 - 0
xinkeaboard-admin/config/config.local.js


+ 0 - 0
xinkeaboard-admin/config/config.test.js


+ 33 - 0
xinkeaboard-admin/config/plugin.config.js

@@ -0,0 +1,33 @@
+// Change theme plugin
+
+import MergeLessPlugin from 'antd-pro-merge-less';
+import AntDesignThemePlugin from 'antd-theme-webpack-plugin';
+import path from 'path';
+
+export default config => {
+  // pro 和 开发环境再添加这个插件
+  if (process.env.APP_TYPE === 'site' || process.env.NODE_ENV !== 'production') {
+    // 将所有 less 合并为一个供 themePlugin使用
+    const outFile = path.join(__dirname, '../.temp/ant-design-pro.less');
+    const stylesDir = path.join(__dirname, '../src/');
+
+    config.plugin('merge-less').use(MergeLessPlugin, [
+      {
+        stylesDir,
+        outFile,
+      },
+    ]);
+
+    config.plugin('ant-design-theme').use(AntDesignThemePlugin, [
+      {
+        antDir: path.join(__dirname, '../node_modules/antd'),
+        stylesDir,
+        varFile: path.join(__dirname, '../node_modules/antd/lib/style/themes/default.less'),
+        mainLessFile: outFile, //     themeVariables: ['@primary-color'],
+        indexFileName: 'index.html',
+        generateOne: true,
+        lessUrl: 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js',
+      },
+    ]);
+  }
+};

+ 1091 - 0
xinkeaboard-admin/config/router.config.js

@@ -0,0 +1,1091 @@
+export default [
+  // user
+  {
+    path: '/user',
+    component: '../layouts/UserLayout',
+    routes: [
+      { path: '/user', redirect: '/user/login' },
+      { path: '/user/login', component: './User/Login' },
+    ],
+  },
+  {
+    path: '/decorate_pc/diy_page_lists_to_edit',
+    component: '../layouts/UserLayout',
+    Routes: ['src/pages/CheckLogin'],
+    routes: [
+      { path: '/decorate_pc/diy_page_lists_to_edit', component: './decorate/pc/home/edit_diy_page' },
+    ],
+  },
+  {
+    path: '/decorate_pc/topic_diy_page_lists_to_edit',
+    component: '../layouts/UserLayout',
+    Routes: ['src/pages/CheckLogin'],
+    routes: [
+      { path: '/decorate_pc/topic_diy_page_lists_to_edit', component: './decorate/pc/home/edit_diy_page' },
+    ],
+  },
+  // doc
+  {
+    path: '/doc',
+    component: '../layouts/UserLayout',
+    routes: [
+      { path: '/doc', redirect: '/doc/list' },
+      { path: '/doc/list', component: './doc/doc_lists' },
+      { path: '/doc/detail', component: './doc/detail' },
+    ]
+  },
+  //商品详情
+  {
+    path: '/manage_product/goods_detail',
+    component: '../layouts/UserLayout',
+    routes: [
+      { path: '/manage_product/goods_detail', component: './manage/product/goods_common_detail' },
+    ],
+  },
+  //订单详情
+  {
+    path: '/manage_order/order_detail',
+    component: '../layouts/UserLayout',
+    name: '',
+    routes: [
+      { path: '/manage_order/order_detail', component: './manage/order/order_common_detail' },
+    ],
+  },
+  // app
+  {
+    path: '/',
+    component: '../layouts/BasicLayout',
+    Routes: ['src/pages/CheckLogin'],
+    routes: [
+      { path: '/', redirect: '/sysset_home/basic' },
+      //系统配置—首页管理
+      {
+        path: '/sysset_home',
+        icon: 'home',
+        name: 'home',
+        routes: [
+          //概况页
+          {
+            path: '/sysset_home/basic',
+            name: 'basic',
+            component: './sysset/home/basic',
+          },
+        ],
+      },
+      //系统配置—基本配置
+      {
+        path: '/sysset_setting',
+        icon: 'setting',
+        name: 'setting',
+        routes: [
+
+          // 站点配置
+          {
+            path: '/sysset_setting/site_info',
+            name: 'site_info',
+            component: './sysset/base/site_info',
+          },
+          //关于我们
+          {
+            path: '/sysset_setting/about_us',
+            name: 'about_us',
+            component: './sysset/base/about_us',
+          },
+          //引导留资
+          {
+            path: '/sysset_setting/guide_funds',
+            name: 'guide_funds',
+            component: './sysset/base/guide_funds',
+          },
+          //图片配置
+          {
+            path: '/sysset_setting/pic_set',
+            name: 'pic_set',
+            component: './sysset/base/pic_set',
+          },
+          //支付配置
+          {
+            path: '/sysset_setting/payment',
+            name: 'payment',
+            component: './sysset/base/payment',
+          },
+          //运营配置
+          {
+            path: '/sysset_setting/order',
+            name: 'order',
+            component: './sysset/base/order',
+          },
+          //APP配置
+          {
+            path: '/sysset_setting/app_set',
+            name: 'app_set',
+            component: './sysset/base/app_set',
+          },
+
+        ],
+      },
+      //系统配置—通知管理
+      {
+        path: '/sysset_notice_set',
+        icon: 'bell',
+        name: 'notice_set',
+        routes: [
+          //短信配置
+          {
+            path: '/sysset_notice_set/sms',
+            name: 'sms',
+            component: './sysset/notice_set/sms',
+          },
+          //邮件配置
+          {
+            path: '/sysset_notice_set/email',
+            name: 'email',
+            component: './sysset/notice_set/email',
+          },
+          //消息模板
+          {
+            path: '/sysset_notice_set/msg_tpl',
+            name: 'msg_tpl',
+            component: './sysset/notice_set/msg_tpl',
+          },
+
+        ],
+      },
+      // 系统配置—三方账号
+      {
+        path: '/sysset_acount',
+        icon: 'usergroup-add',
+        name: 'acount',
+        routes: [
+          //授权配置
+          {
+            path: '/sysset_acount/union_login',
+            name: 'union_login',
+            component: './sysset/acount/union_login',
+          },
+        ],
+      },
+      //系统配置—权限管理
+      {
+        path: '/sysset_authority',
+        icon: 'security-scan',
+        name: 'authority',
+        routes: [
+          //权限组
+          {
+            path: '/sysset_authority/authority_group',
+            name: 'authority_group',
+            component: './sysset/authority/group',
+          },
+          //操作员管理
+          {
+            path: '/sysset_authority/authority_member',
+            name: 'authority_member',
+            component: './sysset/authority/member',
+          },
+          //操作日志
+          {
+            path: '/sysset_authority/operate_log',
+            name: 'operate_log',
+            component: './sysset/authority/operate_log',
+          },
+        ],
+      },
+      //系统配置-协议管理
+      {
+        path: '/sysset_agreement',
+        icon: 'reconciliation',
+        name: 'agreement',
+        routes: [
+          //协议管理
+          {
+            path: '/sysset_agreement/lists',
+            name: 'lists',
+            component: './sysset/agreement/lists',
+          },
+          //编辑协议
+          {
+            path: '/sysset_agreement/lists_to_edit',
+            name: '',
+            component: './sysset/agreement/edit',
+          },
+        ],
+      },
+      //系统配置—物流管理
+      {
+        path: '/sysset_express',
+        icon: 'car',
+        name: 'express',
+        routes: [
+          //物流公司
+          {
+            path: '/sysset_express/express_lists',
+            name: 'express_lists',
+            component: './sysset/express/express_lists',
+          },
+          //物流配置
+          {
+            path: '/sysset_express/express',
+            name: 'express',
+            component: './sysset/express/express',
+          },
+        ],
+      },
+      // 会员管理
+      {
+        path: '/member',
+        name: 'member',
+        icon: 'usergroup-add',
+        routes: [
+          //会员列表
+          {
+            path: '/member/lists',
+            name: 'lists',
+            component: './member/lists',
+          },
+          //会员详情
+          {
+            path: '/member/lists_to_detail',
+            name: '',
+            component: './member/detail',
+          },
+          //商家列表
+          {
+            path: '/member/vendors',
+            name: 'vendors',
+            component: './member/vendors',
+          },
+          //充值管理
+          {
+            path: '/member/recharge',
+            name: 'recharge',
+            component: './member/recharge',
+          },
+          //提现管理
+          {
+            path: '/member/withdraw',
+            name: 'withdraw',
+            component: './member/withdraw',
+          },
+          //资金明细
+          {
+            path: '/member/balance_log',
+            name: 'balance_log',
+            component: './member/balance_log',
+          },
+          //积分设置
+          {
+            path: '/member/point_setting',
+            name: 'point_setting',
+            component: './member/point_set',
+          },
+        ],
+      },
+      // 商品管理
+      {
+        path: '/manage_product',
+        icon: 'appstore',
+        name: 'product',
+        routes: [
+          //商品设置
+          {
+            path: '/manage_product/goods_setting',
+            name: 'goods_setting',
+            component: './manage/product/goods_setting',
+          },
+          //商品列表
+          {
+            path: '/manage_product/goods_list',
+            name: 'goods_list',
+            component: './manage/product/goods_list',
+          },
+          //商品详情
+          {
+            path: '/manage_product/goods_list_to_detail',
+            name: '',
+            component: './manage/product/goods_detail',
+          },
+          //分类管理
+          {
+            path: '/manage_product/cate_lists',
+            name: 'cate_lists',
+            component: './manage/product/cate_lists',
+          },
+          //品牌列表
+          {
+            path: '/manage_product/brand',
+            name: 'brand',
+            component: './manage/product/brand',
+          },
+          //属性管理
+          {
+            path: '/manage_product/search_attr',
+            name: 'search_attr',
+            component: './manage/product/search_attr',
+          },
+          //商品标签
+          {
+            path: '/manage_product/goods_label',
+            name: 'goods_label',
+            component: './manage/product/goods_label',
+          },
+          //多媒体管理-admin
+          {
+            path: '/manage_product/media_list',
+            name: 'media_list',
+            component: './manage/product/media',
+          },
+        ],
+      },
+      // 商品库管理
+      {
+        path: '/manage_goods_platform',
+        icon: 'cloud-upload',
+        name: 'goods_platform',
+        routes: [
+          //商品资料库
+          {
+            path: '/manage_goods_platform/list',
+            name: 'list',
+            component: './manage/goods_platform/list',
+          },
+          //编辑商品资料
+          {
+            path: '/manage_goods_platform/list_to_edit',
+            name: '',
+            component: './manage/goods_platform/edit',
+          },
+          //添加商品资料
+          {
+            path: '/manage_goods_platform/add',
+            name: 'add',
+            component: './manage/goods_platform/add',
+          },
+          //LM商品库
+          {
+            path: '/manage_goods_platform/LM',
+            name: 'LM',
+            component: './manage/goods_platform/lm',
+          },
+          //VOP商品库
+          {
+            path: '/manage_goods_platform/VOP',
+            name: 'VOP',
+            component: './manage/goods_platform/vop',
+          },
+        ],
+      },
+      // PC装修
+      {
+        path: '/decorate_pc',
+        icon: 'cluster',
+        name: 'decorate_pc',
+        routes: [
+          // 实例化模版
+          {
+            path: '/decorate_pc/instance_template_lists',
+            name: 'instance_template_lists',
+            component: './decorate/pc/home/instance_template_lists',
+          },
+          // 新增/编辑模版
+          {
+            path: '/decorate_pc/instance_template_lists_to_add',
+            name: '',
+            component: './decorate/pc/home/add_template',
+          },
+          // // 测试模板
+          // {
+          //   path: '/decorate_pc/adv_21',
+          //   name: 'adv_21',
+          //   component: './decorate/pc/home/adv_21',
+          // },
+          // 首页装修
+          {
+            path: '/decorate_pc/diy_page_lists',
+            name: 'diy_page_lists',
+            component: './decorate/pc/home/diy_page_lists',
+          },
+          // 专题装修
+          {
+            path: '/decorate_pc/topic_diy_page_lists',
+            name: 'topic_diy_page_lists',
+            component: './decorate/pc/topic/topic_diy_page_lists',
+          },
+          // 首页广告
+          {
+            path: '/decorate_pc/home_setting',
+            name: 'home_setting',
+            component: './decorate/pc/home/home_setting',
+          },
+          // 首页导航
+          {
+            path: '/decorate_pc/nav',
+            name: 'nav',
+            component: './decorate/pc/home/nav',
+          },
+          //页脚管理
+          {
+            path: '/decorate_pc/footer',
+            name: 'footer',
+            component: './decorate/pc/home/footer',
+          },
+        ],
+      },
+      // 首页装修
+      {
+        path: '/decorate_m',
+        icon: 'mobile',
+        name: 'decorate_m',
+        routes: [
+          // 首页装修
+          {
+            path: '/decorate_m/lists',
+            name: 'lists',
+            component: './decorate/mobile/lists',
+          },
+          // 首页装修页面
+          {
+            path: '/decorate_m/lists_to_diy',
+            name: '',
+            component: './decorate/mobile/edit_diy_page',
+          },
+          // 专题装修
+          {
+            path: '/decorate_m/topic_lists',
+            name: 'topic_lists',
+            component: './decorate/mobile/topic_lists',
+          },
+          // 专题装修页面
+          {
+            path: '/decorate_m/topic_lists_to_diy',
+            name: '',
+            component: './decorate/mobile/edit_diy_page',
+          },
+          // 分类图片
+          {
+            path: '/decorate_m/cat_pic',
+            name: 'cat_pic',
+            component: './decorate/mobile/mcat',
+          },
+        ],
+      },
+      // 店铺管理
+      {
+        path: '/manage_store',
+        icon: 'shop',
+        name: 'store',
+        routes: [
+          //自营店铺
+          {
+            path: '/manage_store/own_list',
+            name: 'own_list',
+            component: './manage/store/own_list',
+          },
+          //入驻店铺
+          {
+            path: '/manage_store/settle_store_list',
+            name: 'settle_store_list',
+            component: './manage/store/settle_store_list',
+          },
+          //入驻审核店铺详情
+          {
+            path: '/manage_store/settle_store_list_apply_detail',
+            name: '',
+            component: './manage/store/apply_store_detail',
+          },
+          //店铺入驻信息详情
+          {
+            path: '/manage_store/settle_store_list_view',
+            name: '',
+            component: './manage/store/settled_store_detail',
+          },
+          //编辑店铺入驻信息
+          {
+            path: '/manage_store/settle_store_list_to_edit',
+            name: '',
+            component: './manage/store/edit_settled_store',
+          },
+          //店铺等级
+          {
+            path: '/manage_store/grade_list',
+            name: 'grade_list',
+            component: './manage/store/grade_list',
+          },
+          //售后原因
+          {
+            path: '/manage_store/salereson_lists',
+            name: 'salereson_lists',
+            component: './manage/order/salereson_lists',
+          },
+        ],
+      },
+      // 订单管理
+      {
+        path: '/manage_order',
+        icon: 'form',
+        name: 'order',
+        routes: [
+          //订单列表
+          {
+            path: '/manage_order/order_lists',
+            name: 'order_lists',
+            component: './manage/order/order_lists',
+          },
+          //订单详情
+          {
+            path: '/manage_order/order_lists_to_detail',
+            name: '',
+            component: './manage/order/order_detail',
+          },
+          //售后管理
+          {
+            path: '/manage_order/service',
+            name: 'service',
+            component: './manage/order/service',
+          },
+          //评价管理
+          {
+            path: '/manage_order/evaluation',
+            name: 'evaluation',
+            component: './manage/order/evaluation',
+          },
+          //询盘管理
+          {
+            path: '/manage_order/enquiry',
+            name: 'enquiry',
+            component: './manage/order/enquiry/enquiry_lists',
+          },
+          //询盘跟踪记录
+          {
+            path: '/manage_order/enquiry_track_to_add',
+            icon: '',
+            name: 'enquiry_track_to_add',
+            component: './manage/order/enquiry/add_track',
+          },
+          //询盘邮箱配置
+          {
+            path: '/manage_order/enquiry_receive_mail_setting',
+            name: 'enquiry_receive_mail_setting',
+            component: './manage/order/enquiry/receive_mail_setting',
+          },
+        ],
+      },
+      // 结算管理
+      {
+        path: '/manage_bill',
+        icon: 'pay-circle',
+        name: 'bill',
+        routes: [
+          //结算账单
+          {
+            path: '/manage_bill/lists',
+            name: 'lists',
+            component: './manage/bill/lists',
+          },
+          //结算账单详情
+          {
+            path: '/manage_bill/lists_to_detail',
+            name: '',
+            component: './manage/bill/detail',
+          },
+        ],
+      },
+      // 文章管理
+      {
+        path: '/manage_article',
+        icon: 'file-word',
+        name: 'article',
+        routes: [
+          {
+            path: '/manage_article/article_cat_lists',
+            name: 'article_cat_lists',
+            component: './manage/article/article_cat_lists',
+          }, {
+            path: '/manage_article/article_lists',
+            name: 'article_lists',
+            component: './manage/article/article_lists',
+          }, {
+            path: '/manage_article/article_lists_to_add',
+            component: './manage/article/add_article',
+          },
+        ],
+      },
+
+      //帮助管理
+      {
+        path: '/manage_help',
+        icon: 'file-word',
+        name: 'help',
+        routes: [
+          {
+            path: '/manage_help/category_list',
+            name: 'category_list',
+            component: './manage/help/article_cat_lists',
+          }, {
+            path: '/manage_help/article_list',
+            name: 'article_list',
+            component: './manage/help/article_lists',
+          }, {
+            path: '/manage_help/article_lists_to_add',
+            component: './manage/help/add_article',
+          },
+        ],
+      },
+      // 促销活动
+      {
+        path: '/marketing_promotion',
+        icon: 'chrome',
+        name: 'promotion',
+        routes: [
+          //优惠券
+          {
+            path: '/marketing_promotion/center',
+            name: 'center',
+            component: './marketing/promotion/center',
+          },
+          //优惠券
+          {
+            path: '/marketing_promotion/coupon',
+            name: 'coupon',
+            component: './marketing/promotion/coupon/home',
+          },
+          //新建优惠券
+          {
+            path: '/marketing_promotion/coupon_to_add',
+            name: '',
+            component: './marketing/promotion/coupon/add_coupon',
+          },
+          //平台优惠券——查看优惠券
+          {
+            path: '/marketing_promotion/coupon_to_view',
+            name: '',
+            component: './marketing/promotion/coupon/view_coupon',
+          },
+          //平台优惠券——优惠券领取列表
+          {
+            path: '/marketing_promotion/coupon_to_receive_list',
+            name: '',
+            component: './marketing/promotion/coupon/member_receive_lists',
+          },
+          //店铺优惠券
+          {
+            path: '/marketing_promotion/store_coupon',
+            name: 'store_coupon',
+            component: './marketing/promotion/coupon/store_coupon',
+          },
+          //店铺优惠券——查看优惠券
+          {
+            path: '/marketing_promotion/store_coupon_to_view',
+            name: '',
+            component: './marketing/promotion/coupon/view_coupon',
+          },
+          //店铺优惠券——优惠券领取列表
+          {
+            path: '/marketing_promotion/store_coupon_to_receive_list',
+            name: '',
+            component: './marketing/promotion/coupon/member_receive_lists',
+          },
+          //排行榜
+          {
+            path: '/marketing_promotion/rank',
+            name: 'rank',
+            component: './marketing/promotion/rank/index',
+          },
+          //关联榜单
+          {
+            path: '/marketing_promotion/rank_to_bind',
+            name: '',
+            component: './marketing/promotion/rank/bind_rank_lists',
+          },
+          //新建排行榜
+          {
+            path: '/marketing_promotion/rank_to_add',
+            name: '',
+            component: './marketing/promotion/rank/add',
+          },
+          //积分抵扣
+          {
+            path: '/marketing_promotion/point_setting',
+            name: 'point_setting',
+            component: './marketing/promotion/point_setting',
+          },
+          //满优惠列表
+          {
+            path: '/marketing_promotion/full_discount',
+            name: 'full_discount',
+            component: './marketing/promotion/full/discount',
+          },
+          //秒杀活动
+          {
+            path: '/marketing_promotion/seckill',
+            name: 'seckill',
+            component: './marketing/promotion/seckill/lists',
+          },
+          //秒杀活动详情——秒杀活动场次
+          {
+            path: '/marketing_promotion/seckill_detail',
+            name: '',
+            component: './marketing/promotion/seckill/detail',
+          },
+          //秒杀活动商品
+          {
+            path: '/marketing_promotion/seckill_goods_list',
+            name: '',
+            component: './marketing/promotion/seckill/seckill_goods_lists',
+          },
+          //拼团活动
+          {
+            path: '/marketing_promotion/spell_group',
+            name: 'spell_group',
+            component: './marketing/promotion/spell_group/lists',
+          },
+          //拼团活动——查看详情
+          {
+            path: '/marketing_promotion/spell_group_to_view',
+            name: '',
+            component: './marketing/promotion/spell_group/view_spell_group',
+          },
+          //拼团活动商品
+          {
+            path: '/marketing_promotion/spell_group_bind_goods',
+            name: '',
+            component: './marketing/promotion/spell_group/joined_goods_list',
+          },
+          //拼团活动订单
+          {
+            path: '/marketing_promotion/spell_group_order',
+            name: '',
+            component: './marketing/promotion/spell_group/order_lists',
+          },
+          //拼团活动订单详情
+          {
+            path: '/marketing_promotion/spell_group_order_to_detail',
+            name: '',
+            component: './manage/order/order_detail',
+          },
+          //拼团团队列表
+          {
+            path: '/marketing_promotion/spell_group_team_list',
+            name: '',
+            component: './marketing/promotion/spell_group/team_list',
+          },
+          //阶梯团活动
+          {
+            path: '/marketing_promotion/ladder_group',
+            name: 'ladder_group',
+            component: './marketing/promotion/ladder_group/lists',
+          },
+          //阶梯团活动——查看详情
+          {
+            path: '/marketing_promotion/ladder_group_to_view',
+            name: '',
+            component: './marketing/promotion/ladder_group/view_ladder_group',
+          },
+          //阶梯团活动——团队列表
+          {
+            path: '/marketing_promotion/ladder_group_team_list',
+            name: '',
+            component: './marketing/promotion/ladder_group/team_list',
+          },
+          //预售活动
+          {
+            path: '/marketing_promotion/presale',
+            name: 'presale',
+            component: './marketing/promotion/presale/lists',
+          },
+          //预售详情
+          {
+            path: '/marketing_promotion/presale_to_view',
+            name: '',
+            component: './marketing/promotion/presale/view_presale',
+          },
+          //预售活动商品
+          {
+            path: '/marketing_promotion/presale_goods_list',
+            name: '',
+            component: './marketing/promotion/presale/presale_goods_lists',
+          },
+          //签到统计列表
+          {
+            path: '/marketing_promotion/sign',
+            name: 'sign',
+            component: './marketing/sign/stat',
+          },
+          //新建签到活动
+          {
+            path: '/marketing_promotion/sign_to_add',
+            name: '',
+            component: './marketing/sign/add',
+          },
+          //会员签到统计详情
+          {
+            path: '/marketing_promotion/sign_to_member_detail',
+            name: '',
+            component: './marketing/sign/member_stat_detail',
+          },
+          //活动签到详情
+          {
+            path: '/marketing_promotion/sign_to_activity_detail',
+            name: '',
+            component: './marketing/sign/activity_stat_detail',
+          },
+          //幸运抽奖列表
+          {
+            path: '/marketing_promotion/lucky_draw_list',
+            name: 'lucky_list',
+            component: './marketing/draw/lucky_list',
+          },
+          //新建幸运抽奖活动
+          {
+            path: '/marketing_promotion/lucky_draw_list_to_add',
+            name: '',
+            component: './marketing/draw/add',
+          },
+          //大转盘抽奖
+          {
+            path: '/marketing_promotion/turnplate_list',
+            name: 'turnplate_list',
+            component: './marketing/draw/turnplate_list',
+          },
+          //新建大转盘抽奖活动
+          {
+            path: '/marketing_promotion/turnplate_list_to_add',
+            name: '',
+            component: './marketing/draw/add',
+          },
+          //刮刮卡
+          {
+            path: '/marketing_promotion/scratch_list',
+            name: 'scratch_list',
+            component: './marketing/draw/scratch_list',
+          },
+          //新建刮刮卡活动
+          {
+            path: '/marketing_promotion/scratch_list_to_add',
+            name: '',
+            component: './marketing/draw/add',
+          },
+          //摇一摇
+          {
+            path: '/marketing_promotion/shake_list',
+            name: 'shake_list',
+            component: './marketing/draw/shake_list',
+          },
+          //新建摇一摇活动
+          {
+            path: '/marketing_promotion/shake_list_to_add',
+            name: '',
+            component: './marketing/draw/add',
+          },
+          //翻翻看
+          {
+            path: '/marketing_promotion/turn_list',
+            name: 'turn_list',
+            component: './marketing/draw/turn_list',
+          },
+          //新建翻翻看活动
+          {
+            path: '/marketing_promotion/turn_list_to_add',
+            name: '',
+            component: './marketing/draw/add',
+          },
+        ],
+      },
+
+      // 统计中心
+      {
+        path: '/statistics',
+        icon: 'pie-chart',
+        name: 'statistics',
+        routes: [
+          //实时分析
+          {
+            path: '/statistics/realtime',
+            name: 'realtime',
+            component: './statistics/realtime',
+          },
+          //交易分析
+          {
+            path: '/statistics/trade',
+            name: 'trade',
+            component: './statistics/trade',
+          },
+          //流量分析
+          {
+            path: '/statistics/flow',
+            name: 'flow',
+            component: './statistics/flow',
+          },
+          //商品动销
+          {
+            path: '/statistics/goods_saling',
+            name: 'goods_saling',
+            component: './statistics/goods_saling',
+          },
+          //商品品类
+          {
+            path: '/statistics/goods_category',
+            name: 'goods_category',
+            component: './statistics/goods_category',
+          },
+          //会员分析
+          {
+            path: '/statistics/member',
+            name: 'member',
+            component: './statistics/member',
+          },
+          //店铺分析
+          {
+            path: '/statistics/store',
+            name: 'store',
+            component: './statistics/store',
+          },
+          //地域分析
+          {
+            path: '/statistics/region',
+            name: 'region',
+            component: './statistics/region',
+          }
+        ]
+      },
+      //svideo-start
+      //短视频
+      {
+        path: '/marketing_svideo',
+        icon: 'pay-circle',
+        name: 'svideo',
+        routes: [
+          //短视频设置
+          {
+            path: '/marketing_svideo/setting',
+            name: 'setting',
+            component: './marketing/svideo/setting',
+          },
+          //标签管理
+          {
+            path: '/marketing_svideo/label',
+            name: 'label',
+            component: './marketing/svideo/label',
+          },
+          //推荐主题
+          {
+            path: '/marketing_svideo/video_theme',
+            name: 'theme',
+            component: './marketing/svideo/theme',
+          },
+          //新增推荐主题
+          {
+            path: '/marketing_svideo/video_theme_to_add',
+            name: '',
+            component: './marketing/svideo/add_theme',
+          },
+          //推荐主题绑定的视频
+          {
+            path: '/marketing_svideo/video_theme_bind_video',
+            name: '',
+            component: './marketing/svideo/view_theme_video',
+          },
+          //作者管理
+          {
+            path: '/marketing_svideo/author_manage',
+            name: 'author_manage',
+            component: './marketing/svideo/author_manage',
+          },
+          //作品管理
+          {
+            path: '/marketing_svideo/video_manage',
+            name: 'video_manage',
+            component: './marketing/svideo/video_manage',
+          },
+          //视频绑定的商品
+          {
+            path: '/marketing_svideo/video_manage_bind_goods',
+            name: '',
+            component: './marketing/svideo/video_goods',
+          },
+          //评论管理
+          {
+            path: '/marketing_svideo/comment_lists',
+            name: 'comment_lists',
+            component: './marketing/svideo/comment_lists',
+          },
+          //查看视频评论
+          {
+            path: '/marketing_svideo/comment_lists_to_view',
+            name: '',
+            component: './marketing/svideo/view_video_comments',
+          },
+        ]
+      },
+      //svideo-end
+
+
+      // 积分商城
+      {
+        path: '/marketing_point',
+        icon: 'transaction',
+        name: 'point',
+        routes: [
+          //积分商城——首页装修
+          {
+            path: '/marketing_point/diy_home',
+            name: 'diy_home',
+            component: './marketing/point/mdiy/home',
+          },
+          // 装修页面
+          {
+            path: '/marketing_point/diy_home_to_edit',
+            name: '',
+            component: './marketing/point/mdiy/edit_diy_page',
+          },
+          //积分商城——积分设置
+          {
+            path: '/marketing_point/setting',
+            name: 'setting',
+            component: './marketing/point/setting',
+          },
+          //积分商城——标签管理
+          {
+            path: '/marketing_point/label',
+            name: 'label',
+            component: './marketing/point/label',
+          },
+          //积分商城——商品管理
+          {
+            path: '/marketing_point/goods_list',
+            name: 'goods_list',
+            component: './marketing/point/goods/goods_list',
+          },
+          //积分商城——订单管理
+          {
+            path: '/marketing_point/order_list',
+            name: 'order_list',
+            component: './marketing/point/order/order_lists',
+          },
+          //积分商城——订单详情
+          {
+            path: '/marketing_point/order_list_to_detail',
+            name: '',
+            component: './marketing/point/order/order_detail',
+          },
+          //积分商城——结算管理
+          {
+            path: '/marketing_point/bill_list',
+            name: 'bill_list',
+            component: './marketing/point/bill/lists',
+          },
+          //积分商城——结算详情
+          {
+            path: '/marketing_point/bill_list_to_detail',
+            name: '',
+            component: './marketing/point/bill/detail',
+          },
+        ]
+      },
+
+      {
+        component: '404',
+      },
+    ],
+  },
+];

+ 14 - 0
xinkeaboard-admin/docker/docker-compose.dev.yml

@@ -0,0 +1,14 @@
+version: "3.5"
+
+services:
+  ant-design-pro_dev:
+    ports:
+      - 8000:8000
+    build:
+      context: ../
+      dockerfile: Dockerfile.dev
+    container_name: "ant-design-pro_dev"
+    volumes:
+      - ../src:/usr/src/app/src
+      - ../config:/usr/src/app/config
+      - ../mock:/usr/src/app/mock

+ 21 - 0
xinkeaboard-admin/docker/docker-compose.yml

@@ -0,0 +1,21 @@
+version: "3.5"
+
+services:
+  ant-design-pro_build:
+    build: ../
+    container_name: "ant-design-pro_build"
+    volumes:
+      - dist:/usr/src/app/dist
+
+  ant-design-pro_web:
+    image: nginx
+    ports:
+      - 80:80
+    container_name: "ant-design-pro_web"
+    restart: unless-stopped
+    volumes:
+      - dist:/usr/share/nginx/html:ro
+      - ./nginx.conf:/etc/nginx/conf.d/default.conf
+
+volumes:
+  dist:

+ 22 - 0
xinkeaboard-admin/docker/nginx.conf

@@ -0,0 +1,22 @@
+server {
+    listen 80;
+    # gzip config
+    gzip on;
+    gzip_min_length 1k;
+    gzip_comp_level 9;
+    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
+    gzip_vary on;
+    gzip_disable "MSIE [1-6]\.";
+
+    root /usr/share/nginx/html;
+
+    location / {
+        try_files $uri $uri/ /index.html;
+    }
+    location /api {
+        proxy_pass https://preview.pro.ant.design;
+        proxy_set_header   X-Forwarded-Proto $scheme;
+        proxy_set_header   Host              $http_host;
+        proxy_set_header   X-Real-IP         $remote_addr;
+    }
+}

+ 13 - 0
xinkeaboard-admin/firebase.json

@@ -0,0 +1,13 @@
+{
+  "hosting": {
+    "public": "dist",
+    "rewrites": [
+      { "source": "/api/**", "function": "api" },
+      {
+        "source": "**",
+        "destination": "/index.html"
+      }
+    ],
+    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
+  }
+}

+ 9 - 0
xinkeaboard-admin/functions/index.js

@@ -0,0 +1,9 @@
+// [START functionsimport]
+const functions = require('firebase-functions');
+const express = require('express');
+const matchMock = require('./matchMock');
+const app = express();
+
+app.use(matchMock);
+
+exports.api = functions.https.onRequest(app);

+ 117 - 0
xinkeaboard-admin/functions/matchMock.js

@@ -0,0 +1,117 @@
+const mockFile = require('./mock/index');
+const pathToRegexp = require('path-to-regexp');
+const debug = console.log;
+const bodyParser = require('body-parser');
+
+const BODY_PARSED_METHODS = ['post', 'put', 'patch'];
+
+function parseKey(key) {
+  let method = 'get';
+  let path = key;
+  if (key.indexOf(' ') > -1) {
+    const splited = key.split(' ');
+    method = splited[0].toLowerCase();
+    path = splited[1]; // eslint-disable-line
+  }
+  return {
+    method,
+    path,
+  };
+}
+
+function createHandler(method, path, handler) {
+  return function(req, res, next) {
+    if (BODY_PARSED_METHODS.includes(method)) {
+      bodyParser.json({ limit: '5mb', strict: false })(req, res, () => {
+        bodyParser.urlencoded({ limit: '5mb', extended: true })(req, res, () => {
+          sendData();
+        });
+      });
+    } else {
+      sendData();
+    }
+
+    function sendData() {
+      if (typeof handler === 'function') {
+        handler(req, res, next);
+      } else {
+        res.json(handler);
+      }
+    }
+  };
+}
+
+function normalizeConfig(config) {
+  return Object.keys(config).reduce((memo, key) => {
+    const handler = config[key];
+    const { method, path } = parseKey(key);
+    const keys = [];
+    const re = pathToRegexp(path, keys);
+    memo.push({
+      method,
+      path,
+      re,
+      keys,
+      handler: createHandler(method, path, handler),
+    });
+    return memo;
+  }, []);
+}
+
+const mockData = normalizeConfig(mockFile);
+
+function matchMock(req) {
+  const { path: exceptPath } = req;
+  const exceptMethod = req.method.toLowerCase();
+  for (const mock of mockData) {
+    const { method, re, keys } = mock;
+    if (method === exceptMethod) {
+      const match = re.exec(req.path);
+      if (match) {
+        const params = {};
+
+        for (let i = 1; i < match.length; i = i + 1) {
+          const key = keys[i - 1];
+          const prop = key.name;
+          const val = decodeParam(match[i]);
+
+          if (val !== undefined || !hasOwnProperty.call(params, prop)) {
+            params[prop] = val;
+          }
+        }
+        req.params = params;
+        return mock;
+      }
+    }
+  }
+
+  function decodeParam(val) {
+    if (typeof val !== 'string' || val.length === 0) {
+      return val;
+    }
+
+    try {
+      return decodeURIComponent(val);
+    } catch (err) {
+      if (err instanceof URIError) {
+        err.message = `Failed to decode param ' ${val} '`;
+        err.status = err.statusCode = 400;
+      }
+
+      throw err;
+    }
+  }
+
+  return mockData.filter(({ method, re }) => {
+    return method === exceptMethod && re.test(exceptPath);
+  })[0];
+}
+module.exports = (req, res, next) => {
+  const match = matchMock(req);
+  if (match) {
+    debug(`mock matched: [${match.method}] ${match.path}`);
+    return match.handler(req, res, next);
+  } else {
+    return next();
+  }
+};

+ 11 - 0
xinkeaboard-admin/functions/mock/index.js

@@ -0,0 +1,11 @@
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+	typeof define === 'function' && define.amd ? define(factory) :
+	(global.mock = factory());
+}(this, (function () { 'use strict';
+
+	const data = Object.assign({},);
+
+	return data;
+
+})));

+ 23 - 0
xinkeaboard-admin/functions/package.json

@@ -0,0 +1,23 @@
+{
+  "name": "functions",
+  "description": "Cloud Functions for Firebase",
+  "scripts": {
+    "serve": "npm run mock && firebase serve --only functions",
+    "shell": "firebase functions:shell",
+    "start": "npm run shell",
+    "deploy": "firebase deploy --only functions",
+    "logs": "firebase functions:log",
+    "mock": "node ../scripts/generateMock.js"
+  },
+  "dependencies": {
+    "@babel/runtime": "^7.0.0",
+    "body-parser": "^1.18.3",
+    "express": "^4.16.3",
+    "firebase-admin": "^5.12.1",
+    "firebase-functions": "^2.0.5",
+    "mockjs": "^1.0.1-beta3",
+    "moment": "^2.22.2",
+    "path-to-regexp": "^2.2.1"
+  },
+  "private": true
+}

+ 15 - 0
xinkeaboard-admin/jest-puppeteer.config.js

@@ -0,0 +1,15 @@
+// ps https://github.com/GoogleChrome/puppeteer/issues/3120
+module.exports = {
+  launch: {
+    headless: false,
+    args: [
+      '--disable-gpu',
+      '--disable-dev-shm-usage',
+      '--disable-setuid-sandbox',
+      '--no-first-run',
+      '--no-sandbox',
+      '--no-zygote',
+      '--single-process',
+    ],
+  },
+};

+ 4 - 0
xinkeaboard-admin/jest.config.js

@@ -0,0 +1,4 @@
+module.exports = {
+  testURL: 'http://localhost:8000',
+  preset: 'jest-puppeteer',
+};

+ 10 - 0
xinkeaboard-admin/jsconfig.json

@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  }
+}

+ 13 - 0
xinkeaboard-admin/netlify.toml

@@ -0,0 +1,13 @@
+[[redirects]]
+  from = "/api/*"
+  to = "https://us-central1-antd-pro.cloudfunctions.net/api/api/:splat"
+  status = 200
+  force = true
+  [redirects.headers]
+    X-From = "Netlify"
+    X-Api-Key = "some-api-key-string"
+
+[[redirects]]
+  from = "/*"
+  to = "/index.html"
+  status = 200

+ 138 - 0
xinkeaboard-admin/package.json

@@ -0,0 +1,138 @@
+{
+  "name": "ant-design-pro",
+  "version": "2.1.1",
+  "description": "An out-of-box UI solution for enterprise applications",
+  "private": true,
+  "scripts": {
+    "presite": "node ./scripts/generateMock.js && cd functions && npm install",
+    "start": "cross-env APP_TYPE=site umi dev --port=8107 --max_old_space_size=6666",
+    "start:no-mock": "cross-env MOCK=none umi dev",
+    "build": "umi build",
+    "site": "npm run presite && cross-env APP_TYPE=site npm run build && firebase deploy && npm run docker:push",
+    "analyze": "cross-env ANALYZE=1 umi build",
+    "lint:style": "stylelint \"src/**/*.less\" --syntax less",
+    "lint": "eslint --ext .js src mock tests && npm run lint:style",
+    "lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style",
+    "lint-staged": "lint-staged",
+    "lint-staged:js": "eslint --ext .js",
+    "tslint": "npm run tslint:fix",
+    "tslint:fix": "tslint --fix 'src/**/*.ts*'",
+    "test": "umi test",
+    "test:component": "umi test ./src/components",
+    "test:all": "node ./tests/run-tests.js",
+    "prettier": "node ./scripts/prettier.js",
+    "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up",
+    "docker:build": "docker-compose -f ./docker/docker-compose.dev.yml build",
+    "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up",
+    "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build",
+    "docker-hub:build": "docker build  -f Dockerfile.hub -t  ant-design-pro ./",
+    "docker:tag": "docker tag ant-design-pro chenshuai2144/ant-design-pro",
+    "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push chenshuai2144/ant-design-pro"
+  },
+  "dependencies": {
+    "@ant-design/charts": "1.2.7",
+    "@antv/data-set": "^0.10.0",
+    "@babel/runtime": "^7.1.5",
+    "antd": "^3.16.6",
+    "bizcharts": "^3.5.9",
+    "bizcharts-plugin-slider": "^2.1.1-beta.1",
+    "classnames": "^2.2.6",
+    "dva": "^2.4.0",
+    "enquire-js": "^0.2.1",
+    "hash.js": "^1.1.5",
+    "jquery": "^3.5.1",
+    "lodash": "^4.17.10",
+    "lodash-decorators": "^6.0.0",
+    "memoize-one": "^5.0.0",
+    "moment": "^2.22.2",
+    "numeral": "^2.0.6",
+    "nzh": "^1.0.3",
+    "omit.js": "^1.0.0",
+    "path-to-regexp": "^2.4.0",
+    "prop-types": "^15.5.10",
+    "qrcode.react": "^0.9.3",
+    "qs": "^6.6.0",
+    "quill-delta-to-html": "^0.10.7",
+    "rc-animate": "^2.4.4",
+    "rc-tween-one": "^2.7.3",
+    "re-resizable": "^4.11.0",
+    "react": "^16.14.0",
+    "react-activation": "^0.10.1",
+    "react-beautiful-dnd": "^10.1.1",
+    "react-color": "^2.14.1",
+    "react-container-query": "^0.11.0",
+    "react-copy-to-clipboard": "^5.0.1",
+    "react-custom-scrollbars": "^4.2.1",
+    "react-document-title": "^2.0.3",
+    "react-dom": "^16.6.3",
+    "react-fittext": "^1.0.0",
+    "react-marquee": "^1.0.0",
+    "react-media": "^1.8.0",
+    "react-quill": "^1.3.3",
+    "react-resizable": "1.7.5",
+    "react-router-dom": "^4.3.1",
+    "react-slick": "^0.27.11",
+    "slick-carousel": "^1.8.1",
+    "ml-matrix": "6.5.0"
+  },
+  "resolutions": {
+    "ml-matrix": "6.5.0"
+  },
+  "devDependencies": {
+    "@types/react": "^16.7.7",
+    "@types/react-dom": "^16.0.10",
+    "antd-pro-merge-less": "^1.0.0",
+    "antd-theme-webpack-plugin": "^1.1.8",
+    "babel-eslint": "^10.0.1",
+    "cross-env": "^5.1.1",
+    "cross-port-killer": "^1.0.1",
+    "enzyme": "^3.7.0",
+    "eslint": "^5.4.0",
+    "eslint-config-airbnb": "^17.0.0",
+    "eslint-config-prettier": "^3.0.1",
+    "eslint-plugin-babel": "^5.3.0",
+    "eslint-plugin-compat": "^2.6.2",
+    "eslint-plugin-import": "^2.14.0",
+    "eslint-plugin-jsx-a11y": "^6.1.2",
+    "eslint-plugin-markdown": "^1.0.0-beta.6",
+    "eslint-plugin-react": "^7.11.1",
+    "gh-pages": "^2.0.1",
+    "husky": "^1.2.0",
+    "jest-puppeteer": "^3.5.1",
+    "lint-staged": "^8.1.0",
+    "merge-umi-mock-data": "^0.0.3",
+    "mockjs": "^1.0.1-beta3",
+    "prettier": "1.15.2",
+    "pro-download": "^1.0.1",
+    "style-resources-loader": "^1.5.0",
+    "stylelint": "^9.8.0",
+    "stylelint-config-prettier": "^4.0.0",
+    "stylelint-config-standard": "^18.0.0",
+    "tslint": "^5.10.0",
+    "tslint-config-prettier": "^1.10.0",
+    "tslint-react": "^3.6.0",
+    "umi": "^2.2.7",
+    "umi-plugin-ga": "^1.1.3",
+    "umi-plugin-react": "^1.2.0",
+    "vue-cli-plugin-style-resources-loader": "^0.1.5"
+  },
+  "optionalDependencies": {
+    "puppeteer": "^1.10.0"
+  },
+  "lint-staged": {
+    "**/*.{jsx}": "npm run lint-staged:js"
+  },
+  "engines": {
+    "node": ">=8.0.0"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 10"
+  ],
+  "husky": {
+    "hooks": {
+      "pre-commit": "npm run lint-staged"
+    }
+  }
+}

+ 40 - 0
xinkeaboard-admin/public/UEditor/dialogs/anchor/anchor.html

@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+    "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+        <title></title>
+        <style type="text/css">
+            *{color: #838383;margin: 0;padding: 0}
+            html,body {font-size: 12px;overflow: hidden; }
+            .content{padding:5px 0 0 15px;}
+            input{width:210px;height:21px;line-height:21px;margin-left: 4px;}
+        </style>
+    </head>
+    <body>
+        <div class="content">
+            <span><var id="lang_input_anchorName"></var></span><input id="anchorName"  value="" />
+        </div>
+        <script type="text/javascript" src="../internal.js"></script>
+        <script type="text/javascript">
+            var anchorInput = $G('anchorName'),
+                node = editor.selection.getRange().getClosedNode();
+            if(node && node.tagName == 'IMG' && (node = node.getAttribute('anchorname'))){
+                anchorInput.value = node;
+            }
+            anchorInput.onkeydown = function(evt){
+                evt = evt || window.event;
+                if(evt.keyCode == 13){
+                    editor.execCommand('anchor', anchorInput.value);
+                    dialog.close();
+                    domUtils.preventDefault(evt)
+                }
+            };
+            dialog.onok = function (){
+                editor.execCommand('anchor', anchorInput.value);
+                dialog.close();
+            };
+            $focus(anchorInput);
+        </script>
+    </body>
+</html>

+ 681 - 0
xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.css

@@ -0,0 +1,681 @@
+@charset "utf-8";
+/* dialog样式 */
+.wrapper {
+    zoom: 1;
+    width: 630px;
+    *width: 626px;
+    height: 380px;
+    margin: 0 auto;
+    padding: 10px;
+    position: relative;
+    font-family: sans-serif;
+}
+
+/*tab样式框大小*/
+.tabhead {
+    float:left;
+}
+.tabbody {
+    width: 100%;
+    height: 346px;
+    position: relative;
+    clear: both;
+}
+
+.tabbody .panel {
+    position: absolute;
+    width: 0;
+    height: 0;
+    background: #fff;
+    overflow: hidden;
+    display: none;
+}
+
+.tabbody .panel.focus {
+    width: 100%;
+    height: 346px;
+    display: block;
+}
+
+/* 上传附件 */
+.tabbody #upload.panel {
+    width: 0;
+    height: 0;
+    overflow: hidden;
+    position: absolute !important;
+    clip: rect(1px, 1px, 1px, 1px);
+    background: #fff;
+    display: block;
+}
+
+.tabbody #upload.panel.focus {
+    width: 100%;
+    height: 346px;
+    display: block;
+    clip: auto;
+}
+
+#upload .queueList {
+    margin: 0;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    overflow: hidden;
+}
+
+#upload p {
+    margin: 0;
+}
+
+.element-invisible {
+    width: 0 !important;
+    height: 0 !important;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    overflow: hidden;
+    position: absolute !important;
+    clip: rect(1px, 1px, 1px, 1px);
+}
+
+#upload .placeholder {
+    margin: 10px;
+    border: 2px dashed #e6e6e6;
+    *border: 0px dashed #e6e6e6;
+    height: 172px;
+    padding-top: 150px;
+    text-align: center;
+    background: url(./images/image.png) center 70px no-repeat;
+    color: #cccccc;
+    font-size: 18px;
+    position: relative;
+    top:0;
+    *top: 10px;
+}
+
+#upload .placeholder .webuploader-pick {
+    font-size: 18px;
+    background: #00b7ee;
+    border-radius: 3px;
+    line-height: 44px;
+    padding: 0 30px;
+    *width: 120px;
+    color: #fff;
+    display: inline-block;
+    margin: 0 auto 20px auto;
+    cursor: pointer;
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+#upload .placeholder .webuploader-pick-hover {
+    background: #00a2d4;
+}
+
+
+#filePickerContainer {
+    text-align: center;
+}
+
+#upload .placeholder .flashTip {
+    color: #666666;
+    font-size: 12px;
+    position: absolute;
+    width: 100%;
+    text-align: center;
+    bottom: 20px;
+}
+
+#upload .placeholder .flashTip a {
+    color: #0785d1;
+    text-decoration: none;
+}
+
+#upload .placeholder .flashTip a:hover {
+    text-decoration: underline;
+}
+
+#upload .placeholder.webuploader-dnd-over {
+    border-color: #999999;
+}
+
+#upload .filelist {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+    overflow-x: hidden;
+    overflow-y: auto;
+    position: relative;
+    height: 300px;
+}
+
+#upload .filelist:after {
+    content: '';
+    display: block;
+    width: 0;
+    height: 0;
+    overflow: hidden;
+    clear: both;
+}
+
+#upload .filelist li {
+    width: 113px;
+    height: 113px;
+    background: url(./images/bg.png);
+    text-align: center;
+    margin: 9px 0 0 9px;
+    *margin: 6px 0 0 6px;
+    position: relative;
+    display: block;
+    float: left;
+    overflow: hidden;
+    font-size: 12px;
+}
+
+#upload .filelist li p.log {
+    position: relative;
+    top: -45px;
+}
+
+#upload .filelist li p.title {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    top: 5px;
+    text-indent: 5px;
+    text-align: left;
+}
+
+#upload .filelist li p.progress {
+    position: absolute;
+    width: 100%;
+    bottom: 0;
+    left: 0;
+    height: 8px;
+    overflow: hidden;
+    z-index: 50;
+    margin: 0;
+    border-radius: 0;
+    background: none;
+    -webkit-box-shadow: 0 0 0;
+}
+
+#upload .filelist li p.progress span {
+    display: none;
+    overflow: hidden;
+    width: 0;
+    height: 100%;
+    background: #1483d8 url(./images/progress.png) repeat-x;
+
+    -webit-transition: width 200ms linear;
+    -moz-transition: width 200ms linear;
+    -o-transition: width 200ms linear;
+    -ms-transition: width 200ms linear;
+    transition: width 200ms linear;
+
+    -webkit-animation: progressmove 2s linear infinite;
+    -moz-animation: progressmove 2s linear infinite;
+    -o-animation: progressmove 2s linear infinite;
+    -ms-animation: progressmove 2s linear infinite;
+    animation: progressmove 2s linear infinite;
+
+    -webkit-transform: translateZ(0);
+}
+
+@-webkit-keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+@-moz-keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+@keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+#upload .filelist li p.imgWrap {
+    position: relative;
+    z-index: 2;
+    line-height: 113px;
+    vertical-align: middle;
+    overflow: hidden;
+    width: 113px;
+    height: 113px;
+
+    -webkit-transform-origin: 50% 50%;
+    -moz-transform-origin: 50% 50%;
+    -o-transform-origin: 50% 50%;
+    -ms-transform-origin: 50% 50%;
+    transform-origin: 50% 50%;
+
+    -webit-transition: 200ms ease-out;
+    -moz-transition: 200ms ease-out;
+    -o-transition: 200ms ease-out;
+    -ms-transition: 200ms ease-out;
+    transition: 200ms ease-out;
+}
+#upload .filelist li p.imgWrap.notimage {
+    margin-top: 0;
+    width: 111px;
+    height: 111px;
+    border: 1px #eeeeee solid;
+}
+#upload .filelist li p.imgWrap.notimage i.file-preview {
+    margin-top: 15px;
+}
+
+#upload .filelist li img {
+    width: 100%;
+}
+
+#upload .filelist li p.error {
+    background: #f43838;
+    color: #fff;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 28px;
+    line-height: 28px;
+    width: 100%;
+    z-index: 100;
+    display:none;
+}
+
+#upload .filelist li .success {
+    display: block;
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    height: 40px;
+    width: 100%;
+    z-index: 200;
+    background: url(./images/success.png) no-repeat right bottom;
+    background-image: url(./images/success.gif) \9;
+}
+
+#upload .filelist li.filePickerBlock {
+    width: 113px;
+    height: 113px;
+    background: url(./images/image.png) no-repeat center 12px;
+    border: 1px solid #eeeeee;
+    border-radius: 0;
+}
+#upload .filelist li.filePickerBlock div.webuploader-pick  {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    opacity: 0;
+    background: none;
+    font-size: 0;
+}
+
+#upload .filelist div.file-panel {
+    position: absolute;
+    height: 0;
+    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0;
+    background: rgba(0, 0, 0, 0.5);
+    width: 100%;
+    top: 0;
+    left: 0;
+    overflow: hidden;
+    z-index: 300;
+}
+
+#upload .filelist div.file-panel span {
+    width: 24px;
+    height: 24px;
+    display: inline;
+    float: right;
+    text-indent: -9999px;
+    overflow: hidden;
+    background: url(./images/icons.png) no-repeat;
+    background: url(./images/icons.gif) no-repeat \9;
+    margin: 5px 1px 1px;
+    cursor: pointer;
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+#upload .filelist div.file-panel span.rotateLeft {
+    display:none;
+    background-position: 0 -24px;
+}
+
+#upload .filelist div.file-panel span.rotateLeft:hover {
+    background-position: 0 0;
+}
+
+#upload .filelist div.file-panel span.rotateRight {
+    display:none;
+    background-position: -24px -24px;
+}
+
+#upload .filelist div.file-panel span.rotateRight:hover {
+    background-position: -24px 0;
+}
+
+#upload .filelist div.file-panel span.cancel {
+    background-position: -48px -24px;
+}
+
+#upload .filelist div.file-panel span.cancel:hover {
+    background-position: -48px 0;
+}
+
+#upload .statusBar {
+    height: 45px;
+    border-bottom: 1px solid #dadada;
+    margin: 0 10px;
+    padding: 0;
+    line-height: 45px;
+    vertical-align: middle;
+    position: relative;
+}
+
+#upload .statusBar .progress {
+    border: 1px solid #1483d8;
+    width: 198px;
+    background: #fff;
+    height: 18px;
+    position: absolute;
+    top: 12px;
+    display: none;
+    text-align: center;
+    line-height: 18px;
+    color: #6dbfff;
+    margin: 0 10px 0 0;
+}
+#upload .statusBar .progress span.percentage {
+    width: 0;
+    height: 100%;
+    left: 0;
+    top: 0;
+    background: #1483d8;
+    position: absolute;
+}
+#upload .statusBar .progress span.text {
+    position: relative;
+    z-index: 10;
+}
+
+#upload .statusBar .info {
+    display: inline-block;
+    font-size: 14px;
+    color: #666666;
+}
+
+#upload .statusBar .btns {
+    position: absolute;
+    top: 7px;
+    right: 0;
+    line-height: 30px;
+}
+
+#filePickerBtn {
+    display: inline-block;
+    float: left;
+}
+#upload .statusBar .btns .webuploader-pick,
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-uploading,
+#upload .statusBar .btns .uploadBtn.state-paused {
+    background: #ffffff;
+    border: 1px solid #cfcfcf;
+    color: #565656;
+    padding: 0 18px;
+    display: inline-block;
+    border-radius: 3px;
+    margin-left: 10px;
+    cursor: pointer;
+    font-size: 14px;
+    float: left;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+#upload .statusBar .btns .webuploader-pick-hover,
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-uploading:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover {
+    background: #f0f0f0;
+}
+
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-paused{
+    background: #00b7ee;
+    color: #fff;
+    border-color: transparent;
+}
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover{
+    background: #00a2d4;
+}
+
+#upload .statusBar .btns .uploadBtn.disabled {
+    pointer-events: none;
+    filter:alpha(opacity=60);
+    -moz-opacity:0.6;
+    -khtml-opacity: 0.6;
+    opacity: 0.6;
+}
+
+
+
+/* 图片管理样式 */
+#online {
+    width: 100%;
+    height: 336px;
+    padding: 10px 0 0 0;
+}
+#online #fileList{
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    overflow-y: auto;
+    position: relative;
+}
+#online ul {
+    display: block;
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+#online li {
+    float: left;
+    display: block;
+    list-style: none;
+    padding: 0;
+    width: 113px;
+    height: 113px;
+    margin: 0 0 9px 9px;
+    *margin: 0 0 6px 6px;
+    background-color: #eee;
+    overflow: hidden;
+    cursor: pointer;
+    position: relative;
+}
+#online li.clearFloat {
+    float: none;
+    clear: both;
+    display: block;
+    width:0;
+    height:0;
+    margin: 0;
+    padding: 0;
+}
+#online li img {
+    cursor: pointer;
+}
+#online li div.file-wrapper {
+    cursor: pointer;
+    position: absolute;
+    display: block;
+    width: 111px;
+    height: 111px;
+    border: 1px solid #eee;
+    background: url("./images/bg.png") repeat;
+}
+#online li div span.file-title{
+    display: block;
+    padding: 0 3px;
+    margin: 3px 0 0 0;
+    font-size: 12px;
+    height: 13px;
+    color: #555555;
+    text-align: center;
+    width: 107px;
+    white-space: nowrap;
+    word-break: break-all;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+#online li .icon {
+    cursor: pointer;
+    width: 113px;
+    height: 113px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    border: 0;
+    background-repeat: no-repeat;
+}
+#online li .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+}
+#online li.selected .icon {
+    background-image: url(images/success.png);
+    background-image: url(images/success.gif) \9;
+    background-position: 75px 75px;
+}
+#online li.selected .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+    background-position: 72px 72px;
+}
+
+
+/* 在线文件的文件预览图标 */
+i.file-preview {
+    display: block;
+    margin: 10px auto;
+    width: 70px;
+    height: 70px;
+    background-image: url("./images/file-icons.png");
+    background-image: url("./images/file-icons.gif") \9;
+    background-position: -140px center;
+    background-repeat: no-repeat;
+}
+i.file-preview.file-type-dir{
+    background-position: 0 center;
+}
+i.file-preview.file-type-file{
+    background-position: -140px center;
+}
+i.file-preview.file-type-filelist{
+    background-position: -210px center;
+}
+i.file-preview.file-type-zip,
+i.file-preview.file-type-rar,
+i.file-preview.file-type-7z,
+i.file-preview.file-type-tar,
+i.file-preview.file-type-gz,
+i.file-preview.file-type-bz2{
+    background-position: -280px center;
+}
+i.file-preview.file-type-xls,
+i.file-preview.file-type-xlsx{
+    background-position: -350px center;
+}
+i.file-preview.file-type-doc,
+i.file-preview.file-type-docx{
+    background-position: -420px center;
+}
+i.file-preview.file-type-ppt,
+i.file-preview.file-type-pptx{
+    background-position: -490px center;
+}
+i.file-preview.file-type-vsd{
+    background-position: -560px center;
+}
+i.file-preview.file-type-pdf{
+    background-position: -630px center;
+}
+i.file-preview.file-type-txt,
+i.file-preview.file-type-md,
+i.file-preview.file-type-json,
+i.file-preview.file-type-htm,
+i.file-preview.file-type-xml,
+i.file-preview.file-type-html,
+i.file-preview.file-type-js,
+i.file-preview.file-type-css,
+i.file-preview.file-type-php,
+i.file-preview.file-type-jsp,
+i.file-preview.file-type-asp{
+    background-position: -700px center;
+}
+i.file-preview.file-type-apk{
+    background-position: -770px center;
+}
+i.file-preview.file-type-exe{
+    background-position: -840px center;
+}
+i.file-preview.file-type-ipa{
+    background-position: -910px center;
+}
+i.file-preview.file-type-mp4,
+i.file-preview.file-type-swf,
+i.file-preview.file-type-mkv,
+i.file-preview.file-type-avi,
+i.file-preview.file-type-flv,
+i.file-preview.file-type-mov,
+i.file-preview.file-type-mpg,
+i.file-preview.file-type-mpeg,
+i.file-preview.file-type-ogv,
+i.file-preview.file-type-webm,
+i.file-preview.file-type-rm,
+i.file-preview.file-type-rmvb{
+    background-position: -980px center;
+}
+i.file-preview.file-type-ogg,
+i.file-preview.file-type-wav,
+i.file-preview.file-type-wmv,
+i.file-preview.file-type-mid,
+i.file-preview.file-type-mp3{
+    background-position: -1050px center;
+}
+i.file-preview.file-type-jpg,
+i.file-preview.file-type-jpeg,
+i.file-preview.file-type-gif,
+i.file-preview.file-type-bmp,
+i.file-preview.file-type-png,
+i.file-preview.file-type-psd{
+    background-position: -140px center;
+}

+ 60 - 0
xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.html

@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>ueditor图片对话框</title>
+    <script type="text/javascript" src="../internal.js"></script>
+
+    <!-- jquery -->
+    <script type="text/javascript" src="../../third-party/jquery-1.10.2.min.js"></script>
+
+    <!-- webuploader -->
+    <script src="../../third-party/webuploader/webuploader.min.js"></script>
+    <link rel="stylesheet" type="text/css" href="../../third-party/webuploader/webuploader.css">
+
+    <!-- attachment dialog -->
+    <link rel="stylesheet" href="attachment.css" type="text/css" />
+</head>
+<body>
+
+    <div class="wrapper">
+        <div id="tabhead" class="tabhead">
+            <span class="tab focus" data-content-id="upload"><var id="lang_tab_upload"></var></span>
+            <span class="tab" data-content-id="online"><var id="lang_tab_online"></var></span>
+        </div>
+        <div id="tabbody" class="tabbody">
+            <!-- 上传图片 -->
+            <div id="upload" class="panel focus">
+                <div id="queueList" class="queueList">
+                    <div class="statusBar element-invisible">
+                        <div class="progress">
+                            <span class="text">0%</span>
+                            <span class="percentage"></span>
+                        </div><div class="info"></div>
+                        <div class="btns">
+                            <div id="filePickerBtn"></div>
+                            <div class="uploadBtn"><var id="lang_start_upload"></var></div>
+                        </div>
+                    </div>
+                    <div id="dndArea" class="placeholder">
+                        <div class="filePickerContainer">
+                            <div id="filePickerReady"></div>
+                        </div>
+                    </div>
+                    <ul class="filelist element-invisible">
+                        <li id="filePickerBlock" class="filePickerBlock"></li>
+                    </ul>
+                </div>
+            </div>
+
+            <!-- 在线图片 -->
+            <div id="online" class="panel">
+                <div id="fileList"><var id="lang_imgLoading"></var></div>
+            </div>
+
+        </div>
+    </div>
+    <script type="text/javascript" src="attachment.js"></script>
+
+</body>
+</html>

+ 760 - 0
xinkeaboard-admin/public/UEditor/dialogs/attachment/attachment.js

@@ -0,0 +1,760 @@
+/**
+ * User: Jinqn
+ * Date: 14-04-08
+ * Time: 下午16:34
+ * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片
+ */
+
+(function () {
+
+    var uploadFile,
+        onlineFile;
+
+    window.onload = function () {
+        initTabs();
+        initButtons();
+    };
+
+    /* 初始化tab标签 */
+    function initTabs() {
+        var tabs = $G('tabhead').children;
+        for (var i = 0; i < tabs.length; i++) {
+            domUtils.on(tabs[i], "click", function (e) {
+                var target = e.target || e.srcElement;
+                setTabFocus(target.getAttribute('data-content-id'));
+            });
+        }
+
+        setTabFocus('upload');
+    }
+
+    /* 初始化tabbody */
+    function setTabFocus(id) {
+        if(!id) return;
+        var i, bodyId, tabs = $G('tabhead').children;
+        for (i = 0; i < tabs.length; i++) {
+            bodyId = tabs[i].getAttribute('data-content-id')
+            if (bodyId == id) {
+                domUtils.addClass(tabs[i], 'focus');
+                domUtils.addClass($G(bodyId), 'focus');
+            } else {
+                domUtils.removeClasses(tabs[i], 'focus');
+                domUtils.removeClasses($G(bodyId), 'focus');
+            }
+        }
+        switch (id) {
+            case 'upload':
+                uploadFile = uploadFile || new UploadFile('queueList');
+                break;
+            case 'online':
+                onlineFile = onlineFile || new OnlineFile('fileList');
+                break;
+        }
+    }
+
+    /* 初始化onok事件 */
+    function initButtons() {
+
+        dialog.onok = function () {
+            var list = [], id, tabs = $G('tabhead').children;
+            for (var i = 0; i < tabs.length; i++) {
+                if (domUtils.hasClass(tabs[i], 'focus')) {
+                    id = tabs[i].getAttribute('data-content-id');
+                    break;
+                }
+            }
+
+            switch (id) {
+                case 'upload':
+                    list = uploadFile.getInsertList();
+                    var count = uploadFile.getQueueCount();
+                    if (count) {
+                        $('.info', '#queueList').html('<span style="color:red;">' + '还有2个未上传文件'.replace(/[\d]/, count) + '</span>');
+                        return false;
+                    }
+                    break;
+                case 'online':
+                    list = onlineFile.getInsertList();
+                    break;
+            }
+
+            editor.execCommand('insertfile', list);
+        };
+    }
+
+
+    /* 上传附件 */
+    function UploadFile(target) {
+        this.$wrap = target.constructor == String ? $('#' + target) : $(target);
+        this.init();
+    }
+    UploadFile.prototype = {
+        init: function () {
+            this.fileList = [];
+            this.initContainer();
+            this.initUploader();
+        },
+        initContainer: function () {
+            this.$queue = this.$wrap.find('.filelist');
+        },
+        /* 初始化容器 */
+        initUploader: function () {
+            var _this = this,
+                $ = jQuery,    // just in case. Make sure it's not an other libaray.
+                $wrap = _this.$wrap,
+            // 图片容器
+                $queue = $wrap.find('.filelist'),
+            // 状态栏,包括进度和控制按钮
+                $statusBar = $wrap.find('.statusBar'),
+            // 文件总体选择信息。
+                $info = $statusBar.find('.info'),
+            // 上传按钮
+                $upload = $wrap.find('.uploadBtn'),
+            // 上传按钮
+                $filePickerBtn = $wrap.find('.filePickerBtn'),
+            // 上传按钮
+                $filePickerBlock = $wrap.find('.filePickerBlock'),
+            // 没选择文件之前的内容。
+                $placeHolder = $wrap.find('.placeholder'),
+            // 总体进度条
+                $progress = $statusBar.find('.progress').hide(),
+            // 添加的文件数量
+                fileCount = 0,
+            // 添加的文件总大小
+                fileSize = 0,
+            // 优化retina, 在retina下这个值是2
+                ratio = window.devicePixelRatio || 1,
+            // 缩略图大小
+                thumbnailWidth = 113 * ratio,
+                thumbnailHeight = 113 * ratio,
+            // 可能有pedding, ready, uploading, confirm, done.
+                state = '',
+            // 所有文件的进度信息,key为file id
+                percentages = {},
+                supportTransition = (function () {
+                    var s = document.createElement('p').style,
+                        r = 'transition' in s ||
+                            'WebkitTransition' in s ||
+                            'MozTransition' in s ||
+                            'msTransition' in s ||
+                            'OTransition' in s;
+                    s = null;
+                    return r;
+                })(),
+            // WebUploader实例
+                uploader,
+                actionUrl = editor.getActionUrl(editor.getOpt('fileActionName')),
+                fileMaxSize = editor.getOpt('fileMaxSize'),
+                acceptExtensions = (editor.getOpt('fileAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, '');;
+
+            if (!WebUploader.Uploader.support()) {
+                $('#filePickerReady').after($('<div>').html(lang.errorNotSupport)).hide();
+                return;
+            } else if (!editor.getOpt('fileActionName')) {
+                $('#filePickerReady').after($('<div>').html(lang.errorLoadConfig)).hide();
+                return;
+            }
+
+            uploader = _this.uploader = WebUploader.create({
+                pick: {
+                    id: '#filePickerReady',
+                    label: lang.uploadSelectFile
+                },
+                swf: '../../third-party/webuploader/Uploader.swf',
+                server: actionUrl,
+                fileVal: editor.getOpt('fileFieldName'),
+                duplicate: true,
+                fileSingleSizeLimit: fileMaxSize,
+                compress: false
+            });
+            uploader.addButton({
+                id: '#filePickerBlock'
+            });
+            uploader.addButton({
+                id: '#filePickerBtn',
+                label: lang.uploadAddFile
+            });
+
+            setState('pedding');
+
+            // 当有文件添加进来时执行,负责view的创建
+            function addFile(file) {
+                var $li = $('<li id="' + file.id + '">' +
+                        '<p class="title">' + file.name + '</p>' +
+                        '<p class="imgWrap"></p>' +
+                        '<p class="progress"><span></span></p>' +
+                        '</li>'),
+
+                    $btns = $('<div class="file-panel">' +
+                        '<span class="cancel">' + lang.uploadDelete + '</span>' +
+                        '<span class="rotateRight">' + lang.uploadTurnRight + '</span>' +
+                        '<span class="rotateLeft">' + lang.uploadTurnLeft + '</span></div>').appendTo($li),
+                    $prgress = $li.find('p.progress span'),
+                    $wrap = $li.find('p.imgWrap'),
+                    $info = $('<p class="error"></p>').hide().appendTo($li),
+
+                    showError = function (code) {
+                        switch (code) {
+                            case 'exceed_size':
+                                text = lang.errorExceedSize;
+                                break;
+                            case 'interrupt':
+                                text = lang.errorInterrupt;
+                                break;
+                            case 'http':
+                                text = lang.errorHttp;
+                                break;
+                            case 'not_allow_type':
+                                text = lang.errorFileType;
+                                break;
+                            default:
+                                text = lang.errorUploadRetry;
+                                break;
+                        }
+                        $info.text(text).show();
+                    };
+
+                if (file.getStatus() === 'invalid') {
+                    showError(file.statusText);
+                } else {
+                    $wrap.text(lang.uploadPreview);
+                    if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) {
+                        $wrap.empty().addClass('notimage').append('<i class="file-preview file-type-' + file.ext.toLowerCase() + '"></i>' +
+                        '<span class="file-title" title="' + file.name + '">' + file.name + '</span>');
+                    } else {
+                        if (browser.ie && browser.version <= 7) {
+                            $wrap.text(lang.uploadNoPreview);
+                        } else {
+                            uploader.makeThumb(file, function (error, src) {
+                                if (error || !src) {
+                                    $wrap.text(lang.uploadNoPreview);
+                                } else {
+                                    var $img = $('<img src="' + src + '">');
+                                    $wrap.empty().append($img);
+                                    $img.on('error', function () {
+                                        $wrap.text(lang.uploadNoPreview);
+                                    });
+                                }
+                            }, thumbnailWidth, thumbnailHeight);
+                        }
+                    }
+                    percentages[ file.id ] = [ file.size, 0 ];
+                    file.rotation = 0;
+
+                    /* 检查文件格式 */
+                    if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {
+                        showError('not_allow_type');
+                        uploader.removeFile(file);
+                    }
+                }
+
+                file.on('statuschange', function (cur, prev) {
+                    if (prev === 'progress') {
+                        $prgress.hide().width(0);
+                    } else if (prev === 'queued') {
+                        $li.off('mouseenter mouseleave');
+                        $btns.remove();
+                    }
+                    // 成功
+                    if (cur === 'error' || cur === 'invalid') {
+                        showError(file.statusText);
+                        percentages[ file.id ][ 1 ] = 1;
+                    } else if (cur === 'interrupt') {
+                        showError('interrupt');
+                    } else if (cur === 'queued') {
+                        percentages[ file.id ][ 1 ] = 0;
+                    } else if (cur === 'progress') {
+                        $info.hide();
+                        $prgress.css('display', 'block');
+                    } else if (cur === 'complete') {
+                    }
+
+                    $li.removeClass('state-' + prev).addClass('state-' + cur);
+                });
+
+                $li.on('mouseenter', function () {
+                    $btns.stop().animate({height: 30});
+                });
+                $li.on('mouseleave', function () {
+                    $btns.stop().animate({height: 0});
+                });
+
+                $btns.on('click', 'span', function () {
+                    var index = $(this).index(),
+                        deg;
+
+                    switch (index) {
+                        case 0:
+                            uploader.removeFile(file);
+                            return;
+                        case 1:
+                            file.rotation += 90;
+                            break;
+                        case 2:
+                            file.rotation -= 90;
+                            break;
+                    }
+
+                    if (supportTransition) {
+                        deg = 'rotate(' + file.rotation + 'deg)';
+                        $wrap.css({
+                            '-webkit-transform': deg,
+                            '-mos-transform': deg,
+                            '-o-transform': deg,
+                            'transform': deg
+                        });
+                    } else {
+                        $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
+                    }
+
+                });
+
+                $li.insertBefore($filePickerBlock);
+            }
+
+            // 负责view的销毁
+            function removeFile(file) {
+                var $li = $('#' + file.id);
+                delete percentages[ file.id ];
+                updateTotalProgress();
+                $li.off().find('.file-panel').off().end().remove();
+            }
+
+            function updateTotalProgress() {
+                var loaded = 0,
+                    total = 0,
+                    spans = $progress.children(),
+                    percent;
+
+                $.each(percentages, function (k, v) {
+                    total += v[ 0 ];
+                    loaded += v[ 0 ] * v[ 1 ];
+                });
+
+                percent = total ? loaded / total : 0;
+
+                spans.eq(0).text(Math.round(percent * 100) + '%');
+                spans.eq(1).css('width', Math.round(percent * 100) + '%');
+                updateStatus();
+            }
+
+            function setState(val, files) {
+
+                if (val != state) {
+
+                    var stats = uploader.getStats();
+
+                    $upload.removeClass('state-' + state);
+                    $upload.addClass('state-' + val);
+
+                    switch (val) {
+
+                        /* 未选择文件 */
+                        case 'pedding':
+                            $queue.addClass('element-invisible');
+                            $statusBar.addClass('element-invisible');
+                            $placeHolder.removeClass('element-invisible');
+                            $progress.hide(); $info.hide();
+                            uploader.refresh();
+                            break;
+
+                        /* 可以开始上传 */
+                        case 'ready':
+                            $placeHolder.addClass('element-invisible');
+                            $queue.removeClass('element-invisible');
+                            $statusBar.removeClass('element-invisible');
+                            $progress.hide(); $info.show();
+                            $upload.text(lang.uploadStart);
+                            uploader.refresh();
+                            break;
+
+                        /* 上传中 */
+                        case 'uploading':
+                            $progress.show(); $info.hide();
+                            $upload.text(lang.uploadPause);
+                            break;
+
+                        /* 暂停上传 */
+                        case 'paused':
+                            $progress.show(); $info.hide();
+                            $upload.text(lang.uploadContinue);
+                            break;
+
+                        case 'confirm':
+                            $progress.show(); $info.hide();
+                            $upload.text(lang.uploadStart);
+
+                            stats = uploader.getStats();
+                            if (stats.successNum && !stats.uploadFailNum) {
+                                setState('finish');
+                                return;
+                            }
+                            break;
+
+                        case 'finish':
+                            $progress.hide(); $info.show();
+                            if (stats.uploadFailNum) {
+                                $upload.text(lang.uploadRetry);
+                            } else {
+                                $upload.text(lang.uploadStart);
+                            }
+                            break;
+                    }
+
+                    state = val;
+                    updateStatus();
+
+                }
+
+                if (!_this.getQueueCount()) {
+                    $upload.addClass('disabled')
+                } else {
+                    $upload.removeClass('disabled')
+                }
+
+            }
+
+            function updateStatus() {
+                var text = '', stats;
+
+                if (state === 'ready') {
+                    text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));
+                } else if (state === 'confirm') {
+                    stats = uploader.getStats();
+                    if (stats.uploadFailNum) {
+                        text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);
+                    }
+                } else {
+                    stats = uploader.getStats();
+                    text = lang.updateStatusFinish.replace('_', fileCount).
+                        replace('_KB', WebUploader.formatSize(fileSize)).
+                        replace('_', stats.successNum);
+
+                    if (stats.uploadFailNum) {
+                        text += lang.updateStatusError.replace('_', stats.uploadFailNum);
+                    }
+                }
+
+                $info.html(text);
+            }
+
+            uploader.on('fileQueued', function (file) {
+                fileCount++;
+                fileSize += file.size;
+
+                if (fileCount === 1) {
+                    $placeHolder.addClass('element-invisible');
+                    $statusBar.show();
+                }
+
+                addFile(file);
+            });
+
+            uploader.on('fileDequeued', function (file) {
+                fileCount--;
+                fileSize -= file.size;
+
+                removeFile(file);
+                updateTotalProgress();
+            });
+
+            uploader.on('filesQueued', function (file) {
+                if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {
+                    setState('ready');
+                }
+                updateTotalProgress();
+            });
+
+            uploader.on('all', function (type, files) {
+                switch (type) {
+                    case 'uploadFinished':
+                        setState('confirm', files);
+                        break;
+                    case 'startUpload':
+                        /* 添加额外的GET参数 */
+                        var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',
+                            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);
+                        uploader.option('server', url);
+                        setState('uploading', files);
+                        break;
+                    case 'stopUpload':
+                        setState('paused', files);
+                        break;
+                }
+            });
+
+            uploader.on('uploadBeforeSend', function (file, data, header) {
+                //这里可以通过data对象添加POST参数
+                header['X_Requested_With'] = 'XMLHttpRequest';
+                // HaoChuan9421
+                if(editor.options.headers && Object.prototype.toString.apply(editor.options.headers) === "[object Object]"){
+                    for(var key in editor.options.headers){
+                        header[key] = editor.options.headers[key]
+                    }
+                }
+            });
+
+            uploader.on('uploadProgress', function (file, percentage) {
+                var $li = $('#' + file.id),
+                    $percent = $li.find('.progress span');
+
+                $percent.css('width', percentage * 100 + '%');
+                percentages[ file.id ][ 1 ] = percentage;
+                updateTotalProgress();
+            });
+
+            uploader.on('uploadSuccess', function (file, ret) {
+                var $file = $('#' + file.id);
+                try {
+                    var responseText = (ret._raw || ret),
+                        json = utils.str2json(responseText);
+                    if (json.state == 'SUCCESS') {
+                        _this.fileList.push(json);
+                        $file.append('<span class="success"></span>');
+                    } else {
+                        $file.find('.error').text(json.state).show();
+                    }
+                } catch (e) {
+                    $file.find('.error').text(lang.errorServerUpload).show();
+                }
+            });
+
+            uploader.on('uploadError', function (file, code) {
+            });
+            uploader.on('error', function (code, file) {
+                if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {
+                    addFile(file);
+                }
+            });
+            uploader.on('uploadComplete', function (file, ret) {
+            });
+
+            $upload.on('click', function () {
+                if ($(this).hasClass('disabled')) {
+                    return false;
+                }
+
+                if (state === 'ready') {
+                    uploader.upload();
+                } else if (state === 'paused') {
+                    uploader.upload();
+                } else if (state === 'uploading') {
+                    uploader.stop();
+                }
+            });
+
+            $upload.addClass('state-' + state);
+            updateTotalProgress();
+        },
+        getQueueCount: function () {
+            var file, i, status, readyFile = 0, files = this.uploader.getFiles();
+            for (i = 0; file = files[i++]; ) {
+                status = file.getStatus();
+                if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;
+            }
+            return readyFile;
+        },
+        getInsertList: function () {
+            var i, link, data, list = [],
+                prefix = editor.getOpt('fileUrlPrefix');
+            for (i = 0; i < this.fileList.length; i++) {
+                data = this.fileList[i];
+                link = data.url;
+                list.push({
+                    title: data.original || link.substr(link.lastIndexOf('/') + 1),
+                    url: prefix + link
+                });
+            }
+            return list;
+        }
+    };
+
+
+    /* 在线附件 */
+    function OnlineFile(target) {
+        this.container = utils.isString(target) ? document.getElementById(target) : target;
+        this.init();
+    }
+    OnlineFile.prototype = {
+        init: function () {
+            this.initContainer();
+            this.initEvents();
+            this.initData();
+        },
+        /* 初始化容器 */
+        initContainer: function () {
+            this.container.innerHTML = '';
+            this.list = document.createElement('ul');
+            this.clearFloat = document.createElement('li');
+
+            domUtils.addClass(this.list, 'list');
+            domUtils.addClass(this.clearFloat, 'clearFloat');
+
+            this.list.appendChild(this.clearFloat);
+            this.container.appendChild(this.list);
+        },
+        /* 初始化滚动事件,滚动到地步自动拉取数据 */
+        initEvents: function () {
+            var _this = this;
+
+            /* 滚动拉取图片 */
+            domUtils.on($G('fileList'), 'scroll', function(e){
+                var panel = this;
+                if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {
+                    _this.getFileData();
+                }
+            });
+            /* 选中图片 */
+            domUtils.on(this.list, 'click', function (e) {
+                var target = e.target || e.srcElement,
+                    li = target.parentNode;
+
+                if (li.tagName.toLowerCase() == 'li') {
+                    if (domUtils.hasClass(li, 'selected')) {
+                        domUtils.removeClasses(li, 'selected');
+                    } else {
+                        domUtils.addClass(li, 'selected');
+                    }
+                }
+            });
+        },
+        /* 初始化第一次的数据 */
+        initData: function () {
+
+            /* 拉取数据需要使用的值 */
+            this.state = 0;
+            this.listSize = editor.getOpt('fileManagerListSize');
+            this.listIndex = 0;
+            this.listEnd = false;
+
+            /* 第一次拉取数据 */
+            this.getFileData();
+        },
+        /* 向后台拉取图片列表数据 */
+        getFileData: function () {
+            var _this = this;
+
+            if(!_this.listEnd && !this.isLoadingData) {
+                this.isLoadingData = true;
+                ajax.request(editor.getActionUrl(editor.getOpt('fileManagerActionName')), {
+                    timeout: 100000,
+                    data: utils.extend({
+                            start: this.listIndex,
+                            size: this.listSize
+                        }, editor.queryCommandValue('serverparam')),
+                    method: 'get',
+                    onsuccess: function (r) {
+                        try {
+                            var json = eval('(' + r.responseText + ')');
+                            if (json.state == 'SUCCESS') {
+                                _this.pushData(json.list);
+                                _this.listIndex = parseInt(json.start) + parseInt(json.list.length);
+                                if(_this.listIndex >= json.total) {
+                                    _this.listEnd = true;
+                                }
+                                _this.isLoadingData = false;
+                            }
+                        } catch (e) {
+                            if(r.responseText.indexOf('ue_separate_ue') != -1) {
+                                var list = r.responseText.split(r.responseText);
+                                _this.pushData(list);
+                                _this.listIndex = parseInt(list.length);
+                                _this.listEnd = true;
+                                _this.isLoadingData = false;
+                            }
+                        }
+                    },
+                    onerror: function () {
+                        _this.isLoadingData = false;
+                    }
+                });
+            }
+        },
+        /* 添加图片到列表界面上 */
+        pushData: function (list) {
+            var i, item, img, filetype, preview, icon, _this = this,
+                urlPrefix = editor.getOpt('fileManagerUrlPrefix');
+            for (i = 0; i < list.length; i++) {
+                if(list[i] && list[i].url) {
+                    item = document.createElement('li');
+                    icon = document.createElement('span');
+                    filetype = list[i].url.substr(list[i].url.lastIndexOf('.') + 1);
+
+                    if ( "png|jpg|jpeg|gif|bmp".indexOf(filetype) != -1 ) {
+                        preview = document.createElement('img');
+                        domUtils.on(preview, 'load', (function(image){
+                            return function(){
+                                _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);
+                            };
+                        })(preview));
+                        preview.width = 113;
+                        preview.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );
+                    } else {
+                        var ic = document.createElement('i'),
+                            textSpan = document.createElement('span');
+                        textSpan.innerHTML = list[i].url.substr(list[i].url.lastIndexOf('/') + 1);
+                        preview = document.createElement('div');
+                        preview.appendChild(ic);
+                        preview.appendChild(textSpan);
+                        domUtils.addClass(preview, 'file-wrapper');
+                        domUtils.addClass(textSpan, 'file-title');
+                        domUtils.addClass(ic, 'file-type-' + filetype);
+                        domUtils.addClass(ic, 'file-preview');
+                    }
+                    domUtils.addClass(icon, 'icon');
+                    item.setAttribute('data-url', urlPrefix + list[i].url);
+                    if (list[i].original) {
+                        item.setAttribute('data-title', list[i].original);
+                    }
+
+                    item.appendChild(preview);
+                    item.appendChild(icon);
+                    this.list.insertBefore(item, this.clearFloat);
+                }
+            }
+        },
+        /* 改变图片大小 */
+        scale: function (img, w, h, type) {
+            var ow = img.width,
+                oh = img.height;
+
+            if (type == 'justify') {
+                if (ow >= oh) {
+                    img.width = w;
+                    img.height = h * oh / ow;
+                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+                } else {
+                    img.width = w * ow / oh;
+                    img.height = h;
+                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+                }
+            } else {
+                if (ow >= oh) {
+                    img.width = w * ow / oh;
+                    img.height = h;
+                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+                } else {
+                    img.width = w;
+                    img.height = h * oh / ow;
+                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+                }
+            }
+        },
+        getInsertList: function () {
+            var i, lis = this.list.children, list = [];
+            for (i = 0; i < lis.length; i++) {
+                if (domUtils.hasClass(lis[i], 'selected')) {
+                    var url = lis[i].getAttribute('data-url');
+                    var title = lis[i].getAttribute('data-title') || url.substr(url.lastIndexOf('/') + 1);
+                    list.push({
+                        title: title,
+                        url: url
+                    });
+                }
+            }
+            return list;
+        }
+    };
+
+
+})();

BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_chm.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_default.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_doc.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_exe.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_jpg.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_mp3.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_mv.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_pdf.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_ppt.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_psd.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_rar.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_txt.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/fileTypeImages/icon_xls.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/alignicon.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/alignicon.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/bg.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/file-icons.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/file-icons.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/icons.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/icons.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/image.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/progress.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/success.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/attachment/images/success.png


+ 94 - 0
xinkeaboard-admin/public/UEditor/dialogs/background/background.css

@@ -0,0 +1,94 @@
+.wrapper{ width: 424px;margin: 10px auto; zoom:1;position: relative}
+.tabbody{height:225px;}
+.tabbody .panel { position: absolute;width:100%; height:100%;background: #fff; display: none;}
+.tabbody .focus { display: block;}
+
+body{font-size: 12px;color: #888;overflow: hidden;}
+input,label{vertical-align:middle}
+.clear{clear: both;}
+.pl{padding-left: 18px;padding-left: 23px\9;}
+
+#imageList {width: 420px;height: 215px;margin-top: 10px;overflow: hidden;overflow-y: auto;}
+#imageList div {float: left;width: 100px;height: 95px;margin: 5px 10px;}
+#imageList img {cursor: pointer;border: 2px solid white;}
+
+.bgarea{margin: 10px;padding: 5px;height: 84%;border: 1px solid #A8A297;}
+.content div{margin: 10px 0 10px 5px;}
+.content .iptradio{margin: 0px 5px 5px 0px;}
+.txt{width:280px;}
+
+.wrapcolor{height: 19px;}
+div.color{float: left;margin: 0;}
+#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;margin: 0;float: left;}
+div.alignment,#custom{margin-left: 23px;margin-left: 28px\9;}
+#custom input{height: 15px;min-height: 15px;width:20px;}
+#repeatType{width:100px;}
+
+
+/* 图片管理样式 */
+#imgManager {
+    width: 100%;
+    height: 225px;
+}
+#imgManager #imageList{
+    width: 100%;
+    overflow-x: hidden;
+    overflow-y: auto;
+}
+#imgManager ul {
+    display: block;
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+#imgManager li {
+    float: left;
+    display: block;
+    list-style: none;
+    padding: 0;
+    width: 113px;
+    height: 113px;
+    margin: 9px 0 0 19px;
+    background-color: #eee;
+    overflow: hidden;
+    cursor: pointer;
+    position: relative;
+}
+#imgManager li.clearFloat {
+    float: none;
+    clear: both;
+    display: block;
+    width:0;
+    height:0;
+    margin: 0;
+    padding: 0;
+}
+#imgManager li img {
+    cursor: pointer;
+}
+#imgManager li .icon {
+    cursor: pointer;
+    width: 113px;
+    height: 113px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    border: 0;
+    background-repeat: no-repeat;
+}
+#imgManager li .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+}
+#imgManager li.selected .icon {
+    background-image: url(images/success.png);
+    background-position: 75px 75px;
+}
+#imgManager li.selected .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+    background-position: 72px 72px;
+}

+ 56 - 0
xinkeaboard-admin/public/UEditor/dialogs/background/background.html

@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
+    <script type="text/javascript" src="../internal.js"></script>
+    <link rel="stylesheet" type="text/css" href="background.css">
+</head>
+<body>
+    <div id="bg_container" class="wrapper">
+        <div id="tabHeads" class="tabhead">
+            <span class="focus" data-content-id="normal"><var id="lang_background_normal"></var></span>
+            <span class="" data-content-id="imgManager"><var id="lang_background_local"></var></span>
+        </div>
+        <div id="tabBodys" class="tabbody">
+            <div id="normal" class="panel focus">
+                <fieldset class="bgarea">
+                    <legend><var id="lang_background_set"></var></legend>
+                    <div class="content">
+                        <div>
+                            <label><input id="nocolorRadio" class="iptradio" type="radio" name="t" value="none" checked="checked"><var id="lang_background_none"></var></label>
+                            <label><input id="coloredRadio" class="iptradio" type="radio" name="t" value="color"><var id="lang_background_colored"></var></label>
+                        </div>
+                        <div class="wrapcolor pl">
+                            <div class="color">
+                                <var id="lang_background_color"></var>:
+                            </div>
+                            <div id="colorPicker"></div>
+                            <div class="clear"></div>
+                        </div>
+                        <div class="wrapcolor pl">
+                            <label><var id="lang_background_netimg"></var>:</label><input class="txt" type="text" id="url">
+                        </div>
+                        <div id="alignment" class="alignment">
+                            <var id="lang_background_align"></var>:<select id="repeatType">
+                                <option value="center"></option>
+                                <option value="repeat-x"></option>
+                                <option value="repeat-y"></option>
+                                <option value="repeat"></option>
+                                <option value="self"></option>
+                            </select>
+                        </div>
+                        <div id="custom" >
+                            <var id="lang_background_position"></var>:x:<input type="text" size="1" id="x" maxlength="4" value="0">px&nbsp;&nbsp;y:<input type="text" size="1" id="y" maxlength="4" value="0">px
+                        </div>
+                    </div>
+                </fieldset>
+
+            </div>
+            <div id="imgManager" class="panel">
+                <div id="imageList" style=""></div>
+            </div>
+        </div>
+    </div>
+    <script type="text/javascript" src="background.js"></script>
+</body>
+</html>

+ 376 - 0
xinkeaboard-admin/public/UEditor/dialogs/background/background.js

@@ -0,0 +1,376 @@
+(function () {
+
+    var onlineImage,
+        backupStyle = editor.queryCommandValue('background');
+
+    window.onload = function () {
+        initTabs();
+        initColorSelector();
+    };
+
+    /* 初始化tab标签 */
+    function initTabs(){
+        var tabs = $G('tabHeads').children;
+        for (var i = 0; i < tabs.length; i++) {
+            domUtils.on(tabs[i], "click", function (e) {
+                var target = e.target || e.srcElement;
+                for (var j = 0; j < tabs.length; j++) {
+                    if(tabs[j] == target){
+                        tabs[j].className = "focus";
+                        var contentId = tabs[j].getAttribute('data-content-id');
+                        $G(contentId).style.display = "block";
+                        if(contentId == 'imgManager') {
+                            initImagePanel();
+                        }
+                    }else {
+                        tabs[j].className = "";
+                        $G(tabs[j].getAttribute('data-content-id')).style.display = "none";
+                    }
+                }
+            });
+        }
+    }
+
+    /* 初始化颜色设置 */
+    function initColorSelector () {
+        var obj = editor.queryCommandValue('background');
+        if (obj) {
+            var color = obj['background-color'],
+                repeat = obj['background-repeat'] || 'repeat',
+                image = obj['background-image'] || '',
+                position = obj['background-position'] || 'center center',
+                pos = position.split(' '),
+                x = parseInt(pos[0]) || 0,
+                y = parseInt(pos[1]) || 0;
+
+            if(repeat == 'no-repeat' && (x || y)) repeat = 'self';
+
+            image = image.match(/url[\s]*\(([^\)]*)\)/);
+            image = image ? image[1]:'';
+            updateFormState('colored', color, image, repeat, x, y);
+        } else {
+            updateFormState();
+        }
+
+        var updateHandler = function () {
+            updateFormState();
+            updateBackground();
+        }
+        domUtils.on($G('nocolorRadio'), 'click', updateBackground);
+        domUtils.on($G('coloredRadio'), 'click', updateHandler);
+        domUtils.on($G('url'), 'keyup', function(){
+            if($G('url').value && $G('alignment').style.display == "none") {
+                utils.each($G('repeatType').children, function(item){
+                    item.selected = ('repeat' == item.getAttribute('value') ? 'selected':false);
+                });
+            }
+            updateHandler();
+        });
+        domUtils.on($G('repeatType'), 'change', updateHandler);
+        domUtils.on($G('x'), 'keyup', updateBackground);
+        domUtils.on($G('y'), 'keyup', updateBackground);
+
+        initColorPicker();
+    }
+
+    /* 初始化颜色选择器 */
+    function initColorPicker() {
+        var me = editor,
+            cp = $G("colorPicker");
+
+        /* 生成颜色选择器ui对象 */
+        var popup = new UE.ui.Popup({
+            content: new UE.ui.ColorPicker({
+                noColorText: me.getLang("clearColor"),
+                editor: me,
+                onpickcolor: function (t, color) {
+                    updateFormState('colored', color);
+                    updateBackground();
+                    UE.ui.Popup.postHide();
+                },
+                onpicknocolor: function (t, color) {
+                    updateFormState('colored', 'transparent');
+                    updateBackground();
+                    UE.ui.Popup.postHide();
+                }
+            }),
+            editor: me,
+            onhide: function () {
+            }
+        });
+
+        /* 设置颜色选择器 */
+        domUtils.on(cp, "click", function () {
+            popup.showAnchor(this);
+        });
+        domUtils.on(document, 'mousedown', function (evt) {
+            var el = evt.target || evt.srcElement;
+            UE.ui.Popup.postHide(el);
+        });
+        domUtils.on(window, 'scroll', function () {
+            UE.ui.Popup.postHide();
+        });
+    }
+
+    /* 初始化在线图片列表 */
+    function initImagePanel() {
+        onlineImage = onlineImage || new OnlineImage('imageList');
+    }
+
+    /* 更新背景色设置面板 */
+    function updateFormState (radio, color, url, align, x, y) {
+        var nocolorRadio = $G('nocolorRadio'),
+            coloredRadio = $G('coloredRadio');
+
+        if(radio) {
+            nocolorRadio.checked = (radio == 'colored' ? false:'checked');
+            coloredRadio.checked = (radio == 'colored' ? 'checked':false);
+        }
+        if(color) {
+            domUtils.setStyle($G("colorPicker"), "background-color", color);
+        }
+
+        if(url && /^\//.test(url)) {
+            var a = document.createElement('a');
+            a.href = url;
+            browser.ie && (a.href = a.href);
+            url = browser.ie ? a.href:(a.protocol + '//' + a.host + a.pathname + a.search + a.hash);
+        }
+
+        if(url || url === '') {
+            $G('url').value = url;
+        }
+        if(align) {
+            utils.each($G('repeatType').children, function(item){
+                item.selected = (align == item.getAttribute('value') ? 'selected':false);
+            });
+        }
+        if(x || y) {
+            $G('x').value = parseInt(x) || 0;
+            $G('y').value = parseInt(y) || 0;
+        }
+
+        $G('alignment').style.display = coloredRadio.checked && $G('url').value ? '':'none';
+        $G('custom').style.display = coloredRadio.checked && $G('url').value && $G('repeatType').value == 'self' ? '':'none';
+    }
+
+    /* 更新背景颜色 */
+    function updateBackground () {
+        if ($G('coloredRadio').checked) {
+            var color = domUtils.getStyle($G("colorPicker"), "background-color"),
+                bgimg = $G("url").value,
+                align = $G("repeatType").value,
+                backgroundObj = {
+                    "background-repeat": "no-repeat",
+                    "background-position": "center center"
+                };
+
+            if (color) backgroundObj["background-color"] = color;
+            if (bgimg) backgroundObj["background-image"] = 'url(' + bgimg + ')';
+            if (align == 'self') {
+                backgroundObj["background-position"] = $G("x").value + "px " + $G("y").value + "px";
+            } else if (align == 'repeat-x' || align == 'repeat-y' || align == 'repeat') {
+                backgroundObj["background-repeat"] = align;
+            }
+
+            editor.execCommand('background', backgroundObj);
+        } else {
+            editor.execCommand('background', null);
+        }
+    }
+
+
+    /* 在线图片 */
+    function OnlineImage(target) {
+        this.container = utils.isString(target) ? document.getElementById(target) : target;
+        this.init();
+    }
+    OnlineImage.prototype = {
+        init: function () {
+            this.reset();
+            this.initEvents();
+        },
+        /* 初始化容器 */
+        initContainer: function () {
+            this.container.innerHTML = '';
+            this.list = document.createElement('ul');
+            this.clearFloat = document.createElement('li');
+
+            domUtils.addClass(this.list, 'list');
+            domUtils.addClass(this.clearFloat, 'clearFloat');
+
+            this.list.id = 'imageListUl';
+            this.list.appendChild(this.clearFloat);
+            this.container.appendChild(this.list);
+        },
+        /* 初始化滚动事件,滚动到地步自动拉取数据 */
+        initEvents: function () {
+            var _this = this;
+
+            /* 滚动拉取图片 */
+            domUtils.on($G('imageList'), 'scroll', function(e){
+                var panel = this;
+                if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {
+                    _this.getImageData();
+                }
+            });
+            /* 选中图片 */
+            domUtils.on(this.container, 'click', function (e) {
+                var target = e.target || e.srcElement,
+                    li = target.parentNode,
+                    nodes = $G('imageListUl').childNodes;
+
+                if (li.tagName.toLowerCase() == 'li') {
+                    updateFormState('nocolor', null, '');
+                    for (var i = 0, node; node = nodes[i++];) {
+                        if (node == li && !domUtils.hasClass(node, 'selected')) {
+                            domUtils.addClass(node, 'selected');
+                            updateFormState('colored', null, li.firstChild.getAttribute("_src"), 'repeat');
+                        } else {
+                            domUtils.removeClasses(node, 'selected');
+                        }
+                    }
+                    updateBackground();
+                }
+            });
+        },
+        /* 初始化第一次的数据 */
+        initData: function () {
+
+            /* 拉取数据需要使用的值 */
+            this.state = 0;
+            this.listSize = editor.getOpt('imageManagerListSize');
+            this.listIndex = 0;
+            this.listEnd = false;
+
+            /* 第一次拉取数据 */
+            this.getImageData();
+        },
+        /* 重置界面 */
+        reset: function() {
+            this.initContainer();
+            this.initData();
+        },
+        /* 向后台拉取图片列表数据 */
+        getImageData: function () {
+            var _this = this;
+
+            if(!_this.listEnd && !this.isLoadingData) {
+                this.isLoadingData = true;
+                var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')),
+                    isJsonp = utils.isCrossDomainUrl(url);
+                ajax.request(url, {
+                    'timeout': 100000,
+                    'dataType': isJsonp ? 'jsonp':'',
+                    'data': utils.extend({
+                            start: this.listIndex,
+                            size: this.listSize
+                        }, editor.queryCommandValue('serverparam')),
+                    'method': 'get',
+                    'onsuccess': function (r) {
+                        try {
+                            var json = isJsonp ? r:eval('(' + r.responseText + ')');
+                            if (json.state == 'SUCCESS') {
+                                _this.pushData(json.list);
+                                _this.listIndex = parseInt(json.start) + parseInt(json.list.length);
+                                if(_this.listIndex >= json.total) {
+                                    _this.listEnd = true;
+                                }
+                                _this.isLoadingData = false;
+                            }
+                        } catch (e) {
+                            if(r.responseText.indexOf('ue_separate_ue') != -1) {
+                                var list = r.responseText.split(r.responseText);
+                                _this.pushData(list);
+                                _this.listIndex = parseInt(list.length);
+                                _this.listEnd = true;
+                                _this.isLoadingData = false;
+                            }
+                        }
+                    },
+                    'onerror': function () {
+                        _this.isLoadingData = false;
+                    }
+                });
+            }
+        },
+        /* 添加图片到列表界面上 */
+        pushData: function (list) {
+            var i, item, img, icon, _this = this,
+                urlPrefix = editor.getOpt('imageManagerUrlPrefix');
+            for (i = 0; i < list.length; i++) {
+                if(list[i] && list[i].url) {
+                    item = document.createElement('li');
+                    img = document.createElement('img');
+                    icon = document.createElement('span');
+
+                    domUtils.on(img, 'load', (function(image){
+                        return function(){
+                            _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);
+                        }
+                    })(img));
+                    img.width = 113;
+                    img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );
+                    img.setAttribute('_src', urlPrefix + list[i].url);
+                    domUtils.addClass(icon, 'icon');
+
+                    item.appendChild(img);
+                    item.appendChild(icon);
+                    this.list.insertBefore(item, this.clearFloat);
+                }
+            }
+        },
+        /* 改变图片大小 */
+        scale: function (img, w, h, type) {
+            var ow = img.width,
+                oh = img.height;
+
+            if (type == 'justify') {
+                if (ow >= oh) {
+                    img.width = w;
+                    img.height = h * oh / ow;
+                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+                } else {
+                    img.width = w * ow / oh;
+                    img.height = h;
+                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+                }
+            } else {
+                if (ow >= oh) {
+                    img.width = w * ow / oh;
+                    img.height = h;
+                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';
+                } else {
+                    img.width = w;
+                    img.height = h * oh / ow;
+                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';
+                }
+            }
+        },
+        getInsertList: function () {
+            var i, lis = this.list.children, list = [], align = getAlign();
+            for (i = 0; i < lis.length; i++) {
+                if (domUtils.hasClass(lis[i], 'selected')) {
+                    var img = lis[i].firstChild,
+                        src = img.getAttribute('_src');
+                    list.push({
+                        src: src,
+                        _src: src,
+                        floatStyle: align
+                    });
+                }
+
+            }
+            return list;
+        }
+    };
+
+    dialog.onok = function () {
+        updateBackground();
+        editor.fireEvent('saveScene');
+    };
+    dialog.oncancel = function () {
+        editor.execCommand('background', backupStyle);
+    };
+
+})();

BIN
xinkeaboard-admin/public/UEditor/dialogs/background/images/bg.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/background/images/success.png


+ 65 - 0
xinkeaboard-admin/public/UEditor/dialogs/charts/chart.config.js

@@ -0,0 +1,65 @@
+/*
+ * 图表配置文件
+ * */
+
+
+//不同类型的配置
+var typeConfig = [
+    {
+        chart: {
+            type: 'line'
+        },
+        plotOptions: {
+            line: {
+                dataLabels: {
+                    enabled: false
+                },
+                enableMouseTracking: true
+            }
+        }
+    }, {
+        chart: {
+            type: 'line'
+        },
+        plotOptions: {
+            line: {
+                dataLabels: {
+                    enabled: true
+                },
+                enableMouseTracking: false
+            }
+        }
+    }, {
+        chart: {
+            type: 'area'
+        }
+    }, {
+        chart: {
+            type: 'bar'
+        }
+    }, {
+        chart: {
+            type: 'column'
+        }
+    }, {
+        chart: {
+            plotBackgroundColor: null,
+            plotBorderWidth: null,
+            plotShadow: false
+        },
+        plotOptions: {
+            pie: {
+                allowPointSelect: true,
+                cursor: 'pointer',
+                dataLabels: {
+                    enabled: true,
+                    color: '#000000',
+                    connectorColor: '#000000',
+                    formatter: function() {
+                        return '<b>'+ this.point.name +'</b>: '+ ( Math.round( this.point.percentage*100 ) / 100 ) +' %';
+                    }
+                }
+            }
+        }
+    }
+];

+ 165 - 0
xinkeaboard-admin/public/UEditor/dialogs/charts/charts.css

@@ -0,0 +1,165 @@
+html, body {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    overflow-x: hidden;
+}
+
+.main {
+    width: 100%;
+    overflow: hidden;
+}
+
+.table-view {
+    height: 100%;
+    float: left;
+    margin: 20px;
+    width: 40%;
+}
+
+.table-view .table-container {
+    width: 100%;
+    margin-bottom: 50px;
+    overflow: scroll;
+}
+
+.table-view th {
+    padding: 5px 10px;
+    background-color: #F7F7F7;
+}
+
+.table-view td {
+    width: 50px;
+    text-align: center;
+    padding:0;
+}
+
+.table-container input {
+    width: 40px;
+    padding: 5px;
+    border: none;
+    outline: none;
+}
+
+.table-view caption {
+    font-size: 18px;
+    text-align: left;
+}
+
+.charts-view {
+    /*margin-left: 49%!important;*/
+    width: 50%;
+    margin-left: 49%;
+    height: 400px;
+}
+
+.charts-container {
+    border-left: 1px solid #c3c3c3;
+}
+
+.charts-format fieldset {
+    padding-left: 20px;
+    margin-bottom: 50px;
+}
+
+.charts-format legend {
+    padding-left: 10px;
+    padding-right: 10px;
+}
+
+.format-item-container {
+    padding: 20px;
+}
+
+.format-item-container label {
+    display: block;
+    margin: 10px 0;
+}
+
+.charts-format .data-item {
+    border: 1px solid black;
+    outline: none;
+    padding: 2px 3px;
+}
+
+/* 图表类型 */
+
+.charts-type {
+    margin-top: 50px;
+    height: 300px;
+}
+
+.scroll-view {
+    border: 1px solid #c3c3c3;
+    border-left: none;
+    border-right: none;
+    overflow: hidden;
+}
+
+.scroll-container {
+    margin: 20px;
+    width: 100%;
+    overflow: hidden;
+}
+
+.scroll-bed {
+    width: 10000px;
+    _margin-top: 20px;
+    -webkit-transition: margin-left .5s ease;
+    -moz-transition: margin-left .5s ease;
+    transition: margin-left .5s ease;
+}
+
+.view-box {
+    display: inline-block;
+    *display: inline;
+    *zoom: 1;
+    margin-right: 20px;
+    border: 2px solid white;
+    line-height: 0;
+    overflow: hidden;
+    cursor: pointer;
+}
+
+.view-box img {
+    border: 1px solid #cecece;
+}
+
+.view-box.selected {
+    border-color: #7274A7;
+}
+
+.button-container {
+    margin-bottom: 20px;
+    text-align: center;
+}
+
+.button-container a {
+    display: inline-block;
+    width: 100px;
+    height: 25px;
+    line-height: 25px;
+    border: 1px solid #c2ccd1;
+    margin-right: 30px;
+    text-decoration: none;
+    color: black;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+}
+
+.button-container a:HOVER {
+    background: #fcfcfc;
+}
+
+.button-container a:ACTIVE {
+    border-top-color: #c2ccd1;
+    box-shadow:inset 0 5px 4px -4px rgba(49, 49, 64, 0.1);
+}
+
+.edui-charts-not-data {
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+}

+ 89 - 0
xinkeaboard-admin/public/UEditor/dialogs/charts/charts.html

@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>chart</title>
+        <meta chartset="utf-8">
+        <link rel="stylesheet" type="text/css" href="charts.css">
+        <script type="text/javascript" src="../internal.js"></script>
+    </head>
+    <body>
+        <div class="main">
+            <div class="table-view">
+                <h3><var id="lang_data_source"></var></h3>
+                <div id="tableContainer" class="table-container"></div>
+                <h3><var id="lang_chart_format"></var></h3>
+                <form name="data-form">
+                    <div class="charts-format">
+                        <fieldset>
+                            <legend><var id="lang_data_align"></var></legend>
+                            <div class="format-item-container">
+                                <label>
+                                    <input type="radio" class="format-ctrl not-pie-item" name="charts-format" value="1" checked="checked">
+                                    <var id="lang_chart_align_same"></var>
+                                </label>
+                                <label>
+                                    <input type="radio" class="format-ctrl not-pie-item" name="charts-format" value="-1">
+                                    <var id="lang_chart_align_reverse"></var>
+                                </label>
+                                <br>
+                            </div>
+                        </fieldset>
+                        <fieldset>
+                            <legend><var id="lang_chart_title"></var></legend>
+                            <div class="format-item-container">
+                                <label>
+                                    <var id="lang_chart_main_title"></var><input type="text" name="title" class="data-item">
+                                </label>
+                                <label>
+                                    <var id="lang_chart_sub_title"></var><input type="text" name="sub-title" class="data-item not-pie-item">
+                                </label>
+                                <label>
+                                    <var id="lang_chart_x_title"></var><input type="text" name="x-title" class="data-item not-pie-item">
+                                </label>
+                                <label>
+                                    <var id="lang_chart_y_title"></var><input type="text" name="y-title" class="data-item not-pie-item">
+                                </label>
+                            </div>
+                        </fieldset>
+                        <fieldset>
+                            <legend><var id="lang_chart_tip"></var></legend>
+                            <div class="format-item-container">
+                                <label>
+                                    <var id="lang_cahrt_tip_prefix"></var>
+                                    <input type="text" id="tipInput" name="tip" class="data-item" disabled="disabled">
+                                </label>
+                                <p><var id="lang_cahrt_tip_description"></var></p>
+                            </div>
+                        </fieldset>
+                        <fieldset>
+                            <legend><var id="lang_chart_data_unit"></var></legend>
+                            <div class="format-item-container">
+                                <label><var id="lang_chart_data_unit_title"></var><input type="text" name="unit" class="data-item"></label>
+                                <p><var id="lang_chart_data_unit_description"></var></p>
+                            </div>
+                        </fieldset>
+                    </div>
+                </form>
+            </div>
+            <div class="charts-view">
+                <div id="chartsContainer" class="charts-container"></div>
+                <div id="chartsType" class="charts-type">
+                    <h3><var id="lang_chart_type"></var></h3>
+                    <div class="scroll-view">
+                        <div class="scroll-container">
+                            <div id="scrollBed" class="scroll-bed"></div>
+                        </div>
+                        <div id="buttonContainer" class="button-container">
+                            <a href="#" data-title="prev"><var id="lang_prev_btn"></var></a>
+                            <a href="#" data-title="next"><var id="lang_next_btn"></var></a>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <script src="../../third-party/jquery-1.10.2.min.js"></script>
+        <script src="../../third-party/highcharts/highcharts.js"></script>
+        <script src="chart.config.js"></script>
+        <script src="charts.js"></script>
+    </body>
+</html>

+ 519 - 0
xinkeaboard-admin/public/UEditor/dialogs/charts/charts.js

@@ -0,0 +1,519 @@
+/*
+ * 图片转换对话框脚本
+ **/
+
+var tableData = [],
+    //编辑器页面table
+    editorTable = null,
+    chartsConfig = window.typeConfig,
+    resizeTimer = null,
+    //初始默认图表类型
+    currentChartType = 0;
+
+window.onload = function () {
+
+    editorTable = domUtils.findParentByTagName( editor.selection.getRange().startContainer, 'table', true);
+
+    //未找到表格, 显示错误页面
+    if ( !editorTable ) {
+        document.body.innerHTML = "<div class='edui-charts-not-data'>未找到数据</div>";
+        return;
+    }
+
+    //初始化图表类型选择
+    initChartsTypeView();
+    renderTable( editorTable );
+    initEvent();
+    initUserConfig( editorTable.getAttribute( "data-chart" ) );
+    $( "#scrollBed .view-box:eq("+ currentChartType +")" ).trigger( "click" );
+    updateViewType( currentChartType );
+
+    dialog.addListener( "resize", function () {
+
+        if ( resizeTimer != null ) {
+            window.clearTimeout( resizeTimer );
+        }
+
+        resizeTimer = window.setTimeout( function () {
+
+            resizeTimer = null;
+
+            renderCharts();
+
+        }, 500 );
+
+    } );
+
+};
+
+function initChartsTypeView () {
+
+    var contents = [];
+
+    for ( var i = 0, len = chartsConfig.length; i<len; i++ ) {
+
+        contents.push( '<div class="view-box" data-chart-type="'+ i +'"><img width="300" src="images/charts'+ i +'.png"></div>' );
+
+    }
+
+    $( "#scrollBed" ).html( contents.join( "" ) );
+
+}
+
+//渲染table, 以便用户修改数据
+function renderTable ( table ) {
+
+    var tableHtml = [];
+
+    //构造数据
+    for ( var i = 0, row; row = table.rows[ i ]; i++ ) {
+
+        tableData[ i ] = [];
+        tableHtml[ i ] = [];
+
+        for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) {
+
+            var value = getCellValue( cell );
+
+            if ( i > 0 && j > 0 ) {
+                value = +value;
+            }
+
+            if ( i === 0 || j === 0 ) {
+                tableHtml[ i ].push( '<th>'+ value +'</th>' );
+            } else {
+                tableHtml[ i ].push( '<td><input type="text" class="data-item" value="'+ value +'"></td>' );
+            }
+
+            tableData[ i ][ j ] = value;
+
+        }
+
+        tableHtml[ i ] = tableHtml[ i ].join( "" );
+
+    }
+
+    //draw 表格
+    $( "#tableContainer" ).html( '<table id="showTable" border="1"><tbody><tr>'+ tableHtml.join( "</tr><tr>" ) +'</tr></tbody></table>' );
+
+}
+
+/*
+ * 根据表格已有的图表属性初始化当前图表属性
+ */
+function initUserConfig ( config ) {
+
+    var parsedConfig = {};
+
+    if ( !config ) {
+        return;
+    }
+
+    config = config.split( ";" );
+
+    $.each( config, function ( index, item ) {
+
+        item = item.split( ":" );
+        parsedConfig[ item[ 0 ] ] = item[ 1 ];
+
+    } );
+
+    setUserConfig( parsedConfig );
+
+}
+
+function initEvent () {
+
+    var cacheValue = null,
+        //图表类型数
+        typeViewCount = chartsConfig.length- 1,
+        $chartsTypeViewBox = $( '#scrollBed .view-box' );
+
+    $( ".charts-format" ).delegate( ".format-ctrl", "change", function () {
+
+        renderCharts();
+
+    } )
+
+    $( ".table-view" ).delegate( ".data-item", "focus", function () {
+
+        cacheValue = this.value;
+
+    } ).delegate( ".data-item", "blur", function () {
+
+        if ( this.value !== cacheValue ) {
+            renderCharts();
+        }
+
+        cacheValue = null;
+
+    } );
+
+    $( "#buttonContainer" ).delegate( "a", "click", function (e) {
+
+        e.preventDefault();
+
+        if ( this.getAttribute( "data-title" ) === 'prev' ) {
+
+            if ( currentChartType > 0 ) {
+                currentChartType--;
+                updateViewType( currentChartType );
+            }
+
+        } else {
+
+            if ( currentChartType < typeViewCount ) {
+                currentChartType++;
+                updateViewType( currentChartType );
+            }
+
+        }
+
+    } );
+
+    //图表类型变化
+    $( '#scrollBed' ).delegate( ".view-box", "click", function (e) {
+
+        var index = $( this ).attr( "data-chart-type" );
+        $chartsTypeViewBox.removeClass( "selected" );
+        $( $chartsTypeViewBox[ index ] ).addClass( "selected" );
+
+        currentChartType = index | 0;
+
+        //饼图, 禁用部分配置
+        if ( currentChartType === chartsConfig.length - 1 ) {
+
+            disableNotPieConfig();
+
+        //启用完整配置
+        } else {
+
+            enableNotPieConfig();
+
+        }
+
+        renderCharts();
+
+    } );
+
+}
+
+function renderCharts () {
+
+    var data = collectData();
+
+    $('#chartsContainer').highcharts( $.extend( {}, chartsConfig[ currentChartType ], {
+
+        credits: {
+            enabled: false
+        },
+        exporting: {
+            enabled: false
+        },
+        title: {
+            text: data.title,
+            x: -20 //center
+        },
+        subtitle: {
+            text: data.subTitle,
+            x: -20
+        },
+        xAxis: {
+            title: {
+                text: data.xTitle
+            },
+            categories: data.categories
+        },
+        yAxis: {
+            title: {
+                text: data.yTitle
+            },
+            plotLines: [{
+                value: 0,
+                width: 1,
+                color: '#808080'
+            }]
+        },
+        tooltip: {
+            enabled: true,
+            valueSuffix: data.suffix
+        },
+        legend: {
+            layout: 'vertical',
+            align: 'right',
+            verticalAlign: 'middle',
+            borderWidth: 1
+        },
+        series: data.series
+
+    } ));
+
+}
+
+function updateViewType ( index ) {
+
+    $( "#scrollBed" ).css( 'marginLeft', -index*324+'px' );
+
+}
+
+function collectData () {
+
+    var form = document.forms[ 'data-form' ],
+        data = null;
+
+    if ( currentChartType !== chartsConfig.length - 1 ) {
+
+        data = getSeriesAndCategories();
+        $.extend( data, getUserConfig() );
+
+    //饼图数据格式
+    } else {
+        data = getSeriesForPieChart();
+        data.title = form[ 'title' ].value;
+        data.suffix = form[ 'unit' ].value;
+    }
+
+    return data;
+
+}
+
+/**
+ * 获取用户配置信息
+ */
+function getUserConfig () {
+
+    var form = document.forms[ 'data-form' ],
+        info = {
+            title: form[ 'title' ].value,
+            subTitle: form[ 'sub-title' ].value,
+            xTitle: form[ 'x-title' ].value,
+            yTitle: form[ 'y-title' ].value,
+            suffix: form[ 'unit' ].value,
+            //数据对齐方式
+            tableDataFormat: getTableDataFormat (),
+            //饼图提示文字
+            tip: $( "#tipInput" ).val()
+        };
+
+    return info;
+
+}
+
+function setUserConfig ( config ) {
+
+    var form = document.forms[ 'data-form' ];
+
+    config.title && ( form[ 'title' ].value = config.title );
+    config.subTitle && ( form[ 'sub-title' ].value = config.subTitle );
+    config.xTitle && ( form[ 'x-title' ].value = config.xTitle );
+    config.yTitle && ( form[ 'y-title' ].value = config.yTitle );
+    config.suffix && ( form[ 'unit' ].value = config.suffix );
+    config.dataFormat == "-1" && ( form[ 'charts-format' ][ 1 ].checked = true );
+    config.tip && ( form[ 'tip' ].value = config.tip );
+    currentChartType = config.chartType || 0;
+
+}
+
+function getSeriesAndCategories () {
+
+    var form = document.forms[ 'data-form' ],
+        series = [],
+        categories = [],
+        tmp = [],
+        tableData = getTableData();
+
+    //反转数据
+    if ( getTableDataFormat() === "-1" ) {
+
+        for ( var i = 0, len = tableData.length; i < len; i++ ) {
+
+            for ( var j = 0, jlen = tableData[ i ].length; j < jlen; j++ ) {
+
+                if ( !tmp[ j ] ) {
+                    tmp[ j ] = [];
+                }
+
+                tmp[ j ][ i ] = tableData[ i ][ j ];
+
+            }
+
+        }
+
+        tableData = tmp;
+
+    }
+
+    categories = tableData[0].slice( 1 );
+
+    for ( var i = 1, data; data = tableData[ i ]; i++ ) {
+
+        series.push( {
+            name: data[ 0 ],
+            data: data.slice( 1 )
+        } );
+
+    }
+
+    return {
+        series: series,
+        categories: categories
+    };
+
+}
+
+/*
+ * 获取数据源数据对齐方式
+ */
+function getTableDataFormat () {
+
+    var form = document.forms[ 'data-form' ],
+        items = form['charts-format'];
+
+    return items[ 0 ].checked ? items[ 0 ].value : items[ 1 ].value;
+
+}
+
+/*
+ * 禁用非饼图类型的配置项
+ */
+function disableNotPieConfig() {
+
+    updateConfigItem( 'disable' );
+
+}
+
+/*
+ * 启用非饼图类型的配置项
+ */
+function enableNotPieConfig() {
+
+    updateConfigItem( 'enable' );
+
+}
+
+function updateConfigItem ( value ) {
+
+    var table = $( "#showTable" )[ 0 ],
+        isDisable = value === 'disable' ? true : false;
+
+    //table中的input处理
+    for ( var i = 2 , row; row = table.rows[ i ]; i++ ) {
+
+        for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
+
+            $( "input", cell ).attr( "disabled", isDisable );
+
+        }
+
+    }
+
+    //其他项处理
+    $( "input.not-pie-item" ).attr( "disabled", isDisable );
+    $( "#tipInput" ).attr( "disabled", !isDisable )
+
+}
+
+/*
+ * 获取饼图数据
+ * 饼图的数据只取第一行的
+ **/
+function getSeriesForPieChart () {
+
+    var series = {
+            type: 'pie',
+            name: $("#tipInput").val(),
+            data: []
+        },
+        tableData = getTableData();
+
+
+    for ( var j = 1, jlen = tableData[ 0 ].length; j < jlen; j++ ) {
+
+        var title = tableData[ 0 ][ j ],
+            val = tableData[ 1 ][ j ];
+
+        series.data.push( [ title, val ] );
+
+    }
+
+    return {
+        series: [ series ]
+    };
+
+}
+
+function getTableData () {
+
+    var table = document.getElementById( "showTable" ),
+        xCount = table.rows[0].cells.length - 1,
+        values = getTableInputValue();
+
+    for ( var i = 0, value; value = values[ i ]; i++ ) {
+
+        tableData[ Math.floor( i / xCount ) + 1 ][ i % xCount + 1 ] = values[ i ];
+
+    }
+
+    return tableData;
+
+}
+
+function getTableInputValue () {
+
+    var table = document.getElementById( "showTable" ),
+        inputs = table.getElementsByTagName( "input" ),
+        values = [];
+
+    for ( var i = 0, input; input = inputs[ i ]; i++ ) {
+        values.push( input.value | 0 );
+    }
+
+    return values;
+
+}
+
+function getCellValue ( cell ) {
+
+    var value = utils.trim( ( cell.innerText || cell.textContent || '' ) );
+
+    return value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' );
+
+}
+
+
+//dialog确认事件
+dialog.onok = function () {
+
+    //收集信息
+    var form = document.forms[ 'data-form' ],
+        info = getUserConfig();
+
+    //添加图表类型
+    info.chartType = currentChartType;
+
+    //同步表格数据到编辑器
+    syncTableData();
+
+    //执行图表命令
+    editor.execCommand( 'charts', info );
+
+};
+
+/*
+ * 同步图表编辑视图的表格数据到编辑器里的原始表格
+ */
+function syncTableData () {
+
+    var tableData = getTableData();
+
+    for ( var i = 1, row; row = editorTable.rows[ i ]; i++ ) {
+
+        for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
+
+            cell.innerHTML = tableData[ i ] [ j ];
+
+        }
+
+    }
+
+}

BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts0.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts1.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts2.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts3.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts4.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/charts/images/charts5.png


+ 43 - 0
xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.css

@@ -0,0 +1,43 @@
+.jd img{
+    background:transparent url(images/jxface2.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+.pp img{
+    background:transparent url(images/fface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:25px;height:25px;display:block;
+}
+.ldw img{
+    background:transparent url(images/wface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+.tsj img{
+    background:transparent url(images/tface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+.cat img{
+    background:transparent url(images/cface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+.bb img{
+    background:transparent url(images/bface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+.youa img{
+    background:transparent url(images/yface.gif?v=1.1) no-repeat scroll left top;
+    cursor:pointer;width:35px;height:35px;display:block;
+}
+
+.smileytable td {height: 37px;}
+#tabPanel{margin-left:5px;overflow: hidden;}
+#tabContent {float:left;background:#FFFFFF;}
+#tabContent div{display: none;width:480px;overflow:hidden;}
+#tabIconReview.show{left:17px;display:block;}
+.menuFocus{background:#ACCD3C;}
+.menuDefault{background:#FFFFFF;}
+#tabIconReview{position:absolute;left:406px;left:398px \9;top:41px;z-index:65533;width:90px;height:76px;}
+img.review{width:90px;height:76px;border:2px solid #9cb945;background:#FFFFFF;background-position:center;background-repeat:no-repeat;}
+
+.wrapper .tabbody{position:relative;float:left;clear:both;padding:10px;width: 95%;}
+.tabbody table{width: 100%;}
+.tabbody td{border:1px solid #BAC498;}
+.tabbody td span{display: block;zoom:1;padding:0 4px;}

+ 54 - 0
xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.html

@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <title></title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <meta name="robots" content="noindex, nofollow"/>
+    <script type="text/javascript" src="../internal.js"></script>
+    <link rel="stylesheet" type="text/css" href="emotion.css">
+</head>
+<body>
+<div id="tabPanel" class="wrapper">
+    <div id="tabHeads" class="tabhead">
+        <span><var id="lang_input_choice"></var></span>
+        <span><var id="lang_input_Tuzki"></var></span>
+        <span><var id="lang_input_lvdouwa"></var></span>
+        <span><var id="lang_input_BOBO"></var></span>
+        <span><var id="lang_input_babyCat"></var></span>
+        <span><var id="lang_input_bubble"></var></span>
+        <span><var id="lang_input_youa"></var></span>
+    </div>
+    <div id="tabBodys" class="tabbody">
+        <div id="tab0"></div>
+        <div id="tab1"></div>
+        <div id="tab2"></div>
+        <div id="tab3"></div>
+        <div id="tab4"></div>
+        <div id="tab5"></div>
+        <div id="tab6"></div>
+    </div>
+</div>
+<div id="tabIconReview">
+    <img id='faceReview' class='review' src="../../themes/default/images/spacer.gif"/>
+</div>
+<script type="text/javascript" src="emotion.js"></script>
+<script type="text/javascript">
+    var emotion = {
+        tabNum:7, //切换面板数量
+        SmilmgName:{ tab0:['j_00', 84], tab1:['t_00', 40], tab2:['w_00', 52], tab3:['B_00', 63], tab4:['C_00', 20], tab5:['i_f', 50], tab6:['y_00', 40] }, //图片前缀名
+        imageFolders:{ tab0:'jx2/', tab1:'tsj/', tab2:'ldw/', tab3:'bobo/', tab4:'babycat/', tab5:'face/', tab6:'youa/'}, //图片对应文件夹路径
+        imageCss:{tab0:'jd', tab1:'tsj', tab2:'ldw', tab3:'bb', tab4:'cat', tab5:'pp', tab6:'youa'}, //图片css类名
+        imageCssOffset:{tab0:35, tab1:35, tab2:35, tab3:35, tab4:35, tab5:25, tab6:35}, //图片偏移
+        SmileyInfor:{
+            tab0:['Kiss', 'Love', 'Yeah', '啊!', '背扭', '顶', '抖胸', '88', '汗', '瞌睡', '鲁拉', '拍砖', '揉脸', '生日快乐', '大笑', '瀑布汗~', '惊讶', '臭美', '傻笑', '抛媚眼', '发怒', '打酱油', '俯卧撑', '气愤', '?', '吻', '怒', '胜利', 'HI', 'KISS', '不说', '不要', '扯花', '大心', '顶', '大惊', '飞吻', '鬼脸', '害羞', '口水', '狂哭', '来', '发财了', '吃西瓜', '套牢', '害羞', '庆祝', '我来了', '敲打', '晕了', '胜利', '臭美', '被打了', '贪吃', '迎接', '酷', '微笑', '亲吻', '调皮', '惊恐', '耍酷', '发火', '害羞', '汗水', '大哭', '', '加油', '困', '你NB', '晕倒', '开心', '偷笑', '大哭', '滴汗', '叹气', '超赞', '??', '飞吻', '天使', '撒花', '生气', '被砸', '吓傻', '随意吐'],
+            tab1:['Kiss', 'Love', 'Yeah', '啊!', '背扭', '顶', '抖胸', '88', '汗', '瞌睡', '鲁拉', '拍砖', '揉脸', '生日快乐', '摊手', '睡觉', '瘫坐', '无聊', '星星闪', '旋转', '也不行', '郁闷', '正Music', '抓墙', '撞墙至死', '歪头', '戳眼', '飘过', '互相拍砖', '砍死你', '扔桌子', '少林寺', '什么?', '转头', '我爱牛奶', '我踢', '摇晃', '晕厥', '在笼子里', '震荡'],
+            tab2:['大笑', '瀑布汗~', '惊讶', '臭美', '傻笑', '抛媚眼', '发怒', '我错了', 'money', '气愤', '挑逗', '吻', '怒', '胜利', '委屈', '受伤', '说啥呢?', '闭嘴', '不', '逗你玩儿', '飞吻', '眩晕', '魔法', '我来了', '睡了', '我打', '闭嘴', '打', '打晕了', '刷牙', '爆揍', '炸弹', '倒立', '刮胡子', '邪恶的笑', '不要不要', '爱恋中', '放大仔细看', '偷窥', '超高兴', '晕', '松口气', '我跑', '享受', '修养', '哭', '汗', '啊~', '热烈欢迎', '打酱油', '俯卧撑', '?'],
+            tab3:['HI', 'KISS', '不说', '不要', '扯花', '大心', '顶', '大惊', '飞吻', '鬼脸', '害羞', '口水', '狂哭', '来', '泪眼', '流泪', '生气', '吐舌', '喜欢', '旋转', '再见', '抓狂', '汗', '鄙视', '拜', '吐血', '嘘', '打人', '蹦跳', '变脸', '扯肉', '吃To', '吃花', '吹泡泡糖', '大变身', '飞天舞', '回眸', '可怜', '猛抽', '泡泡', '苹果', '亲', '', '骚舞', '烧香', '睡', '套娃娃', '捅捅', '舞倒', '西红柿', '爱慕', '摇', '摇摆', '杂耍', '招财', '被殴', '被球闷', '大惊', '理想', '欧打', '呕吐', '碎', '吐痰'],
+            tab4:['发财了', '吃西瓜', '套牢', '害羞', '庆祝', '我来了', '敲打', '晕了', '胜利', '臭美', '被打了', '贪吃', '迎接', '酷', '顶', '幸运', '爱心', '躲', '送花', '选择'],
+            tab5:['微笑', '亲吻', '调皮', '惊讶', '耍酷', '发火', '害羞', '汗水', '大哭', '得意', '鄙视', '困', '夸奖', '晕倒', '疑问', '媒婆', '狂吐', '青蛙', '发愁', '亲吻', '', '爱心', '心碎', '玫瑰', '礼物', '哭', '奸笑', '可爱', '得意', '呲牙', '暴汗', '楚楚可怜', '困', '哭', '生气', '惊讶', '口水', '彩虹', '夜空', '太阳', '钱钱', '灯泡', '咖啡', '蛋糕', '音乐', '爱', '胜利', '赞', '鄙视', 'OK'],
+            tab6:['男兜', '女兜', '开心', '乖乖', '偷笑', '大笑', '抽泣', '大哭', '无奈', '滴汗', '叹气', '狂晕', '委屈', '超赞', '??', '疑问', '飞吻', '天使', '撒花', '生气', '被砸', '口水', '泪奔', '吓傻', '吐舌头', '点头', '随意吐', '旋转', '困困', '鄙视', '狂顶', '篮球', '再见', '欢迎光临', '恭喜发财', '稍等', '我在线', '恕不议价', '库房有货', '货在路上']
+        }
+    };
+</script>
+</body>
+</html>

+ 186 - 0
xinkeaboard-admin/public/UEditor/dialogs/emotion/emotion.js

@@ -0,0 +1,186 @@
+window.onload = function () {
+    editor.setOpt({
+        emotionLocalization:false
+    });
+
+    emotion.SmileyPath = editor.options.emotionLocalization === true ? 'images/' : "http://img.baidu.com/hi/";
+    emotion.SmileyBox = createTabList( emotion.tabNum );
+    emotion.tabExist = createArr( emotion.tabNum );
+
+    initImgName();
+    initEvtHandler( "tabHeads" );
+};
+
+function initImgName() {
+    for ( var pro in emotion.SmilmgName ) {
+        var tempName = emotion.SmilmgName[pro],
+                tempBox = emotion.SmileyBox[pro],
+                tempStr = "";
+
+        if ( tempBox.length ) return;
+        for ( var i = 1; i <= tempName[1]; i++ ) {
+            tempStr = tempName[0];
+            if ( i < 10 ) tempStr = tempStr + '0';
+            tempStr = tempStr + i + '.gif';
+            tempBox.push( tempStr );
+        }
+    }
+}
+
+function initEvtHandler( conId ) {
+    var tabHeads = $G( conId );
+    for ( var i = 0, j = 0; i < tabHeads.childNodes.length; i++ ) {
+        var tabObj = tabHeads.childNodes[i];
+        if ( tabObj.nodeType == 1 ) {
+            domUtils.on( tabObj, "click", (function ( index ) {
+                return function () {
+                    switchTab( index );
+                };
+            })( j ) );
+            j++;
+        }
+    }
+    switchTab( 0 );
+    $G( "tabIconReview" ).style.display = 'none';
+}
+
+function InsertSmiley( url, evt ) {
+    var obj = {
+        src:editor.options.emotionLocalization ? editor.options.UEDITOR_HOME_URL + "dialogs/emotion/" + url : url
+    };
+    obj._src = obj.src;
+    editor.execCommand( 'insertimage', obj );
+    if ( !evt.ctrlKey ) {
+        dialog.popup.hide();
+    }
+}
+
+function switchTab( index ) {
+
+    autoHeight( index );
+    if ( emotion.tabExist[index] == 0 ) {
+        emotion.tabExist[index] = 1;
+        createTab( 'tab' + index );
+    }
+    //获取呈现元素句柄数组
+    var tabHeads = $G( "tabHeads" ).getElementsByTagName( "span" ),
+            tabBodys = $G( "tabBodys" ).getElementsByTagName( "div" ),
+            i = 0, L = tabHeads.length;
+    //隐藏所有呈现元素
+    for ( ; i < L; i++ ) {
+        tabHeads[i].className = "";
+        tabBodys[i].style.display = "none";
+    }
+    //显示对应呈现元素
+    tabHeads[index].className = "focus";
+    tabBodys[index].style.display = "block";
+}
+
+function autoHeight( index ) {
+    var iframe = dialog.getDom( "iframe" ),
+            parent = iframe.parentNode.parentNode;
+    switch ( index ) {
+        case 0:
+            iframe.style.height = "380px";
+            parent.style.height = "392px";
+            break;
+        case 1:
+            iframe.style.height = "220px";
+            parent.style.height = "232px";
+            break;
+        case 2:
+            iframe.style.height = "260px";
+            parent.style.height = "272px";
+            break;
+        case 3:
+            iframe.style.height = "300px";
+            parent.style.height = "312px";
+            break;
+        case 4:
+            iframe.style.height = "140px";
+            parent.style.height = "152px";
+            break;
+        case 5:
+            iframe.style.height = "260px";
+            parent.style.height = "272px";
+            break;
+        case 6:
+            iframe.style.height = "230px";
+            parent.style.height = "242px";
+            break;
+        default:
+
+    }
+}
+
+
+function createTab( tabName ) {
+    var faceVersion = "?v=1.1", //版本号
+            tab = $G( tabName ), //获取将要生成的Div句柄
+            imagePath = emotion.SmileyPath + emotion.imageFolders[tabName], //获取显示表情和预览表情的路径
+            positionLine = 11 / 2, //中间数
+            iWidth = iHeight = 35, //图片长宽
+            iColWidth = 3, //表格剩余空间的显示比例
+            tableCss = emotion.imageCss[tabName],
+            cssOffset = emotion.imageCssOffset[tabName],
+            textHTML = ['<table class="smileytable">'],
+            i = 0, imgNum = emotion.SmileyBox[tabName].length, imgColNum = 11, faceImage,
+            sUrl, realUrl, posflag, offset, infor;
+
+    for ( ; i < imgNum; ) {
+        textHTML.push( '<tr>' );
+        for ( var j = 0; j < imgColNum; j++, i++ ) {
+            faceImage = emotion.SmileyBox[tabName][i];
+            if ( faceImage ) {
+                sUrl = imagePath + faceImage + faceVersion;
+                realUrl = imagePath + faceImage;
+                posflag = j < positionLine ? 0 : 1;
+                offset = cssOffset * i * (-1) - 1;
+                infor = emotion.SmileyInfor[tabName][i];
+
+                textHTML.push( '<td  class="' + tableCss + '"   border="1" width="' + iColWidth + '%" style="border-collapse:collapse;" align="center"  bgcolor="transparent" onclick="InsertSmiley(\'' + realUrl.replace( /'/g, "\\'" ) + '\',event)" onmouseover="over(this,\'' + sUrl + '\',\'' + posflag + '\')" onmouseout="out(this)">' );
+                textHTML.push( '<span>' );
+                textHTML.push( '<img  style="background-position:left ' + offset + 'px;" title="' + infor + '" src="' + emotion.SmileyPath + (editor.options.emotionLocalization ? '0.gif" width="' : 'default/0.gif" width="') + iWidth + '" height="' + iHeight + '"></img>' );
+                textHTML.push( '</span>' );
+            } else {
+                textHTML.push( '<td width="' + iColWidth + '%"   bgcolor="#FFFFFF">' );
+            }
+            textHTML.push( '</td>' );
+        }
+        textHTML.push( '</tr>' );
+    }
+    textHTML.push( '</table>' );
+    textHTML = textHTML.join( "" );
+    tab.innerHTML = textHTML;
+}
+
+function over( td, srcPath, posFlag ) {
+    td.style.backgroundColor = "#ACCD3C";
+    $G( 'faceReview' ).style.backgroundImage = "url(" + srcPath + ")";
+    if ( posFlag == 1 ) $G( "tabIconReview" ).className = "show";
+    $G( "tabIconReview" ).style.display = 'block';
+}
+
+function out( td ) {
+    td.style.backgroundColor = "transparent";
+    var tabIconRevew = $G( "tabIconReview" );
+    tabIconRevew.className = "";
+    tabIconRevew.style.display = 'none';
+}
+
+function createTabList( tabNum ) {
+    var obj = {};
+    for ( var i = 0; i < tabNum; i++ ) {
+        obj["tab" + i] = [];
+    }
+    return obj;
+}
+
+function createArr( tabNum ) {
+    var arr = [];
+    for ( var i = 0; i < tabNum; i++ ) {
+        arr[i] = 0;
+    }
+    return arr;
+}
+

BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/0.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/bface.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/cface.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/fface.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/jxface2.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/neweditor-tab-bg.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/tface.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/wface.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/emotion/images/yface.gif


+ 89 - 0
xinkeaboard-admin/public/UEditor/dialogs/gmap/gmap.html

@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title></title>
+    <script type="text/javascript" src="../internal.js"></script>
+    <style type="text/css">
+        .content{width:530px; height: 350px;margin: 10px auto;}
+        .content table{width: 100%}
+        .content table td{vertical-align: middle;}
+        #address{width:220px;height:21px;background: #FFF;border:1px solid #d7d7d7; line-height: 21px;}
+    </style>
+    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
+</head>
+<body>
+<div class="content">
+    <table>
+        <tr>
+            <td><label for="address"><var id="lang_input_address"></var></label></td>
+            <td><input id="address" type="text" /></td>
+            <td><a id="doSearch" href="javascript:void(0)" class="button"><var id="lang_input_search"></var></a></td>
+        </tr>
+    </table>
+    <div id="container" style="width: 100%; height: 340px;margin: 5px auto; border: 1px solid gray;"></div>
+</div>
+<script type="text/javascript">
+    domUtils.on(window,"load",function(){
+        var map = new google.maps.Map(document.getElementById('container'), {
+                zoom: 3,
+                streetViewControl: false,
+                scaleControl: true,
+                mapTypeId: google.maps.MapTypeId.ROADMAP
+            });
+            var imgcss;
+            var marker = new google.maps.Marker({
+                map: map,
+                draggable: true
+            });
+            function doSearch(){
+                var address = document.getElementById('address').value;
+                var geocoder = new google.maps.Geocoder();
+                geocoder.geocode( { 'address': address}, function (results, status) {
+                    if (status == google.maps.GeocoderStatus.OK) {
+                        var bounds = results[0].geometry.viewport;
+                        map.fitBounds(bounds);
+                        marker.setPosition(results[0].geometry.location);
+                        marker.setTitle(address);
+                    } else alert(lang.searchError);
+                });
+            }
+            $G('address').onkeydown = function (evt){
+                evt = evt || event;
+                if (evt.keyCode == 13) {
+                    doSearch();
+                }
+            };
+            $G("doSearch").onclick = doSearch;
+            dialog.onok = function (){
+                var center = map.getCenter();
+                var point = marker.getPosition();
+                var url = "http://maps.googleapis.com/maps/api/staticmap?center=" + center.lat() + ',' + center.lng() + "&zoom=" + map.zoom + "&size=520x340&maptype=" + map.getMapTypeId() + "&markers=" + point.lat() + ',' + point.lng() + "&sensor=false";
+                editor.execCommand('inserthtml', '<img width="520" height="340" src="' + url + '"' + (imgcss ? ' style="' + imgcss + '"' :'') + '/>');
+            };
+
+            function getPars(str,par){
+                var reg = new RegExp(par+"=((\\d+|[.,])*)","g");
+                return reg.exec(str)[1];
+            }
+            var img = editor.selection.getRange().getClosedNode();
+            if(img && img.src.indexOf("http://maps.googleapis.com/maps/api/staticmap")!=-1){
+                var url = img.getAttribute("src");
+                var centers = getPars(url,"center").split(",");
+                point = new google.maps.LatLng(Number(centers[0]),Number(centers[1]));
+                map.setCenter(point);
+                map.setZoom(Number(getPars(url,"zoom")));
+                centers = getPars(url,"markers").split(",");
+                marker.setPosition(new google.maps.LatLng(Number(centers[0]),Number(centers[1])));
+                imgcss = img.style.cssText;
+            }else{
+                setTimeout(function(){
+                    doSearch();
+                },30)
+            }
+    });
+
+</script>
+</body>
+</html>

+ 7 - 0
xinkeaboard-admin/public/UEditor/dialogs/help/help.css

@@ -0,0 +1,7 @@
+.wrapper{width: 370px;margin: 10px auto;zoom: 1;}
+.tabbody{height: 360px;}
+.tabbody .panel{width:100%;height: 360px;position: absolute;background: #fff;}
+.tabbody .panel h1{font-size:26px;margin: 5px 0 0 5px;}
+.tabbody .panel p{font-size:12px;margin: 5px 0 0 5px;}
+.tabbody table{width:90%;line-height: 20px;margin: 5px 0 0 5px;;}
+.tabbody table thead{font-weight: bold;line-height: 25px;}

+ 82 - 0
xinkeaboard-admin/public/UEditor/dialogs/help/help.html

@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <title>帮助</title>
+    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
+    <script type="text/javascript" src="../internal.js"></script>
+    <link rel="stylesheet" type="text/css" href="help.css">
+</head>
+<body>
+<div class="wrapper" id="helptab">
+    <div id="tabHeads" class="tabhead">
+        <span class="focus" tabsrc="about"><var id="lang_input_about"></var></span>
+        <span tabsrc="shortcuts"><var id="lang_input_shortcuts"></var></span>
+    </div>
+    <div id="tabBodys" class="tabbody">
+        <div id="about" class="panel">
+            <h1>UEditor</h1>
+            <p id="version"></p>
+            <p><var id="lang_input_introduction"></var></p>
+        </div>
+        <div id="shortcuts" class="panel">
+            <table>
+                <thead>
+                <tr>
+                    <td><var id="lang_Txt_shortcuts"></var></td>
+                    <td><var id="lang_Txt_func"></var></td>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>ctrl+b</td>
+                    <td><var id="lang_Txt_bold"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+c</td>
+                    <td><var id="lang_Txt_copy"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+x</td>
+                    <td><var id="lang_Txt_cut"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+v</td>
+                    <td><var id="lang_Txt_Paste"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+y</td>
+                    <td><var id="lang_Txt_undo"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+z</td>
+                    <td><var id="lang_Txt_redo"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+i</td>
+                    <td><var id="lang_Txt_italic"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+u</td>
+                    <td><var id="lang_Txt_underline"></var></td>
+                </tr>
+                <tr>
+                    <td>ctrl+a</td>
+                    <td><var id="lang_Txt_selectAll"></var></td>
+                </tr>
+                <tr>
+                    <td>shift+enter</td>
+                    <td><var id="lang_Txt_visualEnter"></var></td>
+                </tr>
+                <tr>
+                    <td>alt+z</td>
+                    <td><var id="lang_Txt_fullscreen"></var></td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+<script type="text/javascript" src="help.js"></script>
+</body>
+</html>

+ 56 - 0
xinkeaboard-admin/public/UEditor/dialogs/help/help.js

@@ -0,0 +1,56 @@
+/**
+ * Created with JetBrains PhpStorm.
+ * User: xuheng
+ * Date: 12-9-26
+ * Time: 下午1:06
+ * To change this template use File | Settings | File Templates.
+ */
+/**
+ * tab点击处理事件
+ * @param tabHeads
+ * @param tabBodys
+ * @param obj
+ */
+function clickHandler( tabHeads,tabBodys,obj ) {
+    //head样式更改
+    for ( var k = 0, len = tabHeads.length; k < len; k++ ) {
+        tabHeads[k].className = "";
+    }
+    obj.className = "focus";
+    //body显隐
+    var tabSrc = obj.getAttribute( "tabSrc" );
+    for ( var j = 0, length = tabBodys.length; j < length; j++ ) {
+        var body = tabBodys[j],
+            id = body.getAttribute( "id" );
+        body.onclick = function(){
+            this.style.zoom = 1;
+        };
+        if ( id != tabSrc ) {
+            body.style.zIndex = 1;
+        } else {
+            body.style.zIndex = 200;
+        }
+    }
+
+}
+
+/**
+ * TAB切换
+ * @param tabParentId  tab的父节点ID或者对象本身
+ */
+function switchTab( tabParentId ) {
+    var tabElements = $G( tabParentId ).children,
+        tabHeads = tabElements[0].children,
+        tabBodys = tabElements[1].children;
+
+    for ( var i = 0, length = tabHeads.length; i < length; i++ ) {
+        var head = tabHeads[i];
+        if ( head.className === "focus" )clickHandler(tabHeads,tabBodys, head );
+        head.onclick = function () {
+            clickHandler(tabHeads,tabBodys,this);
+        }
+    }
+}
+switchTab("helptab");
+
+document.getElementById('version').innerHTML = parent.UE.version;

+ 894 - 0
xinkeaboard-admin/public/UEditor/dialogs/image/image.css

@@ -0,0 +1,894 @@
+@charset "utf-8";
+/* dialog样式 */
+.wrapper {
+    zoom: 1;
+    width: 630px;
+    *width: 626px;
+    height: 380px;
+    margin: 0 auto;
+    padding: 10px;
+    position: relative;
+    font-family: sans-serif;
+}
+
+/*tab样式框大小*/
+.tabhead {
+    float:left;
+}
+.tabbody {
+    width: 100%;
+    height: 346px;
+    position: relative;
+    clear: both;
+}
+
+.tabbody .panel {
+    position: absolute;
+    width: 0;
+    height: 0;
+    background: #fff;
+    overflow: hidden;
+    display: none;
+}
+
+.tabbody .panel.focus {
+    width: 100%;
+    height: 346px;
+    display: block;
+}
+
+/* 图片对齐方式 */
+.alignBar{
+    float:right;
+    margin-top: 5px;
+    position: relative;
+}
+
+.alignBar .algnLabel{
+    float:left;
+    height: 20px;
+    line-height: 20px;
+}
+
+.alignBar #alignIcon{
+    zoom:1;
+    _display: inline;
+    display: inline-block;
+    position: relative;
+}
+.alignBar #alignIcon span{
+    float: left;
+    cursor: pointer;
+    display: block;
+    width: 19px;
+    height: 17px;
+    margin-right: 3px;
+    margin-left: 3px;
+    background-image: url(./images/alignicon.jpg);
+}
+.alignBar #alignIcon .none-align{
+    background-position: 0 -18px;
+}
+.alignBar #alignIcon .left-align{
+    background-position: -20px -18px;
+}
+.alignBar #alignIcon .right-align{
+    background-position: -40px -18px;
+}
+.alignBar #alignIcon .center-align{
+    background-position: -60px -18px;
+}
+.alignBar #alignIcon .none-align.focus{
+    background-position: 0 0;
+}
+.alignBar #alignIcon .left-align.focus{
+    background-position: -20px 0;
+}
+.alignBar #alignIcon .right-align.focus{
+    background-position: -40px 0;
+}
+.alignBar #alignIcon .center-align.focus{
+    background-position: -60px 0;
+}
+
+
+
+
+/* 远程图片样式 */
+#remote {
+    z-index: 200;
+}
+
+#remote .top{
+    width: 100%;
+    margin-top: 25px;
+}
+#remote .left{
+    display: block;
+    float: left;
+    width: 300px;
+    height:10px;
+}
+#remote .right{
+    display: block;
+    float: right;
+    width: 300px;
+    height:10px;
+}
+#remote .row{
+    margin-left: 20px;
+    clear: both;
+    height: 40px;
+}
+
+#remote .row label{
+    text-align: center;
+    width: 50px;
+    zoom:1;
+    _display: inline;
+    display:inline-block;
+    vertical-align: middle;
+}
+#remote .row label.algnLabel{
+    float: left;
+
+}
+
+#remote input.text{
+    width: 150px;
+    padding: 3px 6px;
+    font-size: 14px;
+    line-height: 1.42857143;
+    color: #555;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+    -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+#remote input.text:focus {
+    border-color: #66afe9;
+    outline: 0;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+}
+#remote #url{
+    width: 500px;
+    margin-bottom: 2px;
+}
+#remote #width,
+#remote #height{
+    width: 20px;
+    margin-left: 2px;
+    margin-right: 2px;
+}
+#remote #border,
+#remote #vhSpace,
+#remote #title{
+    width: 180px;
+    margin-right: 5px;
+}
+#remote #lock{
+}
+#remote #lockicon{
+    zoom: 1;
+    _display:inline;
+    display: inline-block;
+    width: 20px;
+    height: 20px;
+    background: url("../../themes/default/images/lock.gif") -13px -13px no-repeat;
+    vertical-align: middle;
+}
+#remote #preview{
+    clear: both;
+    width: 260px;
+    height: 240px;
+    z-index: 9999;
+    margin-top: 10px;
+    background-color: #eee;
+    overflow: hidden;
+}
+
+/* 上传图片 */
+.tabbody #upload.panel {
+    width: 0;
+    height: 0;
+    overflow: hidden;
+    position: absolute !important;
+    clip: rect(1px, 1px, 1px, 1px);
+    background: #fff;
+    display: block;
+}
+
+.tabbody #upload.panel.focus {
+    width: 100%;
+    height: 346px;
+    display: block;
+    clip: auto;
+}
+
+#upload .queueList {
+    margin: 0;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    overflow: hidden;
+}
+
+#upload p {
+    margin: 0;
+}
+
+.element-invisible {
+    width: 0 !important;
+    height: 0 !important;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    overflow: hidden;
+    position: absolute !important;
+    clip: rect(1px, 1px, 1px, 1px);
+}
+
+#upload .placeholder {
+    margin: 10px;
+    border: 2px dashed #e6e6e6;
+    *border: 0px dashed #e6e6e6;
+    height: 172px;
+    padding-top: 150px;
+    text-align: center;
+    background: url(./images/image.png) center 70px no-repeat;
+    color: #cccccc;
+    font-size: 18px;
+    position: relative;
+    top:0;
+    *top: 10px;
+}
+
+#upload .placeholder .webuploader-pick {
+    font-size: 18px;
+    background: #00b7ee;
+    border-radius: 3px;
+    line-height: 44px;
+    padding: 0 30px;
+    *width: 120px;
+    color: #fff;
+    display: inline-block;
+    margin: 0 auto 20px auto;
+    cursor: pointer;
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+
+#upload .placeholder .webuploader-pick-hover {
+    background: #00a2d4;
+}
+
+
+#filePickerContainer {
+    text-align: center;
+}
+
+#upload .placeholder .flashTip {
+    color: #666666;
+    font-size: 12px;
+    position: absolute;
+    width: 100%;
+    text-align: center;
+    bottom: 20px;
+}
+
+#upload .placeholder .flashTip a {
+    color: #0785d1;
+    text-decoration: none;
+}
+
+#upload .placeholder .flashTip a:hover {
+    text-decoration: underline;
+}
+
+#upload .placeholder.webuploader-dnd-over {
+    border-color: #999999;
+}
+
+#upload .filelist {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+    overflow-x: hidden;
+    overflow-y: auto;
+    position: relative;
+    height: 300px;
+}
+
+#upload .filelist:after {
+    content: '';
+    display: block;
+    width: 0;
+    height: 0;
+    overflow: hidden;
+    clear: both;
+    position: relative;
+}
+
+#upload .filelist li {
+    width: 113px;
+    height: 113px;
+    background: url(./images/bg.png);
+    text-align: center;
+    margin: 9px 0 0 9px;
+    *margin: 6px 0 0 6px;
+    position: relative;
+    display: block;
+    float: left;
+    overflow: hidden;
+    font-size: 12px;
+}
+
+#upload .filelist li p.log {
+    position: relative;
+    top: -45px;
+}
+
+#upload .filelist li p.title {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    top: 5px;
+    text-indent: 5px;
+    text-align: left;
+}
+
+#upload .filelist li p.progress {
+    position: absolute;
+    width: 100%;
+    bottom: 0;
+    left: 0;
+    height: 8px;
+    overflow: hidden;
+    z-index: 50;
+    margin: 0;
+    border-radius: 0;
+    background: none;
+    -webkit-box-shadow: 0 0 0;
+}
+
+#upload .filelist li p.progress span {
+    display: none;
+    overflow: hidden;
+    width: 0;
+    height: 100%;
+    background: #1483d8 url(./images/progress.png) repeat-x;
+
+    -webit-transition: width 200ms linear;
+    -moz-transition: width 200ms linear;
+    -o-transition: width 200ms linear;
+    -ms-transition: width 200ms linear;
+    transition: width 200ms linear;
+
+    -webkit-animation: progressmove 2s linear infinite;
+    -moz-animation: progressmove 2s linear infinite;
+    -o-animation: progressmove 2s linear infinite;
+    -ms-animation: progressmove 2s linear infinite;
+    animation: progressmove 2s linear infinite;
+
+    -webkit-transform: translateZ(0);
+}
+
+@-webkit-keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+@-moz-keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+@keyframes progressmove {
+    0% {
+        background-position: 0 0;
+    }
+    100% {
+        background-position: 17px 0;
+    }
+}
+
+#upload .filelist li p.imgWrap {
+    position: relative;
+    z-index: 2;
+    line-height: 113px;
+    vertical-align: middle;
+    overflow: hidden;
+    width: 113px;
+    height: 113px;
+
+    -webkit-transform-origin: 50% 50%;
+    -moz-transform-origin: 50% 50%;
+    -o-transform-origin: 50% 50%;
+    -ms-transform-origin: 50% 50%;
+    transform-origin: 50% 50%;
+
+    -webit-transition: 200ms ease-out;
+    -moz-transition: 200ms ease-out;
+    -o-transition: 200ms ease-out;
+    -ms-transition: 200ms ease-out;
+    transition: 200ms ease-out;
+}
+
+#upload .filelist li img {
+    width: 100%;
+}
+
+#upload .filelist li p.error {
+    background: #f43838;
+    color: #fff;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    height: 28px;
+    line-height: 28px;
+    width: 100%;
+    z-index: 100;
+    display:none;
+}
+
+#upload .filelist li .success {
+    display: block;
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    height: 40px;
+    width: 100%;
+    z-index: 200;
+    background: url(./images/success.png) no-repeat right bottom;
+    background: url(./images/success.gif) no-repeat right bottom \9;
+}
+
+#upload .filelist li.filePickerBlock {
+    width: 113px;
+    height: 113px;
+    background: url(./images/image.png) no-repeat center 12px;
+    border: 1px solid #eeeeee;
+    border-radius: 0;
+}
+#upload .filelist li.filePickerBlock div.webuploader-pick  {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    opacity: 0;
+    background: none;
+    font-size: 0;
+}
+
+#upload .filelist div.file-panel {
+    position: absolute;
+    height: 0;
+    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0;
+    background: rgba(0, 0, 0, 0.5);
+    width: 100%;
+    top: 0;
+    left: 0;
+    overflow: hidden;
+    z-index: 300;
+}
+
+#upload .filelist div.file-panel span {
+    width: 24px;
+    height: 24px;
+    display: inline;
+    float: right;
+    text-indent: -9999px;
+    overflow: hidden;
+    background: url(./images/icons.png) no-repeat;
+    background: url(./images/icons.gif) no-repeat \9;
+    margin: 5px 1px 1px;
+    cursor: pointer;
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+#upload .filelist div.file-panel span.rotateLeft {
+    display:none;
+    background-position: 0 -24px;
+}
+
+#upload .filelist div.file-panel span.rotateLeft:hover {
+    background-position: 0 0;
+}
+
+#upload .filelist div.file-panel span.rotateRight {
+    display:none;
+    background-position: -24px -24px;
+}
+
+#upload .filelist div.file-panel span.rotateRight:hover {
+    background-position: -24px 0;
+}
+
+#upload .filelist div.file-panel span.cancel {
+    background-position: -48px -24px;
+}
+
+#upload .filelist div.file-panel span.cancel:hover {
+    background-position: -48px 0;
+}
+
+#upload .statusBar {
+    height: 45px;
+    border-bottom: 1px solid #dadada;
+    margin: 0 10px;
+    padding: 0;
+    line-height: 45px;
+    vertical-align: middle;
+    position: relative;
+}
+
+#upload .statusBar .progress {
+    border: 1px solid #1483d8;
+    width: 198px;
+    background: #fff;
+    height: 18px;
+    position: absolute;
+    top: 12px;
+    display: none;
+    text-align: center;
+    line-height: 18px;
+    color: #6dbfff;
+    margin: 0 10px 0 0;
+}
+#upload .statusBar .progress span.percentage {
+    width: 0;
+    height: 100%;
+    left: 0;
+    top: 0;
+    background: #1483d8;
+    position: absolute;
+}
+#upload .statusBar .progress span.text {
+    position: relative;
+    z-index: 10;
+}
+
+#upload .statusBar .info {
+    display: inline-block;
+    font-size: 14px;
+    color: #666666;
+}
+
+#upload .statusBar .btns {
+    position: absolute;
+    top: 7px;
+    right: 0;
+    line-height: 30px;
+}
+
+#filePickerBtn {
+    display: inline-block;
+    float: left;
+}
+#upload .statusBar .btns .webuploader-pick,
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-uploading,
+#upload .statusBar .btns .uploadBtn.state-paused {
+    background: #ffffff;
+    border: 1px solid #cfcfcf;
+    color: #565656;
+    padding: 0 18px;
+    display: inline-block;
+    border-radius: 3px;
+    margin-left: 10px;
+    cursor: pointer;
+    font-size: 14px;
+    float: left;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+#upload .statusBar .btns .webuploader-pick-hover,
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-uploading:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover {
+    background: #f0f0f0;
+}
+
+#upload .statusBar .btns .uploadBtn,
+#upload .statusBar .btns .uploadBtn.state-paused{
+    background: #00b7ee;
+    color: #fff;
+    border-color: transparent;
+}
+#upload .statusBar .btns .uploadBtn:hover,
+#upload .statusBar .btns .uploadBtn.state-paused:hover{
+    background: #00a2d4;
+}
+
+#upload .statusBar .btns .uploadBtn.disabled {
+    pointer-events: none;
+    filter:alpha(opacity=60);
+    -moz-opacity:0.6;
+    -khtml-opacity: 0.6;
+    opacity: 0.6;
+}
+
+
+
+/* 图片管理样式 */
+#online {
+    width: 100%;
+    height: 336px;
+    padding: 10px 0 0 0;
+}
+#online #imageList{
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    overflow-y: auto;
+    position: relative;
+}
+#online ul {
+    display: block;
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+#online li {
+    float: left;
+    display: block;
+    list-style: none;
+    padding: 0;
+    width: 113px;
+    height: 113px;
+    margin: 0 0 9px 9px;
+    *margin: 0 0 6px 6px;
+    background-color: #eee;
+    overflow: hidden;
+    cursor: pointer;
+    position: relative;
+}
+#online li.clearFloat {
+    float: none;
+    clear: both;
+    display: block;
+    width:0;
+    height:0;
+    margin: 0;
+    padding: 0;
+}
+#online li img {
+    cursor: pointer;
+}
+#online li .icon {
+    cursor: pointer;
+    width: 113px;
+    height: 113px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    border: 0;
+    background-repeat: no-repeat;
+}
+#online li .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+}
+#online li.selected .icon {
+    background-image: url(images/success.png);
+    background-image: url(images/success.gif)\9;
+    background-position: 75px 75px;
+}
+#online li.selected .icon:hover {
+    width: 107px;
+    height: 107px;
+    border: 3px solid #1094fa;
+    background-position: 72px 72px;
+}
+
+
+/* 图片搜索样式 */
+#search .searchBar {
+    width: 100%;
+    height: 30px;
+    margin: 10px 0 5px 0;
+    padding: 0;
+}
+
+#search input.text{
+    width: 150px;
+    padding: 3px 6px;
+    font-size: 14px;
+    line-height: 1.42857143;
+    color: #555;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+    -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+#search input.text:focus {
+    border-color: #66afe9;
+    outline: 0;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
+}
+#search input.searchTxt {
+    margin-left:5px;
+    padding-left: 5px;
+    background: #FFF;
+    width: 300px;
+    *width: 260px;
+    height: 21px;
+    line-height: 21px;
+    float: left;
+    dislay: block;
+}
+
+#search .searchType {
+    width: 65px;
+    height: 28px;
+    padding:0;
+    line-height: 28px;
+    border: 1px solid #d7d7d7;
+    border-radius: 0;
+    vertical-align: top;
+    margin-left: 5px;
+    float: left;
+    dislay: block;
+}
+
+#search #searchBtn,
+#search #searchReset {
+    display: inline-block;
+    margin-bottom: 0;
+    margin-right: 5px;
+    padding: 4px 10px;
+    font-weight: 400;
+    text-align: center;
+    vertical-align: middle;
+    cursor: pointer;
+    background-image: none;
+    border: 1px solid transparent;
+    white-space: nowrap;
+    font-size: 14px;
+    border-radius: 4px;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    vertical-align: top;
+    float: right;
+}
+
+#search #searchBtn {
+    color: white;
+    border-color: #285e8e;
+    background-color: #3b97d7;
+}
+#search #searchReset {
+    color: #333;
+    border-color: #ccc;
+    background-color: #fff;
+}
+#search #searchBtn:hover {
+    background-color: #3276b1;
+}
+#search #searchReset:hover {
+    background-color: #eee;
+}
+
+#search .msg {
+    margin-left: 5px;
+}
+
+#search .searchList{
+    width: 100%;
+    height: 300px;
+    overflow: hidden;
+    clear: both;
+}
+#search .searchList ul{
+    margin:0;
+    padding:0;
+    list-style:none;
+    clear: both;
+    width: 100%;
+    height: 100%;
+    overflow-x: hidden;
+    overflow-y: auto;
+    zoom: 1;
+    position: relative;
+}
+
+#search .searchList li {
+    list-style:none;
+    float: left;
+    display: block;
+    width: 115px;
+    margin: 5px 10px 5px 20px;
+    *margin: 5px 10px 5px 15px;
+    padding:0;
+    font-size: 12px;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+    -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+    -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+    position: relative;
+    vertical-align: top;
+    text-align: center;
+    overflow: hidden;
+    cursor: pointer;
+    filter: alpha(Opacity=100);
+    -moz-opacity: 1;
+    opacity: 1;
+    border: 2px solid #eee;
+}
+
+#search .searchList li.selected {
+    filter: alpha(Opacity=40);
+    -moz-opacity: 0.4;
+    opacity: 0.4;
+    border: 2px solid #00a0e9;
+}
+
+#search .searchList li p {
+    background-color: #eee;
+    margin: 0;
+    padding: 0;
+    position: relative;
+    width:100%;
+    height:115px;
+    overflow: hidden;
+}
+
+#search .searchList li p img {
+    cursor: pointer;
+    border: 0;
+}
+
+#search .searchList li a {
+    color: #999;
+    border-top: 1px solid #F2F2F2;
+    background: #FAFAFA;
+    text-align: center;
+    display: block;
+    padding: 0 5px;
+    width: 105px;
+    height:32px;
+    line-height:32px;
+    white-space:nowrap;
+    text-overflow:ellipsis;
+    text-decoration: none;
+    overflow: hidden;
+    word-break: break-all;
+}
+
+#search .searchList a:hover {
+    text-decoration: underline;
+    color: #333;
+}
+#search .searchList .clearFloat{
+    clear: both;
+}

+ 120 - 0
xinkeaboard-admin/public/UEditor/dialogs/image/image.html

@@ -0,0 +1,120 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>ueditor图片对话框</title>
+    <script type="text/javascript" src="../internal.js"></script>
+
+    <!-- jquery -->
+    <script type="text/javascript" src="../../third-party/jquery-1.10.2.min.js"></script>
+
+    <!-- webuploader -->
+    <script src="../../third-party/webuploader/webuploader.min.js"></script>
+    <link rel="stylesheet" type="text/css" href="../../third-party/webuploader/webuploader.css">
+
+    <!-- image dialog -->
+    <link rel="stylesheet" href="image.css" type="text/css" />
+</head>
+<body>
+
+    <div class="wrapper">
+        <div id="tabhead" class="tabhead">
+            <span class="tab" data-content-id="remote"><var id="lang_tab_remote"></var></span>
+            <span class="tab focus" data-content-id="upload"><var id="lang_tab_upload"></var></span>
+            <span class="tab" data-content-id="online"><var id="lang_tab_online"></var></span>
+            <span class="tab" data-content-id="search"><var id="lang_tab_search"></var></span>
+        </div>
+        <div class="alignBar">
+            <label class="algnLabel"><var id="lang_input_align"></var></label>
+                    <span id="alignIcon">
+                        <span id="noneAlign" class="none-align focus" data-align="none"></span>
+                        <span id="leftAlign" class="left-align" data-align="left"></span>
+                        <span id="rightAlign" class="right-align" data-align="right"></span>
+                        <span id="centerAlign" class="center-align" data-align="center"></span>
+                    </span>
+            <input id="align" name="align" type="hidden" value="none"/>
+        </div>
+        <div id="tabbody" class="tabbody">
+
+            <!-- 远程图片 -->
+            <div id="remote" class="panel">
+                <div class="top">
+                    <div class="row">
+                        <label for="url"><var id="lang_input_url"></var></label>
+                        <span><input class="text" id="url" type="text"/></span>
+                    </div>
+                </div>
+                <div class="left">
+                    <div class="row">
+                        <label><var id="lang_input_size"></var></label>
+                        <span><var id="lang_input_width">&nbsp;&nbsp;</var><input class="text" type="text" id="width"/>px </span>
+                        <span><var id="lang_input_height">&nbsp;&nbsp;</var><input class="text" type="text" id="height"/>px </span>
+                        <span><input id="lock" type="checkbox" disabled="disabled"><span id="lockicon"></span></span>
+                    </div>
+                    <div class="row">
+                        <label><var id="lang_input_border"></var></label>
+                        <span><input class="text" type="text" id="border"/>px </span>
+                    </div>
+                    <div class="row">
+                        <label><var id="lang_input_vhspace"></var></label>
+                        <span><input class="text" type="text" id="vhSpace"/>px </span>
+                    </div>
+                    <div class="row">
+                        <label><var id="lang_input_title"></var></label>
+                        <span><input class="text" type="text" id="title"/></span>
+                    </div>
+                </div>
+                <div class="right"><div id="preview"></div></div>
+            </div>
+
+            <!-- 上传图片 -->
+            <div id="upload" class="panel focus">
+                <div id="queueList" class="queueList">
+                    <div class="statusBar element-invisible">
+                        <div class="progress">
+                            <span class="text">0%</span>
+                            <span class="percentage"></span>
+                        </div><div class="info"></div>
+                        <div class="btns">
+                            <div id="filePickerBtn"></div>
+                            <div class="uploadBtn"><var id="lang_start_upload"></var></div>
+                        </div>
+                    </div>
+                    <div id="dndArea" class="placeholder">
+                        <div class="filePickerContainer">
+                            <div id="filePickerReady"></div>
+                        </div>
+                    </div>
+                    <ul class="filelist element-invisible">
+                        <li id="filePickerBlock" class="filePickerBlock"></li>
+                    </ul>
+                </div>
+            </div>
+
+            <!-- 在线图片 -->
+            <div id="online" class="panel">
+                <div id="imageList"><var id="lang_imgLoading"></var></div>
+            </div>
+
+            <!-- 搜索图片 -->
+            <div id="search" class="panel">
+                <div class="searchBar">
+                    <input id="searchTxt" class="searchTxt text" type="text" />
+                    <select id="searchType" class="searchType">
+                        <option value="&s=4&z=0"></option>
+                        <option value="&s=1&z=19"></option>
+                        <option value="&s=2&z=0"></option>
+                        <option value="&s=3&z=0"></option>
+                    </select>
+                    <input id="searchReset" type="button"  />
+                    <input id="searchBtn" type="button"  />
+                </div>
+                <div id="searchList" class="searchList"><ul id="searchListUl"></ul></div>
+            </div>
+
+        </div>
+    </div>
+    <script type="text/javascript" src="image.js"></script>
+
+</body>
+</html>

Fichier diff supprimé car celui-ci est trop grand
+ 1031 - 0
xinkeaboard-admin/public/UEditor/dialogs/image/image.js


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/alignicon.jpg


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/bg.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/icons.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/icons.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/image.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/progress.png


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/success.gif


BIN
xinkeaboard-admin/public/UEditor/dialogs/image/images/success.png


+ 98 - 0
xinkeaboard-admin/public/UEditor/dialogs/insertframe/insertframe.html

@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title></title>
+    <script type="text/javascript" src="../internal.js"></script>
+    <style type="text/css">
+        .warp {width: 320px;height: 153px;margin-left:5px;padding: 20px 0 0 15px;position: relative;}
+        #url {width: 290px; margin-bottom: 2px; margin-left: -6px; margin-left: -2px\9;*margin-left:0;_margin-left:0; }
+        .format span{display: inline-block; width: 58px;text-align: center; zoom:1;}
+        table td{padding:5px 0;}
+        #align{width: 65px;height: 23px;line-height: 22px;}
+    </style>
+</head>
+<body>
+<div class="warp">
+        <table width="300" cellpadding="0" cellspacing="0">
+            <tr>
+                <td colspan="2" class="format">
+                    <span><var id="lang_input_address"></var></span>
+                    <input style="width:200px" id="url" type="text" value=""/>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2" class="format"><span><var id="lang_input_width"></var></span><input style="width:200px" type="text" id="width"/> px</td>
+
+            </tr>
+            <tr>
+                <td colspan="2" class="format"><span><var id="lang_input_height"></var></span><input style="width:200px" type="text" id="height"/> px</td>
+            </tr>
+            <tr>
+                <td><span><var id="lang_input_isScroll"></var></span><input type="checkbox" id="scroll"/> </td>
+                <td><span><var id="lang_input_frameborder"></var></span><input type="checkbox" id="frameborder"/> </td>
+            </tr>
+
+            <tr>
+                <td colspan="2"><span><var id="lang_input_alignMode"></var></span>
+                    <select id="align">
+                        <option value=""></option>
+                        <option value="left"></option>
+                        <option value="right"></option>
+                    </select>
+                </td>
+            </tr>
+        </table>
+</div>
+<script type="text/javascript">
+    var iframe = editor._iframe;
+    if(iframe){
+        $G("url").value = iframe.getAttribute("src")||"";
+        $G("width").value = iframe.getAttribute("width")||iframe.style.width.replace("px","")||"";
+        $G("height").value = iframe.getAttribute("height") || iframe.style.height.replace("px","") ||"";
+        $G("scroll").checked = (iframe.getAttribute("scrolling") == "yes") ? true : false;
+        $G("frameborder").checked = (iframe.getAttribute("frameborder") == "1") ? true : false;
+        $G("align").value = iframe.align ? iframe.align : "";
+    }
+    function queding(){
+        var  url = $G("url").value.replace(/^\s*|\s*$/ig,""),
+                width = $G("width").value,
+                height = $G("height").value,
+                scroll = $G("scroll"),
+                frameborder = $G("frameborder"),
+                float = $G("align").value,
+                newIframe = editor.document.createElement("iframe"),
+                div;
+        if(!url){
+            alert(lang.enterAddress);
+            return false;
+        }
+        newIframe.setAttribute("src",/http:\/\/|https:\/\//ig.test(url) ? url : "http://"+url);
+        /^[1-9]+[.]?\d*$/g.test( width ) ? newIframe.setAttribute("width",width) : "";
+        /^[1-9]+[.]?\d*$/g.test( height ) ? newIframe.setAttribute("height",height) : "";
+        scroll.checked ?  newIframe.setAttribute("scrolling","yes") : newIframe.setAttribute("scrolling","no");
+        frameborder.checked ?  newIframe.setAttribute("frameborder","1",0) : newIframe.setAttribute("frameborder","0",0);
+        float ? newIframe.setAttribute("align",float) :  newIframe.setAttribute("align","");
+        if(iframe){
+            iframe.parentNode.insertBefore(newIframe,iframe);
+            domUtils.remove(iframe);
+        }else{
+            div = editor.document.createElement("div");
+            div.appendChild(newIframe);
+            editor.execCommand("inserthtml",div.innerHTML);
+        }
+        editor._iframe = null;
+        dialog.close();
+    }
+    dialog.onok = queding;
+    $G("url").onkeydown = function(evt){
+        evt = evt || event;
+        if(evt.keyCode == 13){
+            queding();
+        }
+    };
+    $focus($G( "url" ));
+
+</script>
+</body>
+</html>

+ 81 - 0
xinkeaboard-admin/public/UEditor/dialogs/internal.js

@@ -0,0 +1,81 @@
+(function () {
+    var parent = window.parent;
+    //dialog对象
+    dialog = parent.$EDITORUI[window.frameElement.id.replace( /_iframe$/, '' )];
+    //当前打开dialog的编辑器实例
+    editor = dialog.editor;
+
+    UE = parent.UE;
+
+    domUtils = UE.dom.domUtils;
+
+    utils = UE.utils;
+
+    browser = UE.browser;
+
+    ajax = UE.ajax;
+
+    $G = function ( id ) {
+        return document.getElementById( id )
+    };
+    //focus元素
+    $focus = function ( node ) {
+        setTimeout( function () {
+            if ( browser.ie ) {
+                var r = node.createTextRange();
+                r.collapse( false );
+                r.select();
+            } else {
+                node.focus()
+            }
+        }, 0 )
+    };
+    utils.loadFile(document,{
+        href:editor.options.themePath + editor.options.theme + "/dialogbase.css?cache="+Math.random(),
+        tag:"link",
+        type:"text/css",
+        rel:"stylesheet"
+    });
+    lang = editor.getLang(dialog.className.split( "-" )[2]);
+    if(lang){
+        domUtils.on(window,'load',function () {
+
+            var langImgPath = editor.options.langPath + editor.options.lang + "/images/";
+            //针对静态资源
+            for ( var i in lang["static"] ) {
+                var dom = $G( i );
+                if(!dom) continue;
+                var tagName = dom.tagName,
+                    content = lang["static"][i];
+                if(content.src){
+                    //clone
+                    content = utils.extend({},content,false);
+                    content.src = langImgPath + content.src;
+                }
+                if(content.style){
+                    content = utils.extend({},content,false);
+                    content.style = content.style.replace(/url\s*\(/g,"url(" + langImgPath)
+                }
+                switch ( tagName.toLowerCase() ) {
+                    case "var":
+                        dom.parentNode.replaceChild( document.createTextNode( content ), dom );
+                        break;
+                    case "select":
+                        var ops = dom.options;
+                        for ( var j = 0, oj; oj = ops[j]; ) {
+                            oj.innerHTML = content.options[j++];
+                        }
+                        for ( var p in content ) {
+                            p != "options" && dom.setAttribute( p, content[p] );
+                        }
+                        break;
+                    default :
+                        domUtils.setAttributes( dom, content);
+                }
+            }
+        } );
+    }
+
+
+})();
+

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff