tuonina 5 år sedan
förälder
incheckning
4a1c526894

+ 0 - 28
.idea/codeStyles/Project.xml

@@ -1,28 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <code_scheme name="Project" version="173">
-    <JSCodeStyleSettings version="0">
-      <option name="FORCE_SEMICOLON_STYLE" value="true" />
-      <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
-      <option name="USE_DOUBLE_QUOTES" value="false" />
-      <option name="FORCE_QUOTE_STYlE" value="true" />
-      <option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
-      <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
-      <option name="SPACES_WITHIN_IMPORTS" value="true" />
-    </JSCodeStyleSettings>
-    <TypeScriptCodeStyleSettings version="0">
-      <option name="FORCE_SEMICOLON_STYLE" value="true" />
-      <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
-      <option name="USE_DOUBLE_QUOTES" value="false" />
-      <option name="FORCE_QUOTE_STYlE" value="true" />
-      <option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
-      <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
-      <option name="SPACES_WITHIN_IMPORTS" value="true" />
-    </TypeScriptCodeStyleSettings>
-    <codeStyleSettings language="JavaScript">
-      <option name="SOFT_MARGINS" value="100" />
-    </codeStyleSettings>
-    <codeStyleSettings language="TypeScript">
-      <option name="SOFT_MARGINS" value="100" />
-    </codeStyleSettings>
-  </code_scheme>
-</component>

+ 0 - 5
.idea/codeStyles/codeStyleConfig.xml

@@ -1,5 +0,0 @@
-<component name="ProjectCodeStyleConfiguration">
-  <state>
-    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
-  </state>
-</component>

+ 0 - 6
.idea/misc.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="JavaScriptSettings">
-    <option name="languageLevel" value="JSX" />
-  </component>
-</project>

+ 0 - 8
.idea/modules.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/tuonq-admin.iml" filepath="$PROJECT_DIR$/.idea/tuonq-admin.iml" />
-    </modules>
-  </component>
-</project>

+ 0 - 12
.idea/tuonq-admin.iml

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
-      <excludeFolder url="file://$MODULE_DIR$/temp" />
-      <excludeFolder url="file://$MODULE_DIR$/tmp" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 6
.idea/vcs.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
-  </component>
-</project>

+ 0 - 342
.idea/workspace.xml

@@ -1,342 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ChangeListManager">
-    <list default="true" id="6f4a0bf1-27c2-4804-af97-a0a1bdd98e1d" name="Default Changelist" comment="">
-      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-    </list>
-    <ignored path="$PROJECT_DIR$/.tmp/" />
-    <ignored path="$PROJECT_DIR$/temp/" />
-    <ignored path="$PROJECT_DIR$/tmp/" />
-    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
-    <option name="SHOW_DIALOG" value="false" />
-    <option name="HIGHLIGHT_CONFLICTS" value="true" />
-    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
-    <option name="LAST_RESOLUTION" value="IGNORE" />
-  </component>
-  <component name="FileEditorManager">
-    <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/App.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="1710">
-              <caret line="97" column="88" selection-start-line="97" selection-start-column="88" selection-end-line="97" selection-end-column="88" />
-              <folding>
-                <element signature="e#0#41#0" expanded="true" />
-              </folding>
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="true">
-        <entry file="file://$PROJECT_DIR$/src/routes/config.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="19">
-              <caret line="28" column="28" selection-start-line="28" selection-start-column="28" selection-end-line="28" selection-end-column="28" />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/pages/config/PropertiesLabel.jsx">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="95">
-              <caret line="5" column="21" selection-start-line="5" selection-start-column="21" selection-end-line="5" selection-end-column="21" />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/components/animation/ExampleAnimations.jsx">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="304">
-              <caret line="24" column="45" selection-start-line="24" selection-start-column="45" selection-end-line="24" selection-end-column="45" />
-              <folding>
-                <element signature="e#409#476#0" />
-                <element signature="e#478#553#0" />
-              </folding>
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/routes/index.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="703">
-              <caret line="43" column="61" selection-start-line="43" selection-start-column="61" selection-end-line="43" selection-end-column="61" />
-              <folding>
-                <element signature="e#39#80#0" expanded="true" />
-              </folding>
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/axios/config.js">
-          <provider selected="true" editor-type-id="text-editor" />
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/axios/index.js">
-          <provider selected="true" editor-type-id="text-editor" />
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/pages/config/SystemProperties.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="171">
-              <caret line="9" column="30" selection-start-line="9" selection-start-column="30" selection-end-line="9" selection-end-column="30" />
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/pages/index.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="76">
-              <caret line="5" column="36" selection-start-line="5" selection-start-column="20" selection-end-line="5" selection-end-column="36" />
-              <folding>
-                <element signature="e#0#54#0" expanded="true" />
-              </folding>
-            </state>
-          </provider>
-        </entry>
-      </file>
-      <file pinned="false" current-in-tab="false">
-        <entry file="file://$PROJECT_DIR$/src/components/index.js">
-          <provider selected="true" editor-type-id="text-editor">
-            <state relative-caret-position="437">
-              <caret line="23" column="50" selection-start-line="23" selection-start-column="50" selection-end-line="23" selection-end-column="50" />
-            </state>
-          </provider>
-        </entry>
-      </file>
-    </leaf>
-  </component>
-  <component name="FileTemplateManagerImpl">
-    <option name="RECENT_TEMPLATES">
-      <list>
-        <option value="JavaScript File" />
-      </list>
-    </option>
-  </component>
-  <component name="Git.Settings">
-    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
-  </component>
-  <component name="IdeDocumentHistory">
-    <option name="CHANGED_PATHS">
-      <list>
-        <option value="$PROJECT_DIR$/.gitignore" />
-        <option value="$PROJECT_DIR$/src/pages/config/PropertiesLabel.js" />
-        <option value="$PROJECT_DIR$/src/pages/config/PropertiesLabel.jsx" />
-        <option value="$PROJECT_DIR$/src/App.js" />
-        <option value="$PROJECT_DIR$/src/routes/index.js" />
-        <option value="$PROJECT_DIR$/src/pages/config/SystemProperties.js" />
-        <option value="$PROJECT_DIR$/src/pages/index.js" />
-        <option value="$PROJECT_DIR$/src/routes/config.js" />
-      </list>
-    </option>
-  </component>
-  <component name="ProjectFrameBounds" extendedState="6">
-    <option name="x" value="85" />
-    <option name="y" value="25" />
-    <option name="width" value="1750" />
-    <option name="height" value="980" />
-  </component>
-  <component name="ProjectLevelVcsManager" settingsEditedManually="true">
-    <ConfirmationsSetting value="2" id="Add" />
-  </component>
-  <component name="ProjectView">
-    <navigator proportions="" version="1">
-      <foldersAlwaysOnTop value="true" />
-    </navigator>
-    <panes>
-      <pane id="ProjectPane" />
-      <pane id="Scope" />
-    </panes>
-  </component>
-  <component name="PropertiesComponent">
-    <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
-    <property name="WebServerToolWindowFactoryState" value="false" />
-    <property name="node.js.detected.package.eslint" value="true" />
-    <property name="node.js.detected.package.standard" value="true" />
-    <property name="node.js.path.for.package.eslint" value="project" />
-    <property name="node.js.path.for.package.standard" value="project" />
-    <property name="node.js.selected.package.eslint" value="(autodetect)" />
-    <property name="node.js.selected.package.standard" value="" />
-    <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
-    <property name="nodejs_npm_path_reset_for_default_project" value="true" />
-    <property name="nodejs_package_manager_path" value="yarn" />
-  </component>
-  <component name="RunDashboard">
-    <option name="ruleStates">
-      <list>
-        <RuleState>
-          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
-        </RuleState>
-        <RuleState>
-          <option name="name" value="StatusDashboardGroupingRule" />
-        </RuleState>
-      </list>
-    </option>
-  </component>
-  <component name="SvnConfiguration">
-    <configuration />
-  </component>
-  <component name="TaskManager">
-    <task active="true" id="Default" summary="Default task">
-      <changelist id="6f4a0bf1-27c2-4804-af97-a0a1bdd98e1d" name="Default Changelist" comment="" />
-      <created>1565328742876</created>
-      <option name="number" value="Default" />
-      <option name="presentableId" value="Default" />
-      <updated>1565328742876</updated>
-      <workItem from="1565328743940" duration="5894000" />
-      <workItem from="1565575153198" duration="1205000" />
-    </task>
-    <servers />
-  </component>
-  <component name="TimeTrackingManager">
-    <option name="totallyTimeSpent" value="7099000" />
-  </component>
-  <component name="ToolWindowManager">
-    <frame x="-7" y="-7" width="1550" height="838" extended-state="6" />
-    <layout>
-      <window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.24966975" />
-      <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
-      <window_info id="npm" order="2" side_tool="true" />
-      <window_info id="Favorites" order="3" side_tool="true" />
-      <window_info anchor="bottom" id="Message" order="0" />
-      <window_info anchor="bottom" id="Find" order="1" />
-      <window_info anchor="bottom" id="Run" order="2" />
-      <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
-      <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
-      <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
-      <window_info anchor="bottom" id="TODO" order="6" />
-      <window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
-      <window_info anchor="bottom" id="Version Control" order="8" />
-      <window_info anchor="bottom" id="RNConsole" order="9" />
-      <window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
-      <window_info active="true" anchor="bottom" id="Terminal" order="11" visible="true" weight="0.28045326" />
-      <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
-      <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
-      <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
-    </layout>
-  </component>
-  <component name="TypeScriptGeneratedFilesManager">
-    <option name="version" value="1" />
-  </component>
-  <component name="editorHistoryManager">
-    <entry file="file://$PROJECT_DIR$/.gitignore">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="1501">
-          <caret line="79" column="10" selection-start-line="79" selection-start-column="10" selection-end-line="79" selection-end-column="10" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/Page.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state>
-          <folding>
-            <element signature="e#0#26#0" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/components/dashboard/Dashboard.jsx">
-      <provider selected="true" editor-type-id="text-editor">
-        <state>
-          <folding>
-            <element signature="n#Dashboard#0" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/components/BreadcrumbCustom.jsx">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="-55">
-          <caret line="3" column="7" lean-forward="true" selection-start-line="3" selection-start-column="7" selection-end-line="3" selection-end-column="7" />
-          <folding>
-            <element signature="e#46#72#0" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/utils/index.jsx">
-      <provider selected="true" editor-type-id="text-editor" />
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/App.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="1710">
-          <caret line="97" column="88" selection-start-line="97" selection-start-column="88" selection-end-line="97" selection-end-column="88" />
-          <folding>
-            <element signature="e#0#41#0" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/pages/config/PropertiesLabel.jsx">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="95">
-          <caret line="5" column="21" selection-start-line="5" selection-start-column="21" selection-end-line="5" selection-end-column="21" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/components/animation/ExampleAnimations.jsx">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="304">
-          <caret line="24" column="45" selection-start-line="24" selection-start-column="45" selection-end-line="24" selection-end-column="45" />
-          <folding>
-            <element signature="e#409#476#0" />
-            <element signature="e#478#553#0" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/routes/index.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="703">
-          <caret line="43" column="61" selection-start-line="43" selection-start-column="61" selection-end-line="43" selection-end-column="61" />
-          <folding>
-            <element signature="e#39#80#0" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/axios/config.js">
-      <provider selected="true" editor-type-id="text-editor" />
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/axios/index.js">
-      <provider selected="true" editor-type-id="text-editor" />
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/pages/config/SystemProperties.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="171">
-          <caret line="9" column="30" selection-start-line="9" selection-start-column="30" selection-end-line="9" selection-end-column="30" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/pages/index.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="76">
-          <caret line="5" column="36" selection-start-line="5" selection-start-column="20" selection-end-line="5" selection-end-column="36" />
-          <folding>
-            <element signature="e#0#54#0" expanded="true" />
-          </folding>
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/components/index.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="437">
-          <caret line="23" column="50" selection-start-line="23" selection-start-column="50" selection-end-line="23" selection-end-column="50" />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/routes/config.js">
-      <provider selected="true" editor-type-id="text-editor">
-        <state relative-caret-position="19">
-          <caret line="28" column="28" selection-start-line="28" selection-start-column="28" selection-end-line="28" selection-end-column="28" />
-        </state>
-      </provider>
-    </entry>
-  </component>
-</project>

+ 1 - 2
src/axios/config.js

@@ -15,5 +15,4 @@ export const GIT_OAUTH = 'https://github.com/login/oauth';
 export const GIT_USER = 'https://api.github.com/user';
 
 // bbc top news
-export const NEWS_BBC =
-    'https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=429904aa01f54a39a278a406acf50070';
+export const NEWS_BBC = 'https://newsapi.org/v2/top-headlines?sources=bbc-news&apiKey=429904aa01f54a39a278a406acf50070';

+ 8 - 1
src/axios/index.js

@@ -4,6 +4,11 @@
 import axios from 'axios';
 import { get, post } from './tools';
 import * as config from './config';
+import { findPLabel, labelAdd, labelEdit, pLabelDelete, searchLabel } from './property/label';
+
+export {
+    findPLabel, searchLabel, labelAdd, labelEdit, pLabelDelete,
+};
 
 export const getBbcNews = () => get({ url: config.NEWS_BBC });
 
@@ -23,7 +28,7 @@ export const gitOauthLogin = () =>
     get({
         url: `${
             config.GIT_OAUTH
-        }/authorize?client_id=792cdcd244e98dcd2dee&redirect_uri=http://localhost:3006/&scope=user&state=reactAdmin`,
+            }/authorize?client_id=792cdcd244e98dcd2dee&redirect_uri=http://localhost:3006/&scope=user&state=reactAdmin`,
     });
 export const gitOauthToken = code =>
     post({
@@ -45,3 +50,5 @@ export const gitOauthInfo = access_token =>
 export const admin = () => get({ url: config.MOCK_AUTH_ADMIN });
 // 访问权限获取
 export const guest = () => get({ url: config.MOCK_AUTH_VISITOR });
+
+

+ 21 - 0
src/axios/property/label.js

@@ -0,0 +1,21 @@
+import {get,post,put,del} from '../tools'
+/**
+ * 查询标签信息
+ * @param params
+ */
+export const findPLabel=(params)=>get({url:'/v1/property/label',params});
+
+export const labelAdd=(params)=>post({url:'/v1/property/label',data:params});
+
+export const labelEdit=(params)=>put({url:'/v1/property/label',data:params});
+export const pLabelDelete=(id)=>del({url:`/v1/property/label/${id}`});
+
+/**
+ * 如果没有关键词,则不查询网络
+ * @param keywords
+ * @returns {{records: Array}|Promise<any | never>}
+ */
+export const searchLabel=({keywords})=>{
+    if (keywords === '') return {records:[]};
+    return get({url:'/v1/property/label',params:{keywords}})
+};

+ 34 - 3
src/axios/tools.js

@@ -4,16 +4,25 @@
  */
 import axios from 'axios';
 import { message } from 'antd';
+import config from '../const';
+
+function checkURL(url) {
+    if (/(http|ws|https)/.test(url)) {
+        return url;
+    }
+    return `${config.BASE_API}${url}`;
+}
 
 /**
  * 公用get请求
  * @param url       接口地址
  * @param msg       接口异常提示
+ * @param params    请求参数
  * @param headers   接口所需header配置
  */
-export const get = ({ url, msg = '接口异常', headers }) =>
+export const get = ({ url, headers, params, msg = '接口异常' }) =>
     axios
-        .get(url, headers)
+        .get(checkURL(url), { headers, params })
         .then(res => res.data)
         .catch(err => {
             console.log(err);
@@ -29,9 +38,31 @@ export const get = ({ url, msg = '接口异常', headers }) =>
  */
 export const post = ({ url, data, msg = '接口异常', headers }) =>
     axios
-        .post(url, data, headers)
+        .post(checkURL(url), data, headers)
         .then(res => res.data)
         .catch(err => {
             console.log(err);
             message.warn(msg);
         });
+
+
+/**
+ *
+ * @param url
+ * @param data
+ * @param msg
+ * @param headers
+ * @returns {Promise<AxiosResponse<any> | never>}
+ */
+export const put = ({ url, data, msg = '接口异常', headers }) =>
+    axios.put(checkURL(url), data, headers)
+        .then(resp => resp.data)
+        .catch(err => {
+            console.log('err : ', url, ' err: ', err);
+            return err;
+        });
+
+
+export const del = ({ url, data, headers }) =>
+    axios.delete(checkURL(url), { data, headers })
+        .then(resp => resp.data);

+ 24 - 0
src/const/index.js

@@ -0,0 +1,24 @@
+const NODE_ENV = process.env.NODE_ENV;
+console.log('当前环境: ', NODE_ENV);
+
+/**
+ * 基础环境配置
+ * @type {{BASE_API: string}}
+ */
+const BASE_CONF = {
+    BASE_API: 'http://192.168.1.113:11111/',
+};
+
+/**
+ * 生成环境下的环境覆盖
+ * @type {{}}
+ */
+const PROD_CONF = {};
+
+let CONF = BASE_CONF;
+if (NODE_ENV === 'development') {
+    CONF = { ...CONF, ...PROD_CONF };
+}
+export default CONF;
+
+

+ 102 - 0
src/pages/config/ConfigLabel.js

@@ -0,0 +1,102 @@
+import React from 'react';
+import { connectAlita } from 'redux-alita';
+import { withRouter } from 'react-router-dom';
+import { Button, List, Modal } from 'antd';
+import './styles/label.less';
+import AddLabelForm from './widget/AddLabelForm';
+
+
+class ConfigLabel extends React.Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            params: { keywords: undefined },
+            labelPathList: [],
+            addVisible: false,
+            loading: false,
+            addModalTitle: '添加属性标签',
+            removeModalTitle: '提示',
+            removeLoading: false,
+            removeModalVisible: false,
+            currentLabel: null,
+        };
+    }
+
+
+    componentDidMount() {
+        this._fetchLabels();
+    }
+
+    _fetchLabels() {
+        let params = this.state.params;
+        this.props.setAlitaState({ funcName: 'findPLabel', params });
+
+    }
+
+    _handleSearch(value) {
+        this.state.params.keywords = value;
+        this._fetchLabels();
+
+    }
+
+
+    renderItem(item) {
+        return (<List.Item className='prop-label-item'>
+            <div>
+                <h3 className='label-label'>{item.path}</h3>
+                <span className={'label-title'}>{item.title}</span>
+            </div>
+            <div>{item.description}</div>
+            <div className='tool-btns'>
+                <Button icon='edit' type='primary' size='small' onClick={() => this.setState({ currentLabel: item })}/>
+                <Button icon='delete' type='danger' size='small' onClick={this.removeLabel.bind(this, item)}/>
+            </div>
+        </List.Item>);
+    }
+
+    _onAddModalHide() {
+        this.setState({ addVisible: false, currentLabel: null });
+
+    }
+
+    render() {
+        const { data: labelList = {} } = this.props.findPLabel || {};
+        const { currentLabel, loading, addModalTitle } = this.state;
+        return (<div>
+            <div className='prop-label-header'>
+                <Button type='primary' icon='sync' onClick={this._fetchLabels.bind(this)}/>
+                <Button type='primary' icon='plus' onClick={()=>this.setState({currentLabel:{}})}/>
+            </div>
+
+            <List
+                dataSource={labelList.records}
+                bordered
+                size='small'
+                renderItem={this.renderItem.bind(this)}/>
+            <Modal visible={!!currentLabel} title={addModalTitle}
+                   onCancel={this._onAddModalHide.bind(this)}
+                   footer={null}>
+                <AddLabelForm cancel={this._onAddModalHide.bind(this)}
+                              label={currentLabel}/>
+            </Modal>
+        </div>);
+    }
+
+    removeLabel(item) {
+        let { removeModalTitle, removeLoading } = this.state;
+        let _this = this;
+        Modal.confirm({
+            title: removeModalTitle,
+            content: `您确定要删除:${item.path} 标签吗?`,
+            onCancel() {
+            },
+            onOk() {
+                _this.props.setAlitaState({ funcName: 'pLabelDelete', params: item.id });
+            },
+        });
+    }
+
+}
+
+export default withRouter(connectAlita(['findPLabel'])(ConfigLabel));

+ 25 - 0
src/pages/config/styles/label.less

@@ -0,0 +1,25 @@
+
+.prop-label-header{
+  padding: 10px;
+}
+
+.prop-label-item{
+  background: white;
+  display: block;
+  .label-label{
+    font-size: x-large;
+    color: #333333;
+    display: inline-block;
+  }
+  .label-title{
+    font-size: larger;
+    color: #666666;
+    padding-left: 10px;
+  }
+  .tool-btns{
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-end;
+  }
+}
+

+ 106 - 0
src/pages/config/widget/AddLabelForm.js

@@ -0,0 +1,106 @@
+import React from 'react';
+import { AutoComplete, Button, Form, Input } from 'antd';
+import { connectAlita } from 'redux-alita';
+
+
+/**
+ * 添加属性标签的表单,
+ * 包括编辑,和添加
+ */
+class AddLabelForm extends React.Component {
+
+    static defaultProps = {
+        searchLabel: { data: {} },
+        cancel: () => {
+        },
+    };
+
+    constructor(props) {
+        super(props);
+        let { label } = props;
+        this.state = {
+            label: label || { pid: 0 },
+            labelList: [],
+        };
+    }
+
+    handleSubmit = e => {
+        e.preventDefault();
+        const _this = this;
+        this.props.form.validateFieldsAndScroll((err, values) => {
+            if (!err) {
+                if (_this.state.label.id) {
+                    _this.props.setAlitaState({ funcName: 'labelEdit', params: values })
+                        .then((resp)=>{
+                            console.log(' resp ',resp)
+                        })
+                } else {
+                    _this.props.setAlitaState({ funcName: 'labelAdd', params: values });
+                }
+            }
+        });
+    };
+
+    handleSearchLabel = (keywords) => {
+        this.props.setAlitaState({ funcName: 'searchLabel', params: { keywords } });
+    };
+
+    onSelect(sources = [], path) {
+        for (let i in sources) {
+            let source = sources[i];
+            if (source.path === path) {
+                let oldV = this.state.label;
+                this.setState({ label: { ...oldV, pid: source.id } });
+                break;
+            }
+        }
+    }
+
+    render() {
+        console.log('props=>',this.props)
+        const { getFieldDecorator } = this.props.form;
+        let { label } = this.props;
+        if (!label) return null;
+        const { data: dataSource, isFetching } = this.props.searchLabel || { data: {} };
+        const { isFetching: isSubmitLoading } = this.props.labelAdd||{};
+        const { isFetching: isEditLoading } = this.props.labelEdit||{};
+
+        if (!dataSource.records) dataSource.records = [];
+        return (<Form onSubmit={this.handleSubmit}>
+            {(!label.id) && (<Form.Item>
+                {getFieldDecorator('path')(<AutoComplete onSearch={this.handleSearchLabel}
+                                                         dataSource={dataSource.records.map(item => item.path)}
+                                                         loading={isFetching}
+                                                         onSelect={this.onSelect.bind(this, dataSource.records)}
+                                                         placeholder='输入关键词查询上级标签'/>)}
+            </Form.Item>)}
+            <Form.Item style={{ display: 'none' }}>
+                {getFieldDecorator('id', { initialValue: label.id })}(<Input/>
+            </Form.Item>
+            <Form.Item style={{ display: 'none' }}>
+                {getFieldDecorator('pid', { initialValue: label.pid })}(<Input/>
+            </Form.Item>
+            <Form.Item>
+                {getFieldDecorator('label', {
+                    rules: [{ required: true, message: '请输入标签' }],
+                    initialValue: label.label,
+                })
+                (<Input disabled={!!label.id} placeholder='请输入标签'/>)}
+            </Form.Item>
+            <Form.Item>
+                {getFieldDecorator('title', { initialValue: label.title })(<Input placeholder='请输入标签名称'/>)}
+            </Form.Item>
+            <Form.Item>
+                {getFieldDecorator('description', { initialValue: label.description })(<Input placeholder='请输入标签简介'/>)}
+            </Form.Item>
+            <Form.Item>
+                <Button type='default' htmlType='button' onClick={this.props.cancel}>取消</Button>
+                <Button loading={isSubmitLoading || isEditLoading} htmlType='submit' type='primary'>提交</Button>
+            </Form.Item>
+        </Form>);
+    }
+
+
+}
+
+export default connectAlita(['searchLabel', 'labelAdd','labelEdit'])(Form.create({ name: 'AddLabelForm' })(AddLabelForm));

+ 6 - 0
src/routes/config.js

@@ -1,7 +1,13 @@
+import ConfigLabel from '../pages/config/ConfigLabel';
+
 export default {
     menus: [
         // 菜单相关路由
         { key: '/app/dashboard/index', title: '首页', icon: 'mobile', component: 'Dashboard' },
+        {
+            key: '/app/config', title: '配置中心', icon: 'mobile',
+            subs: [{ key: '/app/config/label', title: '属性标签', component: ConfigLabel}],
+        },
         {
             key: '/app/ui',
             title: 'UI',

+ 7 - 1
src/routes/index.js

@@ -34,7 +34,13 @@ export default class CRouter extends Component {
                 {Object.keys(routesConfig).map(key =>
                     routesConfig[key].map(r => {
                         const route = r => {
-                            const Component = AllComponents[r.component];
+                            let Component;
+                            let component = r.component;
+                            if (typeof component == 'string') {
+                                Component = AllComponents[r.component];
+                            } else {
+                                Component = component;
+                            }
                             return (
                                 <Route
                                     key={r.route || r.key}